Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/flutter/9.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
如何在BST C语言中删除子树?_C_Binary Search Tree_Subtree - Fatal编程技术网

如何在BST C语言中删除子树?

如何在BST C语言中删除子树?,c,binary-search-tree,subtree,C,Binary Search Tree,Subtree,我想做一个pop函数来删除节点和节点的子树。这是我的密码 void pop(struct data *node,int num) { if(node) { if(node->num==num) { pop(node->left,num); pop(node->right,num); free(node); node=NULL;

我想做一个pop函数来删除节点和节点的子树。这是我的密码

void pop(struct data *node,int num)
{
    if(node)
    {
        if(node->num==num)
        {
            pop(node->left,num);
            pop(node->right,num);
            free(node);
            node=NULL;
        }
        else
        {
            if(num> node->num)
                pop(node->right,num);
            else if (num< node->num)
                pop(node->left,num);
        }
    }
}
void pre(struct data *node)
{
    if(node)
    {
        printf("%d ",node->num);
        pre(node->left);
        pre(node->right);
    }
}
void main()
{
    push(&root,37);
    push(&root,20);
    push(&root,45);
    push(&root,5);
    push(&root,15);
    push(&root,40);
    push(&root,50);
    pre(root);
    pop(root,5);
    pre(root);
    getchar();
}
void pop(结构数据*节点,int num)
{
如果(节点)
{
如果(节点->数量==num)
{
弹出(节点->左,数值);
弹出(节点->右侧,数值);
自由(节点);
node=NULL;
}
其他的
{
如果(num>节点->num)
弹出(节点->右侧,数值);
else if(numnum)
弹出(节点->左,数值);
}
}
}
void pre(结构数据*节点)
{
如果(节点)
{
printf(“%d”,节点->数量);
前置(节点->左侧);
pre(节点->右侧);
}
}
void main()
{
推(和根,37);
推(和根,20);
推(和根,45);
推送(和根,5);
推送(和根,15);
推(和根,40);
推送(&root,50);
前(根);
pop(根,5);
前(根);
getchar();
}

在我使用pop之前,Pre功能运行良好。但是在我使用了pop函数之后,它就坏了。有人知道错误在哪里吗?

pop
中,您正在执行:
node=NULL--但这只影响传递给函数的指针的副本,而不影响原始树中的指针。树保留指向您现在释放的数据的指针。下一次,当你对树做很多事情时,你试着去引用那个指针,结果事情就掉了下来,然后轰隆一声(至少你希望他们这样做——更糟糕的是,有时他们似乎能工作)

解决此问题的一种方法是将双指针传递到
pop

void pop(struct data **node, int num) { 

    if ((*node)->num == num)
        // ...
        free(*node);
        *node = NULL;
    }
}
现在,您正在更改树中的指针,而不是更改函数接收到的指针副本

但这仍然不能很好地工作——您依赖于
pop(child,num)
销毁当前节点的子树,但除非它们的
num
设置为相同的值,否则它们不会删除任何内容,只需沿着树向下移动,查找具有匹配
num
的节点


您可能希望一个函数遍历树以找到您关心的节点,然后另一个函数从指定节点开始遍历树,并(无条件)销毁该节点及其子树。

pop
中,您正在执行:
node=NULL--但这只影响传递给函数的指针的副本,而不影响原始树中的指针。树保留指向您现在释放的数据的指针。下一次,当你对树做很多事情时,你试着去引用那个指针,结果事情就掉了下来,然后轰隆一声(至少你希望他们这样做——更糟糕的是,有时他们似乎能工作)

解决此问题的一种方法是将双指针传递到
pop

void pop(struct data **node, int num) { 

    if ((*node)->num == num)
        // ...
        free(*node);
        *node = NULL;
    }
}
现在,您正在更改树中的指针,而不是更改函数接收到的指针副本

但这仍然不能很好地工作——您依赖于
pop(child,num)
销毁当前节点的子树,但除非它们的
num
设置为相同的值,否则它们不会删除任何内容,只需沿着树向下移动,查找具有匹配
num
的节点


您可能希望一个函数遍历树以找到您关心的节点,然后另一个函数从指定节点开始遍历树,并(无条件)销毁该节点及其子树。

您的pop函数应该如下所示:

struct data* pop(struct data *node,int num)
{
  struct data* temp=null;
if(node)
{
    if(node->num==num)
    {
      if(node->left)
        pop(node->left,node->left->num);
      if(node->right)
        pop(node->right,node->right->num);
      free(node);
    }
    else
    {
        if(num> node->num)
            temp=pop(node->right,num);
        else if (num< node->num)
            temp=pop(node->left,num);

       if(node->right==temp)
        node->right=null;
       else if(node->left==temp)
        node->left=null;
       return temp;
    }
 }
return node;
}
struct data*pop(struct data*node,int num)
{
结构数据*temp=null;
如果(节点)
{
如果(节点->数量==num)
{
如果(节点->左)
弹出(节点->左,节点->左->数值);
如果(节点->右侧)
弹出窗口(节点->右侧,节点->右侧->数值);
自由(节点);
}
其他的
{
如果(num>节点->num)
temp=pop(节点->右侧,num);
else if(numnum)
temp=pop(节点->左侧,num);
如果(节点->右侧==临时)
节点->右=空;
else if(节点->左==temp)
节点->左=空;
返回温度;
}
}
返回节点;
}

如果所需节点被调谐为树的根,则只要您有逻辑将调用它的树的根置零,这将起作用。

您的pop函数应该如下所示:

struct data* pop(struct data *node,int num)
{
  struct data* temp=null;
if(node)
{
    if(node->num==num)
    {
      if(node->left)
        pop(node->left,node->left->num);
      if(node->right)
        pop(node->right,node->right->num);
      free(node);
    }
    else
    {
        if(num> node->num)
            temp=pop(node->right,num);
        else if (num< node->num)
            temp=pop(node->left,num);

       if(node->right==temp)
        node->right=null;
       else if(node->left==temp)
        node->left=null;
       return temp;
    }
 }
return node;
}
struct data*pop(struct data*node,int num)
{
结构数据*temp=null;
如果(节点)
{
如果(节点->数量==num)
{
如果(节点->左)
弹出(节点->左,节点->左->数值);
如果(节点->右侧)
弹出窗口(节点->右侧,节点->右侧->数值);
自由(节点);
}
其他的
{
如果(num>节点->num)
temp=pop(节点->右侧,num);
else if(numnum)
temp=pop(节点->左侧,num);
如果(节点->右侧==临时)
节点->右=空;
else if(节点->左==temp)
节点->左=空;
返回温度;
}
}
返回节点;
}

如果所需的节点被调谐为树的根,只要您有逻辑将调用它的树的根置零,这就可以工作。

谢谢dude,它工作了。我想我应该按照你的建议修复我的代码:)谢谢你,伙计,它成功了。我想我应该按照你的建议修复我的代码:)