C 从根指针指向的二叉搜索树中删除数据
我很难弄清楚如何使用双指针从BST中删除数据,然后在需要时更改根。这就是我正在尝试的,但当我测试它时,它会删除不应该删除的数字…知道什么是有缺陷的吗 编辑:下面是我的新代码后的答案C 从根指针指向的二叉搜索树中删除数据,c,binary-search-tree,treenode,C,Binary Search Tree,Treenode,我很难弄清楚如何使用双指针从BST中删除数据,然后在需要时更改根。这就是我正在尝试的,但当我测试它时,它会删除不应该删除的数字…知道什么是有缺陷的吗 编辑:下面是我的新代码后的答案 int removeBST(struct TreeNode** rootRef, int data) { while (*rootRef && (*rootRef)->data != data) { if ((*rootRef)-&g
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;
}
int removeBST(结构树节点**rootRef,int数据)
{
而(*rootRef&&(*rootRef)->data!=data)
{
if((*rootRef)->data>data)
{
rootRef=&(*rootRef)->左;
}
else if((*rootRef)->data右;
}
}
如果(*rootRef)
{
struct TreeNode*tmp=*rootRef;
if(rootRef->left==NULL&&rootRef->right==NULL)//没有子项
{
免费(tmp);
}
如果(rootRef->left->left==NULL&&rootRef->right->right==NULL)//一个子
{
rootRef=rootRef->left;
}
其他的
{
rootRef=inOrderSuccessor(rootRef);
removeBST(**rootRef,数据);
}
返回1;
}
返回0;
}
我认为问题在于行*rootRef=tmp->left代码>
此行尝试删除节点rootRef
。它实际上只是用左子节点替换节点,如果rootRef
只有左子节点,这是正确的。然而,如果它有一个合适的孩子,它将成为孤儿
您需要做的是正确处理删除,如下所示:
如果rootRef
没有子项,即rootRef->left==NULL&&rootRef->right==NULL
,
只需删除节点即可
如果rootRef
只有一个子项,则用该子项替换rootRef
如果rootRef
有两个子节点,则用其后继节点替换rootRef
的值,然后递归删除该节点,直到出现情况1或2
您的代码必须与以下内容类似:
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;
}
*rootRef=tmp->left
您确实保留了左指针,但是->右指针将被孤立,包括完整的右子树。您可以在谷歌上搜索伪代码,用于此函数。目前,您可能拥有15%的删除节点逻辑。您需要指向要删除的节点的父节点的指针,当您删除时,您有3个用例。1.要删除的节点是叶2。要删除的节点有一个子节点3。要挖掘的节点有两个子节点。所以我应该在*rootRef=tmp->left;之后执行一些if语句;?这种说法是错误的。你需要通过独立处理这3个案例来实现删除算法。好吧,我这样做了,但仍然有问题…我很确定这与两个孩子的案例有关,但我不知道如何递归检查孩子的孩子…请帮助!我对此非常困惑(rootRef->left->left==NULL&&rootRef->right->right==NULL)
意味着rootRef
只有一个孩子吗?