Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/59.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/twitter-bootstrap/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 对于仅叶节点的每个父节点,移除该叶并将其值与父节点一起添加_C_Recursion_Binary Tree - Fatal编程技术网

C 对于仅叶节点的每个父节点,移除该叶并将其值与父节点一起添加

C 对于仅叶节点的每个父节点,移除该叶并将其值与父节点一起添加,c,recursion,binary-tree,C,Recursion,Binary Tree,如果我发现一个父亲小时候只有一片叶子,我就得把叶子摘下来,和父亲一起增加它的价值 这是我的解决方案,但是当我试图移除叶子时,我遇到了一个问题 bool isLeaf(tree a){ //function to verify if the node is a leaf if(a->left==NULL && a->right==NULL) return true; else return false; } void removeLeaves(tr

如果我发现一个父亲小时候只有一片叶子,我就得把叶子摘下来,和父亲一起增加它的价值

这是我的解决方案,但是当我试图移除叶子时,我遇到了一个问题

bool isLeaf(tree a){ //function to verify if the node is a leaf

if(a->left==NULL && a->right==NULL)
    return true;
else
    return false;
}


void removeLeaves(tree* a){

if(*a == NULL) return;

//verify if the node has only a child
 if(((*a)->left==NULL&&(*a)->right!=NULL) || ((*a)->right==NULL&&(*a)->left!=NULL)){

    if((*a)->right==NULL){ //if has only left child,verify  if it is a leaf
        if(isLeaf((*a)->left)){
            (*a)->info = (*a)->info + (*a)->left->info; 
            free((*a)->left);



        }
    }
    if((*a)->left==NULL){ //if has only right child,verify  if it is a leaf
        if(isLeaf((*a)->right)){
            (*a)->info = (*a)->info + (*a)->right->info; 
            free((*a)->right);

        }
    }
}


removeLeaves(&((*a)->left));
removeLeaves(&((*a)->right));
}
最低限度:

if((*a)->right==NULL){ //if has only left child,verify  if it is a leaf
        if(isLeaf((*a)->left)){
            (*a)->info = (*a)->info + (*a)->left->info; 
            free((*a)->left);
如果我到达这一点(左边只有一个孩子,它是一片叶子),我和父亲求和,然后释放它。没有自由,我得到和,但有自由,我得到分段错误。右边只有一个孩子也是一样

编辑1: 我将条件更改为:

if(((*a)->right==NULL&&(*a)->left!=NULL) && isLeaf((*a)->left)){


        (*a)->info = (*a)->info + (*a)->left->info; 

        free((*a)->left);
        (*a)->left = NULL;  

}
这是可行的,但我不明白为什么

Edit2:(用struct实现)

#包括
#包括
信息树;
类型定义结构树{
信息树信息;
结构树*右;
结构树*左;
}NodeTree;
typedef NodeTree*树;
//功能
Tree createTree(InfoTree infoRoot、左树、右树);
树空树();
无效打印树(树a);
布尔岛(树a);
清除空洞的屋檐(树*a);
int main(){
/*二叉树:*/
/*          3               */
/*       /     \           */
/*      7       5          */
/*    /   \      \         */
/*   4    2       9        */
/*       /                     */
/*      6                      */
树A=createTree(6,emptyTree(),emptyTree());
树B=createTree(2,emptyTree(),emptyTree());
树C=createTree(9,emptyTree(),emptyTree());
树D=createTree(5,emptyTree(),C);
树E=createTree(4,A,emptyTree());
treef=createTree(7,E,B);
treeh=createTree(3,F,D);
树t=H;
打印树(t);
拆除屋檐(&t);
printf(“\n”);
打印树(t);
返回0;
}
树createTree(InfoTree-infoRoot,
树左,
树(右){
树a=(树)malloc(树的大小);
a->info=infoRoot;
a->左=左;
a->右=右;
返回a;
}
树空树(){
返回NULL;
}
无效打印树(树a){
如果(a==NULL){
printf(“()”);
}
否则{
printf((%d),a->info);
打印树(a->左);
printf(“”);
打印树(a->右侧);
printf(“)”;
}
}
bool isLeaf(树a){//函数,用于验证节点是否为叶
如果(a->left==NULL&&a->right==NULL)
返回true;
其他的
返回false;
}
空心移除屋檐(树*a){
if(*a==NULL)返回;
//验证节点是否只有一个子节点
如果(((*a)->左==NULL&(*a)->右!=NULL)| |((*a)->右==NULL&(*a)->左!=NULL)){
如果((*a)->right==NULL){//if只有左子级,请验证它是否为叶
if(isLeaf((*a)->左)){
(*a)->info=(*a)->info+(*a)->left->info;
自由((*a)->左);
(*a)->left=NULL;
}
}
如果((*a)->left==NULL){//if只有右子级,请验证它是否为叶
if(isLeaf((*a)->右)){
(*a)->info=(*a)->info+(*a)->right->info;
自由((*a)->权利);
(*a)->right=NULL;
}
}
}
移除屋檐(&((*a)->左);
拆除屋檐(&((*a)->右侧);
}
这是具有树结构的原始源代码和在树上工作的函数。如果我用上述条件(第一版1)修改它,它会工作,但我不明白为什么。
谢谢

释放叶子后,需要将其在父项中的条目设置为空

你的函数是递归的。如果它找到一个叶子,它的内存将被释放,但在函数结束时,它会尝试访问该内存。这就是所谓的“悬垂指针”

编辑:

还有一个问题,如您最初的来源所示:

if((*a)->right==NULL){
    if(isLeaf((*a)->left)){
        // ... irrelevant lines removed ...
        (*a)->left = NULL;
    }
}
if((*a)->left==NULL){ // <== see text below
    if(isLeaf((*a)->right)){ // BOOM!
if((*a)->right==NULL){
if(isLeaf((*a)->左)){
//…删除不相关的行。。。
(*a)->left=NULL;
}
}
如果((*a)->left==NULL){//right)){//BOOM!

如果在第一部分中找到叶,则
指针为空。将
指针设置为空后,标记的
If
计算结果为
,并使用空指针调用
isLeaf()
,给出分段错误。

“我有问题”不够具体。您是否收到错误?程序是否没有执行您希望它执行的操作?请提供确切的错误消息和/或描述您的程序的具体行为以及它应该如何执行。是的,抱歉。它返回我分段错误这是此函数必须返回的内容我看不出
removeLeaves有任何原因获取指向树的指针…同样,请。所以,释放后,我应该添加(*a)->right=NULL;?同样的问题(分段错误)请阅读@Antti链接的文本,并给我们一个可以编译和运行的完整源代码。特别是
树的结构定义和示例树以及调用代码对帮助我们帮助您很重要。好的,对不起,我发布了带有结构定义的代码。谢谢,你说得对!我必须更改第二个条件现在我明白了。
if((*a)->right==NULL){
    if(isLeaf((*a)->left)){
        // ... irrelevant lines removed ...
        (*a)->left = NULL;
    }
}
if((*a)->left==NULL){ // <== see text below
    if(isLeaf((*a)->right)){ // BOOM!