【问题标题】:Iterative Algorithm for Red-Black Tree红黑树的迭代算法
【发布时间】:2011-04-15 01:47:03
【问题描述】:

任何人都可以向我建议任何指向用于在红黑树中插入和删除的迭代算法的指针吗? .Net/C# 中可用的所有算法都基于递归,我不能相信它可以处理大量数据(因此插入/删除的递归深度很大)。有人有基于迭代的吗?

注意:Goletas.Collection 使用 AVL 树的迭代算法,该算法对大量数据非常有效,我也希望 Red-Black Tree 也有类似的东西。

【问题讨论】:

  • 由于红黑树是平衡的,因此包含N 元素的树的高度约为log_2(N)(最多2*log_2(N+1))。因此,即使您的结构非常大,递归操作也不会采取那么多步骤。当然,你还没有具体说明什么是“大”(你能澄清一下吗?)。另外,您是否尝试过使用现有的自平衡树实现?否则,如果您开始实施一些不必要的事情,那将是浪费时间。

标签: .net algorithm red-black-tree


【解决方案1】:

基于树的算法本质上是递归的。

当然,您可以将它们重写为迭代,但那将是徒劳的。原因如下:

红黑树和类似的数据结构是自平衡的,它们的高度与存储的值的数量成对数。这意味着您将永远不会达到递归上限——这需要您插入 ~ 22000 个元素,这根本不会发生:您的计算机没有足够的内存,而且永远不会。

– 坚持递归,没关系。

【讨论】:

  • 是的,我同意你的观点,但是迭代算法不是比递归算法花费的时间少得多吗?我也担心响应时间,我忘了提及。
  • @Anindya:恰恰相反。递归依赖于调用栈,这是一个非常高效的低级数据结构。如果将算法重写为迭代,则需要管理自己的堆栈,这总是效率较低(至少增加一级指针间接,加上边界检查)。使迭代比递归更有效的唯一方法是摆脱显式堆栈(尾递归)。迭代比递归更快的谣言只是:谣言。
【解决方案2】:

感谢大家提供宝贵的 cmets。我刚刚找到了一个,但在 VB6 和 C 中。我认为它足以掌握这个想法。这是链接

  1. Article
  2. C Source
  3. VB Source

希望有人会觉得它有帮助。 :)

【讨论】:

  • 你有没有找到更好的版本/你自己实现了?我想知道 10 年后你会如何改变你的答案。
【解决方案3】:

Thomas H Cormen、Charles E Leiserson、Ronald L Rivest、Clifford Stein 在算法简介中有一个版本。

伪代码在Google books(第270页)在线提供。

就像在 cmets 中指出的那样,将数据复制到节点 z 而不是在第 14/15 行用 y 替换 z 的方法不是最佳的,特别是如果您有指向其他地方的节点的指针.所以第 13-16 行可以改为:

do_fixup = y.color == BLACK

if y is not z:
    replace_parent(tree, y, z)
    y.left = z.left
    y.left.parent = y
    y.right = z.right
    y.right.parent = y
    y.color = z.color

if do_fixup:
    ...

replace_parent 定义为(也可用于第 7-12 行):

def replace_parent(tree, a, b):
    a.parent = b.parent
    if not b.parent:
        tree.root = a
    else:
        if b is b.parent.left:
            b.parent.left = a
        else:
            b.parent.right = a

【讨论】:

  • 必须注意,他们的 RBT 节点删除伪代码是危险的,因为它没有正确地重新链接一个节点,它只是从另一个节点复制数据到它。请参阅第 288 页的 RB-DELETE(T,z) 的第 15 行。
  • @AlexeyFrunze 为什么这很危险?你能解释一下应该怎么做吗?
  • 它不适用于实际的 C 和 C++ 代码。如果从节点数据到节点或其他地方的节点数据有任何指针/引用,代码会中断,因为它们变得无效。解决方法是只进行预期的节点交换而不复制节点数据。您只需要正确地将节点重新链接到其他节点。
  • 特别是一个场景不适用于本书中描述的方法。如果您希望数据位于 2 棵或更多树的节点中,则删除一棵树中的节点会损坏另一棵树。
  • @AlexeyFrunze 更新了答案,这是您的首选方式吗?
猜你喜欢
  • 2021-10-17
  • 2011-03-27
  • 1970-01-01
  • 1970-01-01
  • 2017-12-23
  • 2010-09-06
  • 2018-05-20
  • 2012-12-16
相关资源
最近更新 更多