C++ 红黑树设计与实现
1. 红黑树的概念
1.1 什么是红黑树
红黑树是一种自平衡的二叉搜索树。它在每个节点上增加了一个存储位来表示颜色(红色或黑色)。通过对从根到叶子路径上节点颜色的约束,红黑树确保没有一条路径会比其他路径长出两倍,从而保持近似平衡。
它是一棵被严格规则束缚的二叉搜索树,这些规则保证了树的相对平衡性。下面我们来详细看看这些规则。
1.2 红黑树的五条性质
- 每个节点要么是红色,要么是黑色。
- 根节点必须是黑色。
- 如果一个节点是红色的,则它的两个子节点都必须是黑色的(即不能有两个连续的红色节点)。
- 对任意节点而言,从该节点到其所有后代叶子节点的简单路径上,均包含相同数目的黑色节点。
- 所有的叶子节点(NULL 指针)都是黑色的。
注意:这里的'叶子节点'通常指 NULL 指针,有些书籍称之为外部节点。引入 NULL 节点是为了方便准确地标记路径边界。



1.3 为什么最长路径不超过最短路径的两倍
根据性质 4,每条路径上的黑色节点数量是固定的,记为 bh(Black Height)。
- 最短路径:全由黑色节点组成,长度为
bh。 - 最长路径:在满足性质 3(无连续红节点)的前提下,红黑交替出现,长度最多为
2 * bh。
因此,红黑树的最长路径不会超过最短路径的两倍,这保证了树的高度约为 log N。
1.4 效率分析
假设节点数为 N,高度为 h。由于 2^h - 1 <= N < 2^(2h) - 1,可推导出 h ≈ log N。这意味着红黑树的查找、插入和删除操作的时间复杂度均为 O(log N)。
相比于 AVL 树,红黑树对平衡性的要求稍宽松,因此在插入和删除时旋转次数更少,整体性能更稳定。
2. 红黑树的实现
2.1 节点结构
在编写代码前,我们需要定义节点结构。红黑树通常采用三叉链表,节点需包含父节点指针、左右孩子指针以及颜色属性。我们使用 Key-Value 结构存储数据,Key 用于比较大小,Value 为实际数据。
enum Colour { RED, BLACK };
< , >
{
pair<K, V> _kv;
RBTreeNode<K, V>* _left;
RBTreeNode<K, V>* _right;
RBTreeNode<K, V>* _parent;
Colour _col;
( pair<K, V>& kv)
:_kv(kv), _left(), _right(), _parent(), _col(RED) {}
};
< , >
{
RBTreeNode<K, V> Node;
:
Node* _root = ;
};


