红黑树概述
什么是红黑树?
红黑树(Red-Black Tree)是一种自平衡二叉搜索树,由 Rudolf Bayer 于 1972 年发明。它通过额外的颜色标记和旋转操作来维持树的近似平衡,确保最坏情况下的查找、插入、删除操作时间复杂度均为 O(log n)。在 C++ STL 中,std::map 和 std::set 的底层实现均基于红黑树。
每个节点增加了一个存储位表示颜色(红色或黑色),通过对从根节点到任意叶子节点路径上的节点颜色进行约束,保证没有一条路径的长度会比其他路径长出两倍。
红黑树的基本特性
- 节点颜色属性:每个节点的颜色只能是红色或黑色。
- 根节点与叶子节点:根节点必须是黑色;叶子节点(NIL 节点,即空指针)视为黑色。
- 红节点规则:如果一个节点是红色的,则它的两个子节点都是黑色的(不存在连续的红色节点)。
- 黑色高度:对每个节点,从该节点到其所有后代叶子节点的简单路径上,均包含相同数目的黑色节点。
效率分析
相比普通二叉搜索树,红黑树避免了极端情况下退化为链表的风险。相比 AVL 树,红黑树的平衡调整相对宽松,插入和删除时的旋转次数更少,因此在频繁修改的场景下性能更稳定。虽然 AVL 树查询效率略高,但红黑树在综合读写性能上更具优势。
路径长度推导
最短路径为全黑路径,长度记为 bh(黑色高度)。最长路径为黑红交替路径,长度最多为 2 * bh。因此任意路径长度 h 满足 bh ≤ h ≤ 2 * bh,保证了近似平衡。
基本操作
查找操作
红黑树的查找逻辑与二叉搜索树一致,依托'左小右大'的规则,从根节点出发,通过键值比较不断缩小范围。差异仅在于维护平衡的机制不同,查找本身仍是二分比较的形式。
插入操作
插入操作是在二叉搜索树的基础上,通过颜色调整和旋转操作来维持平衡。新插入的节点默认染为红色。若违反红黑性质(如出现连续红节点),需进行调整。
调整场景
我们定义以下变量辅助理解:
c(current):当前触发调整的节点(新插入节点)p(parent):父节点g(grandfather):祖父节点u(uncle):叔叔节点
情况 1:变色
当 c 为红,p 为红,且 u 存在且为红时:
- 将
p和u染为黑色,g染为红色。 - 将
g视为新的当前节点,继续向上回溯检查。 - 原理:保持黑色高度守恒,解决连续红节点问题。若
g变为根节点,需强制染黑。
情况 2:变色 + 单旋
当 c 为红,p 为红,且 u 不存在或为黑时:
- 左左型(
p是 左孩子, 是 左孩子):以 为中心右单旋, 染黑, 染红。


