我在如何使用双指针从BST中删除数据然后根据需要更改根目录时遇到了很多麻烦。这就是我正在尝试的但是当我测试它时它删除了不应该删除的数字...任何关于什么是有缺陷的想法?
编辑:以下是答案后的新代码......
int removeBST(struct TreeNode** rootRef, int data)
{
while (*rootRef && (*rootRef)->data != data)
{
if ((*rootRef)->data > data)
{
rootRef = &(*rootRef)->left;
}
else if ((*rootRef)->data < data)
{
rootRef = &(*rootRef)->right;
}
}
if (*rootRef)
{
struct TreeNode *tmp = *rootRef;
if (rootRef->left == NULL && rootRef->right == NULL) // no children
{
free(tmp);
}
else if (rootRef->left->left == NULL && rootRef->right->right == NULL) // one child
{
rootRef = rootRef->left;
}
else
{
rootRef = inOrderSuccessor(rootRef);
removeBST(**rootRef, data);
}
return 1;
}
return 0;
}
答案 0 :(得分:1)
我认为问题在于*rootRef = tmp->left;
行。
此行尝试删除节点rootRef
。实际上它只是用左子节点替换节点,如果rootRef
只有一个左子节点,这是正确的。但是,如果它有一个正确的孩子,它将成为孤儿。
您需要做的是正确处理删除,如下所示:
如果rootRef
没有孩子,即rootRef->left == NULL && rootRef->right == NULL
,
只需删除节点。
如果rootRef
只有一个孩子,请将rootRef
替换为该孩子。
如果rootRef
有两个孩子,请将rootRef
的值替换为其in-order后继者,然后以递归方式删除该节点 ,直到你达到案例1或2。
An example on removing a node from a BST
您的代码必须与此类似:
int removeBST(struct TreeNode** rootRef, int data) {
while (*rootRef && (*rootRef)->data != data) {
...
}
struct TreeNode* prootRef = *rootRef;
if (prootRef) {
if(prootRef->left && prootRef->right) // Both children exist
// Find its in-order successor
...
}
else if(prootRef->left) { // Only left child exists
// Replace rootRef by its left child
...
}
else if(prootRef->right) { // Only right child exists
// Replace rootRef by its right child
...
}
else { // rootRef is a leaf node
// Delete rootRef
...
}
return 1;
}
return 0;
}