当前位置: 首页 > 知识库问答 >
问题:

C语言中的二叉搜索树:删除节点函数

景星光
2023-03-14

我正在为二元搜索树组装函数,结果遇到了麻烦。我正在研究当需要从树中删除包含指定值的节点时可能遇到的每种情况。如果节点没有左右子节点,我不确定如何处理释放节点。函数必须返回节点。我是否备份、检查每个左、右子级,并在子级中删除该值?但是如果该值在根中,我是否会遇到类似的问题,即如何删除它?作为解释,程序使用一个void指针,然后在一个单独的函数compare()中强制转换类型val,该函数计算两个值并为返回-1

struct Node *_removeNode(struct Node *cur, TYPE val)
{
    if (compare(cur->val, val) == 0) { //if val == cur->val
        if (cur->right != NULL && cur->left != NULL) { //if cur has right and left
            cur = _leftMost(cur->right);
            free(_leftMost(cur->right));
        }
        else if (cur->right == NULL && cur->left != NULL) {  //if cur has left
            cur = cur->left;
            free(cur->left);
        }
        else if (cur->right != NULL && cur->left == NULL){ //if cur has right
            cur = cur->right;
            free(cur->right);
        }
        else if (cur->right == NULL && cur->left == NULL){ //if cur has no child
                //free cur if cur = val

        }
    }
    else if (compare(cur->val, val) == -1) {
        cur->right = _removeNode(cur->right, val);
    }
    else if (compare(cur->val, val) == 1) {
        cur->left = _removeNode(cur->left, val);
    }

    return cur;
}

共有1个答案

马阳曦
2023-03-14

如果节点没有子节点,则可以简单地将其删除。为了使递归在其他情况下工作,应该从\u removeNode返回NULL。在所有情况下,cur都应该被删除(释放),因为它不再需要。在每种情况下,都需要返回替换子树。并发症发生在第一种情况下,即右侧儿童的最左侧后代被拉起。拉起后,需要将其从右子树中删除(请注意,它可能是右子树)。

我在脑海中写下了以下所有内容,所以要为一些错误/一点调试做好准备。此外,_leftMost和_removeLeftMost可以与一些工作合并。

所讨论的块应该是这样的:

    Node *replacement;
    if (cur->right != NULL && cur->left != NULL) { //if cur has right and left    
        replacement = _leftMost(cur->right);
        replacement->right = _removeLeftMost(cur->right,replacement);
        replacement->left = cur->left;
    }
    else if (cur->right == NULL && cur->left != NULL) {  //if cur has left
        replacement = cur->left;
    }
    else if (cur->right != NULL && cur->left == NULL){ //if cur has right
        replacement = cur->right;
    }
    else if (cur->right == NULL && cur->left == NULL){ //if cur has no child
        replacement = NULL;
    }
    free(cur);
    cur = replacement;

函数\u removeLeftMost向下遍历左子指针,直到看到要替换的节点,然后用该节点的右子节点替换它。类似于:

Node *_removeLeftMost(node, remove) {
    if (node == remove) {
       return node->right; // Note that remove->left should be null
    }
    else {
       node->left = _removeLeftMost(node->left,remove);
       return node;
    }
}

另外,主要的电话是这样的

root = _removeNode(root, val);

这样,当节点是根节点时,就可以处理您的问题。

 类似资料:
  • 我的删除方法由4个if语句组成,用于处理二叉查找树中的4种不同类型的删除。不确定哪里错了,但当我检查它时,它没有删除任何节点。如果赞赏,任何帮助。提前感谢' 我怀疑问题在于我试图将节点删除替换为空 }

  • 当删除具有两个子节点的节点时,如果指示使用标准的二叉搜索树节点删除算法,我们应该将其替换为右子树的最小节点还是左子树的最大节点?

  • 在二元搜索树的情况下,为什么我们不能简单地在一个节点有两个子节点的情况下,将一个节点的前一个节点替换为后一个节点?

  • 我目前正在做一个学校项目,我必须为二叉搜索树编写一些辅助函数。其中一个函数从树中删除了一个节点。我正在尝试运行一些测试用例,但似乎无法让它们正常工作。我知道这个问题与我如何使用指针有关,但我不太确定我哪里出错了。 这是代码: 注意:我没有包括leftRoot()函数,但它相当简单,我知道它做了它应该做的事情(返回子树中最左边的根)下面是我的教授给我们的测试remove函数的代码部分: 如果有必要,

  • 主要内容:src/runoob/binary/BSTRemove.java 文件代码:本小节介绍二分搜索树节点的删除之前,先介绍如何查找最小值和最大值,以及删除最小值和最大值。 以最小值为例(最大值同理): 查找最小 key 值代码逻辑,往左子节点递归查找下去: ... // 返回以node为根的二分搜索树的最小键值所在的节点 private Node minimum (Node node ) {     if ( node. left == null )         retu

  • 我有一个名为TreeNode的结构,它有一个int键、左键、右键和父键。我正试图用DeleteNode函数从树中删除一个节点,但它不起作用。我应该用左边子树中的最大值替换DeleteNode函数中已删除的节点。我的移植和max函数是deletenode的助手函数。我的问题是,我不确定在DeleteNode函数中,我应该将我所在的节点值与通过函数传入的值进行比较。我在代码中有一个注释,我不知道该怎么