C语言二叉树delete函数失效问题求助
二叉树delete函数无法删除节点的问题分析与修复
你的delete函数核心问题是指针传递方式错误,用了传值调用而非传址调用,导致函数内部修改节点指针的操作无法同步到树的实际结构中。
问题拆解
- 当你在delete函数里写
tree = tree->right时,只是修改了函数内部的局部tree指针,上层父节点的left/right指针仍然指向原来的待删除节点,所以树的结构根本没更新。 - 如果删除的是根节点,当前逻辑也无法修改全局的
root指针,导致根节点删除后程序状态异常。
修复方案
把delete函数的参数改成指针的指针(node **tree),这样就能直接修改外部的指针变量(包括父节点的子指针和全局root)。修改后的逻辑如下:
void delete(node **tree, int val){ node *temp; if(*tree == NULL){ printf("Element not found\n"); return; } else if(val < (*tree)->data){ delete(&((*tree)->left), val); } else if(val > (*tree)->data){ delete(&((*tree)->right), val); } else{ // 节点有左右两个子树 if((*tree)->left && (*tree)->right){ temp = largestnode((*tree)->left); (*tree)->data = temp->data; delete(&((*tree)->left), temp->data); } // 节点只有一个子树或叶子节点 else{ temp = *tree; if((*tree)->left == NULL){ *tree = (*tree)->right; } else{ *tree = (*tree)->left; } free(temp); } } }
同时,main函数里的调用要改成传递root的地址:
case 5: printf("Enter the value to be deleted: "); scanf("%d", &val); delete(&root, val); // 修改这里,传root的地址 break;
逻辑说明
- 传址调用后,
*tree代表的就是外部的指针变量(比如父节点的left/right,或者root)。 - 当处理单孩子节点时,
*tree = (*tree)->right直接修改了外部指针的指向,让父节点跳过待删除节点,指向它的子节点,同时释放待删除节点的内存。 - 处理双子节点的逻辑不变,用左子树的最大节点替换当前节点值,再递归删除那个最大节点。
额外注意
你的insert函数其实也有同样的传值隐患(虽然当前靠parent参数勉强工作),不过既然你说忽略注释里的替代写法,这里就不改动insert了。
内容的提问来源于stack exchange,提问作者learner
相关产品推荐
相关产品推荐

