前言
红黑树是 C++ STL 中 map 和 set 的基础数据结构之一,也是平衡二叉搜索树的典型代表。本文将深入探讨其设计原理、核心规则及 C++ 实现细节。
1.红黑树的概念
1.1.红黑树是什么
红黑树是一种二叉搜索树,每个节点增加一个存储位表示该节点的颜色(红色或黑色)。通过对任何一条根到叶子的路径上各个节点的颜色进行约束,红黑树确保没有一条路径会比其他路径长出 2 倍,因而是接近平衡的。
1.2.红黑树的规则
- 每个节点不是黑色的就是红色的。
- 根节点必须是黑色的。
- 如果一个节点是红色的,则它的两个孩子节点必须是黑色的,即任意一条路径上不会出现连续的红色节点。
- 对于任意的一个节点,从该节点到其所有的 NULL 节点的简单路径上,均包含着相同数目的黑色节点。
- 每个叶子节点(NULL)都是黑色的(外部节点)。
以上便是红黑树的五条规则。下面展示几张红黑树的示意图:


1.3.红黑树如何确保最长路径不超过最短路径的两倍
由规则 4 可知,每条路径上有着数量相同的黑色节点。在极端场景下,一条路上全都是黑色节点,最短路径长度记作 bh。
结合规则 2 和规则 3,一条路上不会出现连续的红色节点,所以最长路径应该是一红一黑交织组成,长度为 2bh。
根据红黑树的规则,一般情况下的红黑树路径是由数量不等的红黑节点组成的。假设红黑树一条路径的长度为 h,所以 bh <= h <= 2bh,即红黑树的最长路径不会是最短路径的两倍。
1.4.红黑树的效率问题
假设红黑树的节点个数为 N,最短路径的长度为 h,所以可知:2^h - 1 <= N < 2^(2*h) - 1,由此可以推出 h 大约等于 logN。红黑树查找的效率最差也是 O(log N),时间复杂度终归还是 O(log(N))。
红黑树的表达相对 AVL 树要更抽象一些,AVL 树可以根据高度更加直观地看出树的平衡,而红黑树则是需要根据四条规则的颜色进行约束,间接地实现了近似平衡。他们的效率都是同一档次的,但是相对而言,插入相同数量的节点,红黑树的旋转次数变得更少了,因为它对平衡的把控并不是那么严格。
2.红黑树的实现
2.1.红黑树的结构
红黑树是一个典型的三叉链,节点需要包含父节点以及左右孩子节点。由于红黑树是通过颜色进行平衡的,我们需要设置好一个枚举来确定节点的颜色,默认颜色为红色。红黑树通过 Key 和 Value 存放数据,Key 作为标记,Value 为核心数据。
enum Colour { RED, BLACK };
template<class K, class V>
struct RBTreeNode {
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 = ;
};


