【问题标题】:Red-Black Tree - Black Height restriction红黑树 - 黑色高度限制
【发布时间】:2013-02-09 16:51:50
【问题描述】:

我正在阅读关于 Red-Black Trees 的 wiki。

谁能详细说明第五条限制:

  1. 节点不是红色就是黑色。

  2. 根是黑色的。

  3. 所有叶子 (NIL) 都是黑色的。 (所有的叶子都和根的颜色一样。)

  4. 每个红色节点的两个孩子都是黑色的。

  5. 从给定节点到其任何后代叶子的每条简单路径都包含相同数量的黑色节点。

鉴于the final case of insertion(wiki 上的案例 5)之后示例 RBT 的状态,我很难理解它:

4 和 5 不是比 1,2 和 3 多一个黑色节点吗?

【问题讨论】:

  • 不,因为 1、2 和 3 是黑色节点,而 4 和 5 不是,所以这五个路径都有两个黑色节点。
  • 当然看起来是这样,不是吗。现在你让我想知道维基是否是错误的。 wiki会出错吗?这动摇了我对世界坚固性的信心!
  • 是的,Wiki 是错误的 U 从一开始就应该是红色的。所以最后也是红色的。
  • *文章的图片具有误导性 w.r.t.属性 5 和着色。
  • 是的,实际上,忽略了tree 在旋转之前和之后的颜色,它只是镜像了完全相同的结构,所以旋转它不会产生降神作用......

标签: java c++ algorithm tree


【解决方案1】:

刚刚仔细看了下,图片好像有问题。

由于N 是刚刚插入的节点,这意味着在P 下的最后一个insert 之前有子[1,3] 或[2,3](插入为2 或1 恭敬地)。所以在这种情况下,在最后一次插入之前,PU 必须是红色的(而 4,5 是黑色的)。

【讨论】:

  • 没有。该图具有双重作用。它满足两种情况 (i) N 是刚刚插入的节点,在这种情况下 1 和 2 不存在 (ii) 插入的节点远低于子树 1 或 2 之一,N 是原始节点的祖父或祖父等的祖父,现在需要修复的新节点。 (ii) 的情况将循环向根方向前进,只要当前父级和当前叔叔是红色的,并且祖父的父级也是红色的。
【解决方案2】:

1、2、3、4 和 5 都是子树。我们知道树 1、2 和 3 中根节点的颜色为黑色。我们不知道节点 1-5 中的任何一个是否是叶节点,因为这种插入情况可能是在某个作为新插入节点的祖父母的 N 上递归调用的(来自插入情况 3)。

旋转前后,子树1、2、3都在一个黑色节点之下(G之前,P之后),子树4和5在两个黑色节点之下(G和U之前,P和U之后) .子树 1、2 和 3 分别比子树 4 和 5 多一个黑色节点。

【讨论】:

  • 深入研究它,我会选择这个。 1、2、3、4 和 5 本身不是叶子,而是它们自己的子树。 N 和 G 有黑色的孩子(1,2,3 的头),所以从那里出来的每条路径都没有真正改变,因为它和以前一样多的黑色节点。之前通过 U 的每条路径都将 U 和 G 作为黑色节点(两个),因此在旋转之后,现在每条路径都必须通过 U 和 P 黑色节点(两个)。与以前相同数量的黑色节点。所以限制仍然有效,假设限制在它们下面的子树上。
  • 此外,子树 1,2 和 3 中的黑色节点比 4 和 5 多一个,因为 4 和 5 通过 U 获得它们需要匹配 1,2 的额外黑色节点,并且3. 我现在有点明白了。
【解决方案3】:

祝贺 James 破译了 Wiki 图!没有错,只是模棱两可。

该页面的“讨论”选项卡提到“三角形不是代表叶子而是代表子树。有些子树顶部有黑色圆圈,表示它们的根必须是黑色的。”

显然,没有圆圈的三角形代表子树(包括叶子),其根节点的颜色和树的深度是未知的(并且可能不相关)。

因此,图表根本没有提供足够的信息来判断是否违反了“规则 5”。我们必须将其视为既定事实。

【讨论】:

    【解决方案4】:

    NIL 节点配置是完全可选的。它们是黑色的唯一原因是因为您希望默认保存额外的红色节点。以后可以根据需要将它们变为红色。

    分配的黑色节点增加黑色高度,这也是一个可选的高度差。因为必须在某处记录 NIL 标志,所以可以将其分配为黑色节点。

    只能节省 1bit 地址空间;通常系统非常接近其极限。

    【讨论】: