繁体   English   中英

BST 中的删除

[英]Deletion in BST

我试图在二叉搜索树 (BST) 中执行删除,但在打印已删除的数组后出现分段错误。

treeNode *minVal(treeNode *root)
{
    if(root == NULL || root->left==NULL)
        return root;
    else
        minVal(root->left);
}

treeNode *deleteBST(treeNode *root,int value)
{
    treeNode *tempNode;
    
    if(value>root->value)
        deleteBST(root->right,value);
    else if(value<root->value)
        deleteBST(root->left,value);
    else
    {
        if(root->left==NULL)
        {
            tempNode = root->right;
            free(root);
            return tempNode;
        }
        else if(root->right==NULL)
        {
            tempNode = root->left;
            free(root);
            return tempNode;
        }
        else
        {
            tempNode = minVal(root->right);
            root->value=tempNode->value;
            root->right = deleteBST(root->right,tempNode->value);
        }
    }
    return root;    
}

大概deleteBST()返回treeNode *的要点是返回值指向(子)树的新根。 如果在原始根中发现删除的值,则新根将与原始根不同,因此需要某种更新根的方法。

这需要由该函数的调用者适当处理,包括在执行递归调用时该函数本身。 您的功能无法执行此操作。

当在树中找不到指定值时,您的函数也无法正确处理这种情况。 如果传递了这样的值,它最终将尝试取消引用空指针。

您的功能执行的实际删除是完全不够的。 它释放找到值的节点,但它不会调整以该节点为根的子树以具有有效结构,并且它会为已删除节点的父节点留下一个(然后)无效的子指针。


从 BST 中删除的一般方案是这样的:

  • 如果树的根R为空,则返回空; 除此以外,

  • 如果要删除的值小于R的值,则将其从左子树中删除,并更新R的左指针指向左子树的新根 除此以外,

  • 如果要删除的值大于R的值,则将其从右子树中删除,并更新R的右指针指向右子树的新根 除此以外,

  • 要删除的值是R本身的值。 在这种情况下,

    1. 为此子树选择一个新根:

      • 如果R的两个孩子都为空,则新根也为空。
      • 如果恰好有一个孩子为空,那么另一个孩子就是新的根。
      • 如果两个孩子都不为空,那么您可以选择右子树中最小的节点或左子树中最大的节点。 它们分别是R的直接顺序后继者和前任者。
    2. R的子节点都不为空的情况下,适当地更新子树。 假设右子树的最小节点MR是选定的新根,则必须

      1. 通过将父指针指向它的指针更新为指向MR的右子节点(可能为 null 也可能不为 null),从其当前父节点中移除MR 包括当父母是R时。
      2. MR的左右子指针更新为与R的相同。
    3. 免费R

  • 返回子树的根(原始的或新的,视情况而定)

更新的工作代码附有对错误的评论。

treeNode *minVal(treeNode *root)
{
    if(root == NULL || root->left==NULL)
        return root;
    else
        return minVal(root->left);//1.returning a value is a must here
}

treeNode *deleteBST(treeNode *root,int value)
{
    treeNode *tempNode;
    if(root==NULL)//2.handling the base case
        return NULL;
    if(value>root->value)
        return deleteBST(root->right,value);
    else if(value<root->value)
        return deleteBST(root->left,value);
    else
    {
        if(root->left==NULL)
        {
            tempNode = root->right;
            free(root);
            return tempNode;
        }
        else if(root->right==NULL)
        {
            tempNode = root->left;
            free(root);
            return tempNode;
        }
        else
        {
            tempNode = minVal(root->right);
            root->value=tempNode->value;
            root->right = deleteBST(root->right,tempNode->value);
            return root;//can be skipped
        }
    }
    return root;    
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM