二叉搜索树递归删除

Binary Search Tree Recursive Remove

本文关键字:删除 递归 搜索树      更新时间:2023-10-16

当我试图找到移除函数的最大值时,我的程序一直在中断。我要做的是用左树的最大值覆盖用户想要删除的节点,然后删除该节点。一旦到达第一个Else,它就会继续断裂。这个递归快把我逼疯了。我的缺点在哪里?

这是带有私有递归兄弟函数的remove函数。

template<typename TYPE>
bool BinarySearchTree<TYPE>::remove(TYPE& data)
{
    bool found = search(dataOut);
    if(found)
        TRoot = Premove(TRoot, data);
    return found;
}
template<typename TYPE>
Node<TYPE>* BinarySearchTree<TYPE>::Premove(Node<TYPE>* root, TYPE& data)
{
    Node<TYPE>* del;
    Node<TYPE>* max;
    if(root)
    {
        if(root->data > data)
            root->left = Premove(root->left, data);
        else if(root->data < data)
            root->right = Premove(root->right, data);
        else
        {
            if(root->left && root->right)
            {
                max = root->left;
                while(max->data < max->right->data)
                    max = max->right;
                root->data = max->data;
                max = Premove(root, max->data);
            }
            else
            {
                del = root;
                root = (root->right) ? root->right : root->left;
                delete pDel;
            }
        }
    }
    return root;
}

问题很可能在这里:while(max->data < max->right->data) max = max->right;

您正在耗尽树(max->right最终将变为NULL)。实际上,由于它是一个二叉搜索树,所以不需要比较data。只要有可能向右走就够了:while (max->right) max=max->right;

还要注意这个分支中的最后一个赋值:还有两个额外的问题。首先,您应该执行root->left = Premove(...)而不是max = Premove(...)(否则您将无法修改根->左引用)。其次,您应该为root->left调用Premove,而不是root: root->left = Premove(root->left, max->data);(否则您只是得到一个无限递归)。

我认为你的while语句应该是这样的:

while(max && max->right && max->data < max->right->data ) 

在某些情况下,在您的代码中,maxmax->right可能是NULL,这会导致运行时错误。