【问题标题】:Can anyone explain the deletion of Left-Lean-Red-Black tree clearly?谁能解释清楚Left-Lean-Red-Black树的删除?
【发布时间】:2013-03-05 12:05:22
【问题描述】:

我正在学习Left-Lean-Red-Black tree,来自Prof.Robert Sedgewick

http://www.cs.princeton.edu/~rs/talks/LLRB/LLRB.pdf http://www.cs.princeton.edu/~rs/talks/LLRB/RedBlack.pdf

虽然我了解了2-3 treeLLRB 中的insert,但我已经花了大约40 个小时2 周了,我仍然无法删除LLRB。

谁能真正向我解释LLRBdeletion 吗?

【问题讨论】:

  • @Thomas,很多 RB 或 LLRB 只是在谈论插入,没有人真正谈论删除

标签: algorithm data-structures red-black-tree


【解决方案1】:

好的,我要试试这个,也许 SO 的其他好人可以提供帮助。您知道将红色节点视为指标的一种方式是

  1. 树中存在不平衡/新节点的位置,以及
  2. 存在多少不平衡。

这就是为什么所有新节点都是红色的。当节点(局部)平衡时,它们会发生颜色翻转,红色传递给父节点,现在父节点相对于其兄弟节点可能看起来不平衡。

作为一个例子,考虑一个从大到小添加节点的情况。你从节点 Z 开始,它现在是根节点并且是黑色的。您添加节点 Y,它是红色的,是 Z 的左子节点。您添加一个红色 X 作为 Z 的子节点,但现在您有两个连续的红色,因此您向右旋转,重新着色,并且您有一个平衡的全黑(没有不平衡/“新节点”!)植根于 Y [第一幅图] 的树。现在按顺序添加 W 和 V。起初它们都是红色的[第二张图],但立即将 V/X/W 向右旋转,并且颜色翻转,因此只有 X 是红色的[第三张图]。这很重要:X 为红色表示 Y 的左子树有 2 个节点不平衡,或者换句话说,左子树中有两个新节点。所以红色链接的高度是新的、可能不平衡的节点的数量:红色子树中有 2^height 的新节点。

请注意,在添加节点时,红色总是会向上传递:在颜色翻转中,两个红色子节点在将其父节点着色为红色时变为黑色(=局部平衡)。本质上,删除的作用是反转这个过程。就像一个新节点是红色的一样,我们也总是想删除一个红色节点。如果节点不是红色的,那么我们想先把它变成红色。这可以通过颜色翻转来完成(顺便说一下,这就是为什么第 3 页代码中的颜色翻转实际上是颜色中性的)。所以如果我们要删除的孩子是黑色的,我们可以通过颜色翻转它的父母让它变成红色。现在保证孩子是红色的。

接下来要处理的问题是,当我们开始删除时,我们不知道要删除的目标节点是否为红色。一种策略是先找出答案。但是,根据我对您的第一个参考资料的阅读,那里选择的策略是确保删除的节点可以变为红色,方法是在我们向下搜索树时将红色节点“推”到搜索节点前面要删除的节点。这可能会创建不必要的红色节点,fixUp() 过程将在备份树的过程中解决这些节点。 fixUp() 大概维护了通常的 LLRBT 不变量:“没有连续的红色节点”和“没有正确的红色节点”。

不确定这是否有帮助,或者我们是否需要对代码进行更详细的检查。

