我在BST中删除节点功能有问题。我测试了所有其他功能正常但如果我在删除节点后打印树,则会导致分段错误 这是我的删除代码:
struct Tree * findinorder (struct Tree *t)
{
while (t->lchild != NULL)
t=t->lchild;
return t;
}
bool deleteNode (struct Tree *t, int fvalue)
{
bool find = false; //this is to check if node is already found don't go to right sub tree
struct Tree *inorder;
if (t==NULL) return find;
if (t->value == fvalue)
{
if (t->lchild == NULL && t->rchild == NULL )
{
free(t);
}
else {
if (t->lchild ==NULL)
t= t->rchild;
else {
if (t->rchild ==NULL)
t= t->lchild;
else {
inorder = findinorder(t->rchild);
t->value = inorder->value;
free(inorder);
}
}
}
return true;
}
find = deleteNode(t->lchild, fvalue);
if (!find)
find = deleteNode(t->rchild, fvalue);
return find;
}
这是树结构和打印功能:
struct Tree
{
int value;
struct Tree *lchild;
struct Tree *rchild;
}*root;
void print (struct Tree *t)
{
if (!t) return;
if(t->lchild != NULL)
print(t->lchild);
printf("%d\n",t->value);
if(t->rchild != NULL)
print(t->rchild);
}
我的怀疑是一些节点如何设置为空,这导致打印问题并继续。
请帮忙。
答案 0 :(得分:0)
您应该保留指向上一个节点的指针,以便您可以相应地更新对rchild
/ lchild
的新引用:
想象node
是指向5的指针,删除(在这个具体案例中)看起来应该更像:
if (node->rchild && node->rchild->value == 21) {
struct Tree *child = node->rchild;
node->rchild = child->rchild; // <-- update reference
free(child);
}
但是看看节点21并想一想它被移除后会发生什么? ...代码应该比找到节点的指针上的free
更复杂:)
在您的情况下,您会free
相应的节点,但在此之后遍历它时,会使用指向之前为free
d的节点的指针,从而产生 未定义的行为 。