从平衡二进制搜索树中删除

时间:2016-04-14 20:09:59

标签: c

我想从平衡BST中删除节点。我编写了以下代码,它可以删除一个子代,但是当我想删除一个有两个子节点的节点时,会恢复一个链接,但是我丢失了另一个节点。这是我的代码:

 Nod* minValue(Nod *p)
{
  Nod *q = p;

    while (q->stg != NULL)
       q = q->stg;

   return q;
}

Nod* os_delete(Nod *p, int k) 
{
   if (p == NULL)
       return p;

   if (k < p->ch)
  {
    p->stg = os_delete(p->stg, k);
  }

  else if (k > p->ch)
  {
     p->dr = os_delete(p->dr, k);
  }

  else
  {
      p->size--;
      if (p->stg = NULL)
      {
          Nod* aux = p->dr;
          free(p);
          return aux;
      }
      else if (p->dr == NULL)
      {
          Nod* aux = p->stg;
          free(p);
          return aux;
      } 

      Nod* aux = minValue(p->dr);
      p->ch = aux->ch;
      p->dr = os_delete(p->dr, aux->ch);
  }
  return p;

}

例如:

          9
    4          15
 1     7    10     18

如果我想用键4删除节点,结果树将是:

        9
 7            15
           10     18

编辑:

typedef struct nod
{
   int ch, size; // ch - key of the node; size - size of node's subtree
   struct nod *stg, *dr; // stg - left; dr - right
}Nod;

1 个答案:

答案 0 :(得分:0)

从平衡二叉树中删除的一种方法是创建一个函数balance()。这将用于重新平衡树。将二叉树中元素的引用指针复制到Inorder中的列表中。然后找到列表的中间元素(将列表分成两半)。它将是您的新根节点。根节点的左子节点将位于列表左半部分的中间位置,根节点的右子节点将位于列表右半部分的中间位置。以递归方式执行此操作以创建平衡树。 现在在删除过程中使用此功能。在找到要删除的节点时,跟踪它的父节点。现在构建删除逻辑,就像在BST情况下一样,但是使用此balance()函数可以在需要时重新平衡树。 资料来源:http://www.codeproject.com/Articles/68500/Balanced-Binary-Search-Tree-BST-Search-Delete-InOr

我不确定你是如何保持树平衡的,但另一种更简单的方法是实现自平衡二进制搜索树,如AVL或R-B树。