You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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;

逻辑说明

  1. 传址调用后,*tree代表的就是外部的指针变量(比如父节点的left/right,或者root)。
  2. 当处理单孩子节点时,*tree = (*tree)->right直接修改了外部指针的指向,让父节点跳过待删除节点,指向它的子节点,同时释放待删除节点的内存。
  3. 处理双子节点的逻辑不变,用左子树的最大节点替换当前节点值,再递归删除那个最大节点。

额外注意

你的insert函数其实也有同样的传值隐患(虽然当前靠parent参数勉强工作),不过既然你说忽略注释里的替代写法,这里就不改动insert了。

内容的提问来源于stack exchange,提问作者learner

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.05 11:49:52