在BST中删除节点

时间:2013-09-22 10:09:55

标签: c free binary-search-tree treenode

我在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);
}

我的怀疑是一些节点如何设置为空,这导致打印问题并继续。
请帮忙。

1 个答案:

答案 0 :(得分:0)

您应该保留指向上一个节点的指针,以便您可以相应地更新对rchild / lchild的新引用:

enter image description here

想象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的节点的指针,从而产生 未定义的行为