如何在BST C语言中删除子树?
我想做一个pop函数来删除节点和节点的子树。这是我的密码如何在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;
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,它工作了。我想我应该按照你的建议修复我的代码:)谢谢你,伙计,它成功了。我想我应该按照你的建议修复我的代码:)