【问题标题】:Deleting from a Balanced Binary Search Tree从平衡二叉搜索树中删除
【发布时间】:2016-04-14 20:09:58
【问题描述】:

我想从平衡 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;

【问题讨论】:

  • s/childs/children/。 :-)
  • Nod 结构/类是什么样的?
  • 我编辑了帖子。
  • 除了你的预期之外,你能展示你实际得到的东西吗?

标签: c


【解决方案1】:

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-12-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-13
    相关资源
    最近更新 更多