图片来自:程序员小灰(微信公众号)
在了解红黑树之前,需要先理解二叉查找树。
又叫二叉排序树 排序二叉树 二叉搜索树
二叉查找树(Binary Search Tree),也称有序二叉树(ordered binary tree),排序二叉树(sorted binary tree),是指一棵空树或者具有下列性质的二叉树:
1.左子树上所有结点的值均小于或等于它的根结点的值。
2.右子树上所有结点的值均大于或等于它的根结点的值。
3.左、右子树也分别为二叉排序树。
如下:
这种排序的结构也是造成二叉查找树缺点的原因,如下:
好好地一棵查找树变成了瘸子。为了解决二叉查找树多次插入节点而导致的不平衡问题,便引入了红黑树。红黑树是一种自平衡的二叉查找树,除了二叉查找树的特性,还具有以下特性:
1.节点是红色或者黑色
2.根节点是黑色
3.每个叶子节点都是黑色的空节点(NIL节点)
4.每个红色节点的两个子节点都是黑色。(也就是说,从每个叶子到根的所有路径上不能有两个连续的红色节点)
5.从任一节点到其每个叶子的所有路径都包含相同数目的黑色节点。
正是因为这些规则,才保证了红黑树的自平衡。红黑树从根到叶子的最长路径不会超过最短路径的两倍。
如,当我们向上图红黑树插入14节点时
由于父节点15是黑色节点,这种情况不会破坏二叉树规则,所以不需要进行调整。
向原红黑树插入21节点时:
由于22是红色节点,所以打破了二叉树的规则(每个红色节点的两个子节点都是黑色),所以我们必须进行调整。而且 不能将21变为红色,这样以来影响了规则5
调整分为两种方法:变色和旋转。
首先 变色:
为了重新符合红黑树的规则,尝试把红色节点变成黑色,或者把黑色节点变成红色。
因为22和21同为红色,所以我们把22变为黑色:
起但这样以来打破了另一条规则,从任意节点到其叶子的所有路径都包含相同数目的黑色节点。 所以将25变为红色
这样一来 需要把27再变为黑色:
PS:
左旋 右旋同AVL:
左:
右:
继续刚刚的例子 :
此时的17和25是连续的两个红色节点。那么还需要继续变色,将17变为黑色节点么?那就打破了规则5,13节点的左右子树到叶子节点的黑色节点数量不等。况且根据规则2,也不能把13变为红色。
此时变色已经无法解决问题,我们把节点13看做X,把17看做Y,像上图一样进行左旋。
此时需要变色:
这样并没有结束。因为18-8-6-NIL的黑色节点个数是4,而其他是3,不符合规则5。
这时候我们需要把13看做Y 把8看做X进行右旋转
然后再根据规矩变色:
如此一来 便得到符合规矩的二叉树。