红黑树概述
红黑树是一种自平衡二叉搜索树,由德国计算机科学家 Rudolf Bayer 在 1972 年发明。它通过额外的颜色标记和旋转操作来维持树的近似平衡,确保最坏情况下的基本操作(插入、删除、查找)时间复杂度为 O(log n)。
核心特性
- 节点颜色:每个节点要么是红色,要么是黑色。
- 根节点:根节点必须是黑色。
- 叶子节点:所有叶子节点(NIL 节点,即空指针)都是黑色的。
- 红节点规则:如果一个节点是红色的,则它的两个子节点都必须是黑色的(不存在连续的红色节点)。
- 黑色高度:对每个节点,从该节点到其所有后代叶子节点的简单路径上,均包含相同数目的黑色节点。
这些约束保证了从根到叶子的最长路径不会超过最短路径的两倍,从而实现了近似平衡。
效率分析
相比 AVL 树,红黑树对平衡性的要求稍低,因此在插入和删除时进行的旋转次数更少,性能更稳定。AVL 树追求严格平衡,查询效率高但维护成本高;红黑树在保持 O(log n) 复杂度的同时,牺牲了部分查询效率换取了更高的更新效率。这也是 C++ STL 中的 map 和 set 底层采用红黑树的主要原因。
基本操作
查找操作
查找逻辑与普通二叉搜索树一致,利用'左小右大'的特性递归或迭代向下查找。差异仅在于平衡维护机制不同,查找本身的二分比较形式保持一致。
插入操作
插入操作是在二叉搜索树的基础上,通过颜色调整和旋转操作来维持树的近似平衡。新插入的节点默认为红色。如果插入后破坏了红黑性质,则需要调整。
调整场景
我们定义以下变量以便描述:
c(current):当前触发调整的节点(新插入节点或其祖先)。p(parent):c的父节点。g(grandfather):p的父节点(祖父节点)。u(uncle):p的兄弟节点(叔叔节点)。
情况 1:变色
当 c 为红色,p 为红色,且叔叔节点 u 存在且为红色时:
- 将
p和u染为黑色,g染为红色。 - 将
g视为新的当前节点,继续向上回溯检查。 - 若
g变为根节点,需强制染回黑色。
情况 2:变色 + 单旋
当 c 为红色,p 为红色,且叔叔节点 u 不存在或为黑色时:
- 左左型(
p是g左孩子,c是p左孩子):以g为中心右单旋,p染黑,g染红。 - 右右型(
p是g右孩子,c是p右孩子):以g为中心左单旋,p染黑,g染红。
情况 3:变色 + 双旋
当 c 为红色,p 为红色,且叔叔节点 不存在或为黑色,但结构呈左右或右左型时:


