红黑树
1. 红黑树
1.1 红黑树的定义
红黑树是一棵二叉搜索树,它的每个结点增加一个存储位来表示结点的颜色,可以是红色或者黑色。 通过对任何一条从根到叶子的路径上各个结点的颜色进行约束,最长的不超过最短的 2 倍(近似平衡)。
1.2 红黑树的规则
- 每个结点不是红色就是黑色
- 根结点是黑色的
- 如果一个结点是红色的,则它的两个孩子结点必须是黑色的,也就是说任意一条路径不会有连续的红色结点。
- 对于任意一个结点,从该结点到其所有 NULL 结点的简单路径上,均包含相同数量的黑色结点。 最长路径(一黑一红) <= 2*最短路径(全黑)(四条规则约束) 数路径要数到空结点。(NIL 结点数路径)
1.3 红黑树的效率:
最短路径 logN,最长路径 2*logN,时间复杂度就是 O(logN)。
2. 红黑树的实现
2.1 红黑树的插入
(插入红色结点,按照二叉搜索树的规则,和四条红黑树的规则)
2.1.1 情况 1:变色
- c 为红,p 为红,g 为黑,u 存在且为红,则将 p 和 u 变黑,g 变红。在把 g 当做新的 c,继续往上更新。 情况 1 只变色,不旋转。所以无论 c 是 p 的左还是右,p 是 g 的左还是右,都是上面的变色处理方式。
2.1.2 情况 2:单旋 + 变色
- c 为红,p 为红,g 为黑,u 不存在或者 u 存在且为黑,u 不存在,则 c 一定是新增结点,u 存在且为黑,则 c 一定不是新增,c 之前是黑色的,是在 c 的子树中插入,符合情况 1,变色将 c 从黑色变成红色,更新上来的。
2.1.3 情况 3:双旋 + 变色
- c 为红,p 为红,g 为黑,u 不存在或者 u 存在且为黑,u 不存在,则 c 一定是新增结点,u 存在且为黑,则 c 一定不是新增,c 之前是黑色的,是在 c 的子树中插入,符合情况 1,变色将 c 从黑色变成红色,更新上来的。
2.2 红黑树的插入代码实现
// test.cpp
#include <iostream>
#include <vector>
using namespace std;
#include "RBTree.h"
// void TestRBTree1()
// {
// RBTree<int, int> t;
// // 常规的测试用例
// // int a[] = { 16, 3, 7, 11, 9, 26, 18, 14, 15 };
// // 特殊的带有双旋场景的测试用例
// int a[] = { 4, 2, 6, 1, 3, 5, 15, 7, 16, 14, 3, 5, 66, 33, 543, 54, 2, 435, 321, 32, 43, 4324, 534 };
// for (auto e : a)
// {
{
bit::();
bit::();
;
}


