我很难弄清楚如何使用双指针从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;
}
最佳答案
我认为问题出在*rootRef = tmp->left;
行。
此行尝试删除节点rootRef
。它实际上所做的只是将节点替换为其左子节点,如果rootRef
仅具有左子节点,这是正确的。但是,如果有合适的孩子,它将成为孤儿。
您需要做的是正确处理删除操作,如下所示:
如果rootRef
没有子代,即rootRef->left == NULL && rootRef->right == NULL
,
只需删除该节点。
如果rootRef
只有一个孩子,请用该孩子替换rootRef
。
如果rootRef
有两个子代,请用其in-order后继者替换rootRef
的值,然后递归删除该节点,直到达到情况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;
}