1. 红黑树的概念
红黑树也叫RB树(Red-Black Tree),实际就是一种二叉搜索树,只是它的节点不是通过平衡因子来控制树的形状,而是为节点设置了两种颜色来控制,使得树中最长路径中节点个数不会超过最短路径节点个数的两倍,这样就能保证树触发旋转的几率大大减小。因此红黑树在每个节点上增加了一个一个的存储位表示节点的颜色,可以是Red或Black。
2.红黑树的性质
- 每个节点不是红色就是黑色
- 根节点是黑色的
- 红色结点的两个孩子结点,颜色必须是黑色的
- 对于每个结点,从该结点到其所有后代的叶结点的简单路径上,均包含相同数目的黑色结点。
- 每个空的叶子节点都是黑色的(非空的叶子节点可以不是黑色)
思考1:满足上面的条件,为什么就可以保证最长路径中节点个数不会超过最短路径节点个数的两倍?
解释:首先我们根据红黑树的特性知道,红黑树中的最短路径即为全黑结点的路径(即黑结点个数),而最长路径只能是黑红相间的路径(即最多黑结点+红结点个数,且红结点<=黑结点);故由数学只是可以推出:最长路径<=最短路径*2
其次,根据上述性质,画图就可简单的看到这个原理
思考2:我们为什么要把新增结点的默认颜色给成红色?
解释:若我们新增的结点是黑色,必定会违反第4条性质,因为根节点一边的黑色节点肯定多于另外一边,从而就会引起每条路径都不平衡的结果,这很危险,也很难判断该如何操作才能再次达到平衡。
但我们若把默认结点给为红色,有可能违反第3条性质,因为可能会连续出现两个红色结点,不过此时就只是对当前路径上的平衡有影响,不会影响其他路径的平衡。我们可以根据红黑树的变换规则,对该路径进行变色或者旋转的调整,再次达到标准的红黑树!
3.红黑树结点的定义
// 定义结点的颜色
enum Color {RED,BLACK};
template<class K,class V>
struct RBSTreeNode
{
RBSTreeNode(const pair<K, V>& kv)
:_left(nullptr)
, _right(nullptr)
, _parent(nullptr)
, _kv(kv)
, _col(RED)
{}
RBSTreeNode<K, V>* _left;
RBSTreeNode<K, V>* _right;
RBSTreeNode<K, V>* _parent;