(xa4)红黑树:删除

官方信息技术老师·12 页·深入(追求细节与边界)·0 次浏览·3 天前
删除修复双黑结点颜色翻转旋转调整

(xa4)红黑树:删除

拆解删除后的4种修复情形,掌握双黑、颜色翻转与旋转的完整逻辑

按 空格/→ 演示下一步

1 / 12 页

全部页面点击任意一页,跳回舞台从这页播放

删除修复双黑结点颜色翻转旋转调整

(xa4)红黑树:删除

拆解删除后的4种修复情形,掌握双黑、颜色翻转与旋转的完整逻辑

1第 1 页 · (xa4)红黑树:删除

以曲为直

删除有两个孩子的节点很棘手——直接抽走,左右两棵子树就成了无主的孤儿。红黑树的诀窍是'绕一下':用中序后继的值顶替目标节点,转而删除那个后继——它最多只有一个孩子,问题就变简单了。

绕道删法
要删双孩子节点时,不直接动它,而是用后继的值替换后再删后继
中序后继
右子树中的最小节点,值必然≥被删节点,保持有序
问题转化
把「两个孩子」的复杂情况,转化为「至多一个孩子」的简单情况
后继结构简单
后继要么是叶子,要么只有右孩子,删除它不再棘手
后续修复压力减小
删除点变简单后,变色和旋转的修复调整也更容易收敛
搬底层被压的箱子对应 →删双孩子节点

先把上面碍事的挪开,搬走底箱;上面不必原样放回——绕了一圈,直路反而走得通

2第 2 页 · 以曲为直

算法框架

BST 删除我们已熟:找节点、替换、断开。但红黑树多了一道锁——删完必须保住五条性质。一旦删的是黑节点,这条路径就'欠了一个黑',得靠兄弟子树来偿还。

BST 删除为骨
先按搜索树规则删,找后继或前驱替换,再物理断开
双黑标记
删黑节点令该路径黑高少 1,用'双黑'标记记下这笔账
兄弟分类
按兄弟颜色与两侄节点颜色分 4 类核心情形,左右镜像对称
旋转偿还
通过旋转与重染色把双黑上移到根或就地消除
对数保证
树高始终 O(log n),双黑最多上移至根即消解
家族一人欠债对应 →双黑上移修复

兄弟替还或侄子顶债,层层上传至父亲,直至账平或归零

3第 3 页 · 算法框架

双黑缺陷

前页框架把删点后的修正交给接替结点 x;删去黑结点后,相关路径会少 1 个黑高单位。这个缺口若用“额外黑”记录,就形成双黑缺陷。

产生来源
删去黑色结点后,黑色接替结点 x 会代表一条少 1 的黑高路径。
额外黑标记
双黑不是再涂一次黑色,而是“普通黑+额外黑”的临时记账。
观察兄弟
若黑兄弟的两个孩子都黑,兄弟改红,缺口上移给父亲。
典型修复
黑兄弟若左红右黑,先旋兄弟,再旋父亲并重着色,使 x 到根。
终止条件
x 到根时额外黑可被吸收;父亲为红时也可补黑退出。
账本出现一笔亏空对应 →双黑缺陷

被删黑位像多记的一笔;x 是欠款位置,兄弟、父亲与根构成补款链路。

4第 4 页 · 双黑缺陷

BB-1

前面看到了删除黑色节点会冒出「双黑」缺陷,也知道修复要绕到兄弟子树。现在我们退一步,把红黑树删除这件事正式定义一下:它做什么、难点在哪、用在哪里。

删除的定义
在红黑树上删去指定节点,并让树重新满足五条性质
五条性质再确认
根黑、叶黑算 NIL 黑,红父子不连续,每路黑高相等
真正难点
删黑节点使某路黑高少 1,相当于子树「欠一」需补偿
核心思路
宁可多绕几步,把修复集中到兄弟子树上完成
典型应用
Java TreeMap、Linux CFS 调度器、数据库索引底层结构
拆大楼承重柱对应 →删除黑色节点

拆掉一根柱子后,顶部重量要分给相邻柱子(兄弟子树)重新平衡

5第 5 页 · BB-1

反观回味

走完 BB-1 回头看,删除的真相没那么神秘——核心就一句'黑高不能乱',而修复的关键不在'补'而在'借'。

核心矛盾
删除可能让某条路径的黑色节点数变少,破坏'黑高相等'这条铁律
以曲为直
不试图直接补黑,而是旋转+变色绕道修复,等价于借红色节点补偿
双黑节点
黑节点被删后位置'欠一份黑',需向上和向兄弟借债来化解
化解模式
BB-1 是兄弟为红:旋转+变色把红色推到祖父一侧,一次搞定
复杂度与应用
删除仍 O(log n) 但常数更大,适合读多写少,如 TreeMap、Linux CFS
仪仗队每排黑衣队员数相同对应 →红黑树每条路径黑高相同

有人离队时不能直接补,要靠调队形(旋转)和换肩章(变色)让各排依然平衡

