Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/59.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/url/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 从根指针指向的二叉搜索树中删除数据_C_Binary Search Tree_Treenode - Fatal编程技术网

C 从根指针指向的二叉搜索树中删除数据

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

我很难弄清楚如何使用双指针从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;  

}
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
    只有一个孩子吗?