【问题标题】:Delete a leaf node in binary tree删除二叉树中的叶节点
【发布时间】:2017-12-26 14:40:32
【问题描述】:

我正在尝试从 二叉搜索 树中删除 leaf node,但它对我不起作用,我调试了代码,但找不到问题所在。我可以看到流程是正确的,调用到达leaf node 地址,然后调用free。但在那之后,当我执行pre-order 遍历时,我看到该值仍然存在。

我创建的二叉树(很简单)-:

                           10
                         /    \
                        6      14

Leaf Node 要删除的值 = 14;

删除前Pre - order遍历结果=10->6->14。这是打印在我的控制台上的。

删除代码leaf node -:

// Delete a leaf node

void deleteNode(struct Nodes * root,int value){

    // Check if root is null

    if (root == NULL) {
        return;
    }

    // If no left and right node present, it's a leaf node. Perform delete.

    while (root->left == NULL && root->right == NULL) {

        // Check if value at leaf node is same as value to be deleted. If yes, go inside (if).

        if (root->info == value) {
            printf("Delete the leaf node \n");

            printf("delete node address is \n %p",root);

            // free the root (which is currently a leaf node)
            free(root);
            return;
        }
    }

    // keep checking if value to be deleted is on right or left, till a value is found.

    if (root->info < value) {
        // Ccheck on right
        deleteNode(root->right,value);
    }else{
        // check on left
        deleteNode(root->left,value);
    }

}

我没有得到任何errors,所以我无法猜测根本原因

删除后Pre - order遍历结果=10-&gt;6-&gt;14。谁能帮我吗?我知道我犯了一个非常愚蠢的错误,或者我的概念还不是很清楚。谢谢。

如果需要任何其他信息,请告诉我。

输出图像-:您可以看到我的值正确,地址也相同。

【问题讨论】:

  • 不知何故,也许你需要将free()-d 节点设置为NULL,否则你将读取无效内存。
  • @SouravGhosh 我试过 root=NULL;但同样的结果。如何检查无效内存?
  • C 使用按值传递....
  • @SouravGhosh 哦,我明白了。这意味着我仍然有一份价值而不是参考?我怎样才能在这里得到一个?有任何链接可以分享吗?

标签: c data-structures binary-search-tree


【解决方案1】:

free 几乎意味着“我发誓我不会再使用内存了,它可能会被释放或任意重新分配”。

你违反了这个承诺。释放内存后,您还必须忘记该地址上的所有引用。父节点还记得该节点以前所在的地址,碰巧内存还没有被回收。

您遇到了典型的“释放后使用”错误。如果您在两者之间分配了另一个节点,那么在再次遍历之前,您会注意到内存损坏。

您可以在函数中再添加一个参数,该参数指向父对象中的指针。这样你就可以修改父级了。

或者将引用存储回节点中的父节点。

两者都有效。

【讨论】:

  • 我想我明白了你的意思,这里绝对正确。太棒了!让我检查一下这个想法,我一定会接受答案。谢谢!!
  • 谢谢先生就是这样。:)
【解决方案2】:

一种方法是在递归调用中将指针传递给父级。像这样的:

void deleteNode(struct Nodes *root, struct Nodes *parent, int value){

    // Check if root is null

    if (root == NULL) {
        return;
    }

    if ((root->info == value) && (root->left == NULL) && (root->right == NULL)) {
        if (parent->left->info == value) {free(parent->left); parent->left = NULL;}
        else {free(parent->right); parent->right = NULL;}
    }
    else if (root->info < value) {
        // check on right
        deleteNode(root->right,root, value);
    }else{
        // check on left
        deleteNode(root->left,root, value);
    }
}

【讨论】:

  • 谢谢,这就是我最终的结果。 +1
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-04-01
  • 1970-01-01
  • 2019-12-28
相关资源
最近更新 更多