C++ 手写红黑树:深入理解 STL map 底层结构
1. 红黑树的概念
红黑树本质上是一棵二叉搜索树,每个节点额外增加了一个颜色位(红色或黑色)。通过对路径上颜色的约束,它确保没有一条路径会比其他路径长出两倍,从而保持近似平衡。
1.1 核心规则
- 每个节点非红即黑。
- 根节点必须是黑色。
- 红色节点的子节点必须是黑色(即不存在连续红节点)。
- 任意节点到其所有叶子节点(NIL)的简单路径上,包含相同数量的黑色节点。
注意:《算法导论》中提到的'叶子节点为黑色'通常指外部空节点 NIL。实际编码中常忽略显式的 NIL 节点,但逻辑上需遵循此约束。


1.2 为什么最长路径不超过最短路径的 2 倍?
根据规则 4,每条路径的黑色节点数 bh 是固定的。极端情况下,最短路径全为黑色,长度为 bh。而规则 2 和 3 限制了红色节点不能连续,因此最长路径是一黑一红交替,长度约为 2 * bh。综合来看,若路径长度为 h,则满足 bh <= h <= 2 * bh。
1.3 效率分析
设节点数为 N,高度为 h,则有 2^h - 1 <= N <= 2^(2*h) - 1。由此推导出 h ≈ logN。这意味着红黑树的增删查改在最坏情况下时间复杂度仍为 O(logN)。相比 AVL 树,红黑树对平衡的控制稍宽松,插入时的旋转次数更少,更适合频繁插入的场景。

2. 红黑树的实现
2.1 数据结构定义
我们需要一个节点结构体,包含键值对、左右子指针、父指针以及颜色属性。模板化设计使其能适配不同数据类型。
enum Colour { RED, BLACK };
template<class K, class V>
struct RBTreeNode {
pair<K, V> _kv;
RBTreeNode* _left = ;
RBTreeNode* _right = ;
RBTreeNode* _parent = ;
Colour _col = RED;
( pair<K, V>& kv) : _kv(kv), _col(RED) {}
};
< , >
{
RBTreeNode<K, V> Node;
:
:
Node* _root = ;
};