6第 6 页 · 反观回味

BB-2R

BB-1 我们已经会了——远侄红,一旋就完。但天不遂人愿:远侄偏偏是黑的、近侄才是红的,套 BB-1 走不通。这就是 BB-2R 出场的时刻。

形态识别
兄弟黑、近侄(同侧)红、远侄(对侧)黑
一次同向旋转
对兄弟与近侄做一次旋转,把结构调成 BB-1
形态转化
旋完后,原近侄升为新兄弟的远侄,且为红色——正好是 BB-1
化曲为直
此后直接走 BB-1 流程,一次旋转着色即可恢复
下棋调位再将军对应 →BB-2R 旋转化 BB-1

当前局面不能直接赢,先把子挪到能赢的形态,再一击制胜

7第 7 页 · BB-2R

BB-2B

BB-2R 运气好——有个红侄子帮忙,旋转一下就搞定。可如果兄弟俩都是黑孩子,没人能帮忙扛这个'多出来的黑',怎么办?

形态条件
兄弟 w 为黑,且 w 的左右孩子也均为黑
上推一层
把兄弟 w 染红,让父亲继承这个'多出来的黑'
递归向上
父亲本红则染黑结束;父亲本黑则继续向上递归
没人接棒的接力对应 →BB-2B 上推递归

当前层没人能解决,把多出来的黑责任推给上层

8第 8 页 · BB-2B

BB-3

BB-2R 和 BB-2B 都能靠旋转一锤定音。可若双黑的兄弟是黑的、左右侄儿也都黑——没有红孩子可借色,旋转也无处着力。BB-3 的出路只有一条:把兄弟染红,让双黑顺着父节点继续往上推。

触发条件
双黑节点的兄弟为黑,且兄弟的左右孩子(左侄、右侄)均为黑
核心染色
把兄弟节点染为红色
双黑上移
父节点继承双黑,问题沿树上升一层
终止方式
推到根自然消除,或中途转化为 BB-1 / BB-2R / BB-2B
黑高平衡
兄弟染红少 1 个黑高,由父节点继承的双黑补回,整树黑高不变
难题层层上交对应 →BB-3 双黑上移

兄弟无力解决,把双黑甩给上一级;上一级若也无力再上甩,直到根或可解决的位置

9第 9 页 · BB-3

: 归纳体味

BB-1 旋转、BB-2R 终结、BB-2B 上推、BB-3 变形——四个分支各不相同,但拆开看,它们都在回答同一道题:删除黑节点留下的那层'黑色'该往哪去。

双黑缺口
删除黑节点时,子树黑高比兄弟少 1,需要找地方补回这一层
四种分支
BB-1 旋转转情形、BB-2R 终结型、BB-2B 上推型、BB-3 过渡型
上推收敛
BB-2B 把缺口推给父节点,沿根路径最多上升 O(log n) 层
终止条件
缺口推至根直接消化,或转入 BB-2R 一次性终结
出差超支要报销对应 →双黑缺口的消化

BB-2R 直接平账;BB-2B 推上级;BB-1/BB-3 调整票据再走流程

10第 10 页 · : 归纳体味

本节要点

  • 红黑树删除 = BST 删除 + 修补双黑缺陷
  • 双黑沿父链上移,遇红兄弟或根即停
  • BB-1/2/3 穷尽修补情形,BB-2 按侄子细分
  • 单次修补常数次旋转/染色,整体 O(log n) 不破
延伸主题:2-3-4 树视角再理解红黑树红黑树 vs AVL 树对比
11第 11 页 · 本节要点

课后思考

先合上书想五分钟,再翻看参考答案——这三问没有标准答案,思路比结论更重要。

1红黑树插入修复只需处理'红红'冲突,删除修复却要引入'双黑'缺陷——这两种不对称背后的本质原因是什么?

参考答案插入只增加红色节点、不改变黑高;删除会真实减少某条路径上的黑节点数。'双黑'是'欠一格黑色'的占位标记,让修复规则能统一处理所有路径——这是红黑树不变量设计的精髓。

2BB-2 中兄弟为红(BB-2R)与为黑(BB-2B)处理截然不同:前者能一步终止,后者必须继续上推——为什么会有这种差别?

参考答案BB-2R 时兄弟为红,意味着父和侄子必黑,可借一格黑色补上当前缺口,多余的红色上推后黑高立即平衡。BB-2B 时兄弟为黑,能借的不够,只能染红兄弟、把'债'转嫁给父节点继续修。

3对比 AVL 树,红黑树删除修复只有 4 种 BB-情形;若换一棵约束更严格的平衡树,分支数和最坏旋转次数会如何变化?为什么?

参考答案分支数会显著增多(AVL 失衡类型更多),最坏旋转次数也可能上升。约束越严,失衡可能性越高、修复代价越大——红黑树用'宽松黑高'换'低廉修复代价',是工程取舍的典范。

12第 12 页 · 课后思考
(xa4)红黑树:删除 · 知识图解