RB-INSERT-FIXUP

概述

RB-INSERT-FIXUP 是红黑树插入操作中的修复过程。由于新插入的节点被着为红色,可能违反红黑性质 2(根为黑)或性质 4(红节点的子节点为黑)。RB-INSERT-FIXUP 通过变色旋转操作恢复红黑性质,最多执行 2 次旋转,总时间复杂度为

定义

RB-INSERT-FIXUP(T, z)

给定红黑树 和新插入的红色节点 ,RB-INSERT-FIXUP 通过迭代修复,恢复 的所有红黑性质。

为什么新节点着红色

在 RB-INSERT 中,新节点 被着为红色。这一选择是关键的设计决策:

  • 着红色:只可能违反性质 2( 恰好是根)或性质 4( 的父节点为红色)。这两种情况都容易修复。
  • 着黑色:必定违反性质 5(黑高度一致性),因为从根到 的路径上多了一个黑色节点,而其他路径没有。修复代价远大于着红色。

因此,着红色是”最小破坏”策略,使得修复过程尽可能简单。

三种情况分析

为新插入的红色节点, 的父节点)。由于 为红色且违反了性质 4,因此 必为红色。

的祖父节点),由性质 4, 必为黑色。

的另一个子节点(即 叔叔节点,uncle)。

以下分析假设 左子节点)。 右子节点的情况完全对称。

Case 1:叔叔 为红色

        pp(B)              pp(R)
       /    \             /    \
     p(R)   u(R)   →    p(B)  u(B)
     /                   /
   z(R)                z(R)

处理方法:

  1. 着为黑色
  2. 着为黑色
  3. 着为红色
  4. ,将问题上移两层到祖父节点

效果: 所在的子树的黑高度不变( 从红变黑, 从黑变红),但 变红后可能继续违反性质 4,因此需要继续循环处理。

Case 2:叔叔 为黑色, 的右子节点

        pp(B)            pp(B)
       /    \           /    \
     p(R)   u(B)  →  z(R)   u(B)
       \              /
       z(R)         p(R)

处理方法:

  1. 执行左旋 旋转
  2. (此时 变为 的左子节点)
  3. 转入 Case 3

效果: Case 2 本身不修复问题,而是将情况转化为 Case 3。

Case 3:叔叔 为黑色, 的左子节点

        pp(B)             p(B)
       /    \           /    \
     p(R)   u(B)  →  z(R)  pp(R)
     /                       \
   z(R)                      u(B)

处理方法:

  1. 着为黑色
  2. 着为红色
  3. 执行右旋 旋转

效果: 修复完成。(现在是 的左子节点)和 都是黑色, 变为红色但不违反性质 4(因为 的父节点是黑色的,或者 变为根)。

伪代码

RB-INSERT-FIXUP(T, z)
  while z.p.color == RED
      if z.p == z.p.p.left
          y = z.p.p.right          // y 是叔叔
          if y.color == RED        // Case 1
              z.p.color = BLACK
              y.color = BLACK
              z.p.p.color = RED
              z = z.p.p
          else
              if z == z.p.right    // Case 2
                  z = z.p
                  LEFT-ROTATE(T, z)
              // Case 3
              z.p.color = BLACK
              z.p.p.color = RED
              RIGHT-ROTATE(T, z.p.p)
      else                         // 对称情况(p 是右子节点)
          // 与上面完全对称,left/right 互换
  T.root.color = BLACK             // 确保性质 2

核心性质

旋转次数

最多 2 次旋转

  • Case 1 不需要旋转,只需变色。但 Case 1 可能重复多次(每次上移两层)。
  • Case 2 需要 1 次旋转,然后转入 Case 3。
  • Case 3 需要 1 次旋转,修复完成。
  • 因此,整个修复过程最多需要 2 次旋转(Case 2 + Case 3 各一次)。

时间复杂度

  • Case 1 的循环最多执行 次(每次 上移两层,树高为 ),但每次只有 的变色操作。
  • Case 2 + Case 3 最多 2 次旋转, 时间。
  • 总时间复杂度为

循环终止条件

循环在以下两种情况下终止:

  1. 为黑色(或 为根):此时 为红色不违反任何性质。
  2. 进入 Case 3 并执行旋转后:此时 被着为黑色,循环条件不再满足。

循环结束后,最后将根节点着为黑色(确保性质 2),即使根节点本来就是黑色(幂等操作)。

章节扩展

RB-INSERT 的完整流程:

  1. BST 插入:像普通 BST 一样插入新节点
  2. 着色:将 着为红色。
  3. 修复:调用 RB-INSERT-FIXUP 恢复红黑性质,

总时间复杂度:

参见