红黑树的概念
红黑树是一棵二叉搜索树,它的每个结点增加一个存储位来表示结点的颜色,可以是红色或者黑色。通过对任何一条从根到叶子的路径上各个结点的颜色进行约束,红黑树确保没有一条路径会比其他路径长出 2 倍,因而是接近平衡的。
规则
- 每个结点不是红色就是黑色
- 根结点是黑色的
- 如果一个结点是红色的,则它的两个子结点必须是黑色的,也就是说任意一条路径不会有连续的红色结点
- 对于任意一个结点,从该结点到其所有 NULL 结点的简单路径上,均包含相同数量的黑色结点

为上面的红黑树,有多少条路径?
答案是 10 条,因为要走到空才算一条。
在上面的规则与图中我们发现,根节点一定为黑,那么最短路径就是全黑,最长路径就是黑红黑红相间,这就实现了最短路径与最长路径是二倍的关系。
红黑树的效率
假设 N 是红黑树中结点数量,h 最短路径的长度,那么 $2^h - 1 \le N < 2^{2h} - 1$,由此推出 $h \approx \log_2 N$ 到 $2 * \log_2 N$,也就是意味着红黑树增删查改最坏也就是走最长路径,那么时间复杂度还是 O(logN)。红黑树的表达相对 AVL 树要抽象一些,AVL 树通过高度差直观的控制了平衡。红黑树通过 4 条规则的颜色约束,间接的实现近似平衡,他们效率都是同一档次,但是相对而言,插入相同数量的结点,红黑树的旋转次数是更少的,因为他对平衡的控制没那么严格。
红黑树的实现
红黑树实现的大致思路与前面的 AVL 类似,只不过前面的 bf 变成了此处的 color。
红黑树的大致框架
// 枚举值表示颜色
enum Colour { RED, BLACK };
// 这里我们默认按 key/value 结构实现
template<class K, class V>
struct RBTreeNode {
// 这里更新控制平衡也要加入 parent 指针
pair<K, V> _kv;
RBTreeNode<K, V>* _left;
RBTreeNode<K, V>* _right;
RBTreeNode<K, V>* _parent;
Colour _col;
RBTreeNode(const pair<K, V>& kv) :_kv(kv), _left(nullptr), _right(nullptr), _parent(nullptr) {}
};
template<class K, class V>
class RBTree {
RBTreeNode<K, V> Node;
:
:
Node* _root = ;
};






