1、在理解红黑树之前,先看一下二叉查找树
二叉查找树特性:左子树上所有节点的值都小于或等于其他根节点上的值,右子树上所有节点的值均大于或等于他的根节点的值。左右字数也分别为平衡二叉树。
举个例子:
如果要查询10的话,10>9
因此到他的右子树,右子树根节点为13,10<13
因此到其左子树,左子树根节点11>10
到其左子树,为10,找到相应的节点。
不过二叉查找树有一些问题,可能会出现不平衡的情况,即如下图所示的情况:
从这种情况可以看出,明显存在左子树和右子树深度相差过多,在使用平衡情况下的二叉查找树时时间复杂度是logn,而出现这种极端情况的话,想要查9的位置就需要遍历下一个右子树,很有可能时间复杂度变为n.
基于上述情况,引入了平衡二叉树,红黑树即为平衡二叉树的一种。
二、红黑树
特性:节点是红色或黑色。根节点一定是黑色,每个叶节点都是黑色的空节点(NIL节点)。每个红节点的两个子节点都是黑色的(从每个叶子到根的所有路径上不能有两个连续的红节点)(即对于层来说除了NIL节点,红黑节点是交替的,第一层是黑节点那么其下一层一定是红节点,反之一样)。
从任一节点到其每个叶子节点的所有路径都包含相同数目的黑色节点。正是由于这些原因使得红黑树是一个平衡二叉树。
红黑树的例子:
向红黑树插入节点14(一般默认插入节点是红色的)
在原树上插入20
可以看到,插入以后树已经不是一个平衡二叉树了,而且并不满足红黑树的要求,因为20和21均为红色,这种情况下就需要对红黑树进行变色,21需要变为黑色,22就会变成红色,如果22变成红色,则需要17和25都变成黑色。
而17变成黑色显然是不成立的,因为如果17变为黑色,那么13就会变成红色,不满足二叉树的规则,因此此处需要进行另一个操作——左旋操作。
左旋:下图就是一个左旋的例子,一般情况下,如果左子树深度过深,那么便需要进行左旋操作以保证左右子树深度差变小。
对于上图由于右子树中17变为黑色以后需要把13变为红色,因此进行一次左旋,将17放在根节点,这样即可保证13为红色,左旋后结果为:
而后根据红黑树的要求进行颜色的修改
进行左旋后,发现从根节点17,到1左子树的叶子节点经过了两个黑节点,而到6的左叶子节点或者右叶子节点要经历3个黑节点,很显然也不满足红黑树,因此还需要进行下一步操作,需要进行右旋操作。
右旋,与左旋正好相反:
由于是从13节点出现的不平衡,因此对13节点进行右旋,得到结果
而后再对其节点进行变色,得到结果:
这便是红黑树的一个变换,它主要用途有很多,例如Java中的TreeMap以及JDK1.8以后的HashMap在当个节点中链表长度大于8时都会用到。