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!