一棵树怎么做到“自平衡还不太费力“?——红黑树的旋转与染色

一棵树怎么做到"自平衡还不太费力"?------红黑树的旋转与染色

408 · 数据结构(45 分)· 树。红黑树的五条性质、与 AVL 的取舍、旋转与染色,是查找章节的高频选择题来源。

先把一棵树"插歪"给你看

假设你手写一棵普通的二叉查找树(BST),按 1, 2, 3, 4, 5, 6, 7 的顺序往里插。插完之后你会发现,这棵"树"长得跟一条斜线没什么两样------查找第 7 个节点要走 7 步,退化成了链表,O(n)。

问题出在哪?BST 只管"左小右大",却不管树高。于是人们发明了各种"自平衡"二叉查找树:AVL 树是最早的一批,它要求左右子树高度差不超过 1,把树压得足够矮,代价是每次插入删除可能要多次旋转,维护成本不低。

红黑树(Red-Black Tree)走了另一条路:不追求"绝对最矮",而是用一套"染色规则"保证树"矮得足够快、维护还不贵"。 这篇文章就讲这套规则。

五条性质,一条都不能少

一棵红黑树,每个节点不是红就是黑,同时满足:

  1. 每个节点要么是红色,要么是黑色;
  2. 根节点是黑色;
  3. 每个叶子(NIL 空节点)是黑色;
  4. 红色节点的两个子节点必须是黑色(不能出现连续两个红);
  5. 从任一节点到其每个叶子的所有路径上,黑色节点数量相同(这条最关键,叫"黑高"一致)。

正是第 4、5 条,逼着树保持"大致平衡"。可以证明:

树高 ≤ 2 log ⁡ 2 ( n + 1 ) \text{树高} \le 2\log_2(n+1) 树高≤2log2(n+1)

也就是说,红黑树的最坏高度是 2 log ⁡ ( n + 1 ) 2\log(n+1) 2log(n+1),查找、插入、删除都能保证 O ( log ⁡ n ) O(\log n) O(logn)。虽然它没 AVL 那么"矮"(AVL 约 1.44 log ⁡ n 1.44\log n 1.44logn),但换来了更少的旋转次数------插入最多 2 次旋转,删除最多 3 次,比 AVL 的多次旋转省事得多。

染色与旋转:它平衡的两件工具

红黑树维持平衡,靠两个动作交替进行:

染色(recolor):把某个节点从红变黑或从黑变红,用来调整"黑高"。

旋转(rotate):和 AVL 一样,分左旋和右旋,用来调整树的结构。旋转不改变"中序遍历顺序",只改变父子关系------所以旋转后它仍是合法的 BST。

插入一个新节点时,惯例先把它染成红色(这样不破坏第 5 条"黑高一致"),然后看它的"叔叔节点"(父节点的兄弟)是什么颜色,分几种情况修补:

text 复制代码
情形 1:叔叔是红色
    → 父、叔变黑,祖父变红,把问题上移到祖父继续处理

情形 2:叔叔是黑色,且新节点是父的"外侧"
    → 旋转父节点 + 重新染色,一次搞定

情形 3:叔叔是黑色,且新节点是父的"内侧"
    → 先旋转到外侧,再按情形 2 处理

细节不必全背,抓住一句话就够:"红红冲突就转一转、染一染,黑高始终不乱。" 删除更复杂(要处理"少了一个黑"的情况),但思想和插入一样,都是"破坏哪条性质,就针对性修补哪条"。

红黑树 vs AVL,到底选谁

这是面试最爱问的对比题,答案其实藏在"读写比例"里:

对比项 AVL 树 红黑树
平衡要求 严格(高度差 ≤ 1) 宽松(红黑规则)
树高 更矮(≈ 1.44 log n) 略高(≤ 2 log n)
查找 更快 稍慢
插入/删除 旋转多、更慢 旋转少、更快
典型用途 查多写少的场景 写多、读写均衡的场景

一句话:AVL 是"查得极致",红黑树是"写起来省心"。 所以 Linux 的进程调度、Java 的 TreeMap、C++ 的 std::map,这些"插删频繁"的场合,清一色选了红黑树。

一个会出在选择题里的细节

408 选择题常考红黑树的性质判断题,比如:

一棵红黑树,从根到叶的最长路径,最多是最短路径的几倍?

根据性质 4(不能连续两个红)和性质 5(黑高一致),最长路径是"红黑红黑"交替,最短路径是"全黑",所以最长最多是:

2 × 黑高 黑高 = 2 倍 \frac{2 \times \text{黑高}}{\text{黑高}} = 2 \text{ 倍} 黑高2×黑高=2 倍

答案:2 倍。 这就是"大致平衡"的量化含义------它没有 AVL 那么紧(AVL 最多约 1.44 倍),但换来的是插入删除的廉价。

回到开头那棵插歪的树:红黑树用"两条染色规则 + 几次旋转",就换来了"任何时刻最坏 O ( log ⁡ n ) O(\log n) O(logn)"的承诺。它不追求绝对最矮,只追求"矮得够用、维护还便宜"。下次再在源码里撞见 rb_insert、rb_erase 这样的函数名,你会知道------那团红黑相间里,藏着一套用"约束换效率"的平衡术。

红黑树、AVL 是数据结构"查找"一章的常客,想系统跟学,B站【408实验室】的《数据结构》里有从 BST 到红黑树的完整推导。

相关推荐
CCblandy1 小时前
向量检索 ANN 参数实测:换一种数据分布,recall 掉了 51 个百分点
人工智能·python·算法·自然语言处理·性能优化
Logic1011 小时前
C语言/数据结构位运算题解:异或XOR找出被挑选一次的果子编号——只出现一次的数字
c语言·数据结构·算法·数组·位运算·时间复杂度·空间复杂度
深圳市快瞳科技有限公司1 小时前
面向端侧部署的多帧宠物身份识别:完整性评分机制与工程约束
人工智能·算法·计算机视觉·端侧ai·宠物识别·宠物ai·宠物身份识别
从小白到软工3 小时前
4-3 项目-学生成绩管理系统(上)
c语言·开发语言·数据结构·经验分享·ai编程
悠仁さん3 小时前
非类型模板参数的特化与偏特化
java·数据结构·算法
垆边人似月.3 小时前
最优河堤加固(二分答案 + 前缀和)
算法
171320330计算机毕设编程3 小时前
计算机毕业设计 基于Hadoop的新能源汽车发展前景分析 LW PPT
java·大数据·hadoop·python·算法·随机森林·线性回归
haluhalu.4 小时前
深入理解 AI Agent(1.2):Harness 工程——模型之外的竞争力
前端·数据结构·人工智能·python·langchain·个人开发
垆边人似月.4 小时前
幻兽防御战(贪心算法)
数据结构·算法