【讨论】:

  • 这很有帮助。 Just like a new node is red, we always also want to delete a red node. If the node isn't red, then we want to make it red first.,这真是鼓舞人心。
  • 我认为你的轮换有问题。如果 h.left 和 h.left.left 都是红色的,我们在顶部节点上执行 rotateToRight,在您显示的情况下,结果应该是 V/W/X,并且 W 在颜色翻转后变为红色。 {其实你的子树 VXW 不符合二叉搜索树的条件}
  • 我也被卡住了——我似乎从将红色链接视为以黑色链接开头的链条的一部分而获得了一些里程。因此,左边有红色的黑色链接代表长度为 2 的链——2 个节点和 3 个链接,或 3 个节点。左边有红色的黑色链接,左边的红色也代表长度为 3 的链 - 3 个节点和 4 个链接,或 4 个节点。请注意,当 deleteMin 向下移动时测试的条件是当前头的后继节点既不是红色的,也不是其后继节点是红色的——换句话说,它既不是 3 节点@当前头的一部分,也不是开始一个。
  • 此外,我的许多困难出现是因为我混淆了表示和表示的内容:当递归地沿着左脊柱向下移动时,我们关注的是 LLRB 树的结构,但在评估要做什么时在递归的每一点,我们的测试都基于该树所代表的内容(文中描述的算法,即 2-3-4 树)。
【解决方案2】:

哈佛 Comp Sci 教授对 Sedgwich 的实现,特别是它的删除方法有一个有趣的评论。 Left-Leaning Red-Black Trees Considered Harmful 写于 2013 年(您上面引用的 Sedgwich pdf 日期为 2008 年):

棘手的写作

Sedgewick 的论文很棘手。截至 2013 年,插入部分将 2-3-4 棵树作为默认设置,并将 2-3 棵树描述为变体。但是,删除实现仅适用于 2-3 棵树。如果你实现了默认的 insert 变体和唯一的 delete 变体,你的树将无法工作。文本没有突出显示从 2-3-4 到 2-3 的切换:不友好。

我能找到的最新版本的 Sedgwich 代码包含 2-3 实现,日期为 2014 年 4 月。在他的算法图书网站RedBlackBST.java

【讨论】:

  • 他的实现是错误的,只是说。检查 deleteMin 方法。
  • 只是好奇,你真的看过科勒链接到的 Sedgewick 的论文吗?我看不到重复说 2-3 的大标题和周围文本如何没有“突出显示”删除代码是针对 2-3 棵树的。 Sedgewick 甚至对修改 2-3-4 的代码发表了评论。我不知道科勒从哪里得到 2-3-4 是主树而 2-3 是变体的想法。 Sedgewick 从一开始就清楚地展示了这两种类型,两者都没有被描述为“默认”。科勒似乎对他的一些cmets有一把斧头。
【解决方案3】:

按照下一个策略删除 LLRB 树中不在叶子中的任意节点:

  1. 将 LLRB 树转换为 2-3-4 树(我们不需要转换整棵树,只需转换树的一部分)。
  2. 替换其后继节点(我们要删除的节点)的值。
  3. 删除其继任者。
  4. 修复树(恢复平衡,参见“算法第 4 版”一书的页面 435436)。

如果叶子中有一个值,那么我们不需要使用后继树来替换这个值,但是我们仍然需要将当前树转换为 2-3-4 树来删除这个值。

此演示文稿https://algs4.cs.princeton.edu/lectures/keynote/33BalancedSearchTrees.pdf 页面20 上的幻灯片和437 页面上的“算法第4 版”一书是关键。它们展示了 LLRB 树如何转换为 2-3 树。在“算法第 4 版”一书中,页面 442 https://books.google.com/books?id=MTpsAQAAQBAJ&pg=PA442 是树的变换算法。

例如,打开演示文稿https://www.cs.princeton.edu/~rs/talks/LLRB/08Dagstuhl/RedBlack.pdf 的页面54。节点 H 有子节点 D 和 L。根据页面 442 上的算法,我们将这三个节点转换为 2-3-4 树的 4 节点。然后节点 D 有孩子 B 和 F 我们也将这些节点转换为 2-3-4 树的节点。然后节点 B 有孩子 A 和 C 我们也将这些节点转换为 2-3-4 树的节点。最后我们需要删除A。删除后我们需要恢复平衡。我们在树中向上移动并恢复树的平衡(根据规则,请参阅“算法第 4 版”一书的页面 435436)。如果需要删除节点D(页面上的同一棵树54)。您需要相同的转换,需要将节点 D 的值替换为节点 E 的值并删除节点 E(因为它是 D 的继承者)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-02-28
    相关资源
    最近更新 更多