红黑树原理分析
Posted 区块链and语义研究实验室
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了红黑树原理分析相关的知识,希望对你有一定的参考价值。
在理解红黑树之前,先对二叉查找树进行一个简单的介绍。
1、二叉查找树
二叉查找树的特性如下:
1.左子树上所有结点的值均小于或等于它的根结点的值。
2.右子树上所有结点的值均大于或等于它的根结点的值。
3.左、右子树也分别为二叉排序树。
例如,在下图的二叉查找树中查找元素10,查找的结点依次为:9、13、11、10,利用了二分法的思想,提高了查找的效率。
但是二叉查找树也存在缺点。例如,在下图中插入结点7、6、5、4、3,得到结果:
从这种情况可以看出,明显存在左子树和右子树深度相差过多,想要查找3的位置就需要每一次都遍历下一个左子树,很有可能时间复杂度变为n(与数组普通查询的时间复杂度相同)。基于上述情况,引入了平衡二叉树,红黑树即为平衡二叉树的一种。
2、红黑树的特性
红黑树是一种自平衡二叉查找树,在进行插入和删除操作时通过特定操作保持二叉查找树的平衡,从而获得较高的查找性能。
它的左右子树高差有可能大于1,所以红黑树不是严格意义上的平衡二叉树(AVL),但对其进行平衡的代价较低,因此性能要强于AVL。
由于每一颗红黑树都是一颗二叉排序树,因此,在对红黑树进行查找时,可以采用普通二叉排序树的查找算法,在查找过程中不需要颜色信息。红黑树有5个特性:
1.所有结点是红色或黑色。
2.根结点为黑色。
3.每个叶结点都是黑色的空结点。
4.每个红色结点的两个子结点都是黑色。
5.从任一结点到其每个叶子结点的所有路径都包含相同数目的黑结点。
下图为一个典型的红黑树。
3、红黑树的插入操作
1、插入元素的时候,可能会导致红黑树的结构破坏,有2种基本操作:变色和旋转。
(1)变色:将红色结点变为黑色,或将黑色结点变为红色。
(2)旋转:左旋转和右旋转。(以实例进行说明)
左旋转:以X为轴进行左旋,使X的右孩子Y旋转到X的位置,而X作为新局面中Y的左子树,且原来Y的左孩子b作为了新局面中X的右孩子。
右旋转:以X为轴进行右旋,使X的左孩子Y旋转到X的位置,而X作为新局面中Y的右子树,且原来Y的右孩子c作为了新局面中X的左孩子。
2、红黑树插入新结点的5种情况
注意:插入节点的时候,新插入的结点为红色。因为插入红色结点后树的性质可能不会改变,而插入黑色节点每次都会违反特性5。因此将红黑树的新插入的结点默认颜色设置为红色,是为尽可能减少插入新节点对红黑树造成的影响。
情况1:(变色)新插入的结点A刚好位于红黑树的根部。
此时,破坏了特性2,因此直接将A变色。变色后由于A位于树的根结点上,因此每条路径上都增加了一个黑结点,因此特性5没有被破坏。
情况2:(不变)新插入的结点B的父结点是黑色的。
此时,新结点B为红色,满足红黑树的5个特性,因此不做任何操作。
情况3:(变色)新插入的结点D的父结点B与叔叔结点C都为红色。
此时,B结点(红色)的孩子结点D也为红色,打破了特性4。因此需要变色:使B结点变色成黑色。
但是,此时路径A--B--…...上多出一个黑色结点(相较于路径A--C--…...),违背了特性5。因此需要使A结点变色为红色。
但是,此时还是存在问题。红色的A结点的孩子结点C也是红色,又违背了特性4,因此使C结点变色为黑色。
此时的结果满足红黑树的5个特性,调整完毕。
情况4:(旋转-左旋)新插入的结点D的父结点B为红色,其叔叔结点C为黑色或无叔叔结点,且新结点D位于其父结点B的右孩子,而B结点位于其自身父结点的左孩子上。
此时,以新结点D的父结点B为轴进行左旋,使D替代B的位置,原来的父结点B作为新的父结点D的左孩子,且原来D的左子树2作为新局面中B的右子树。
旋转之后变为了情况5。
情况5:(旋转-右旋+变色)新插入的结点D的父结点B为红色,其叔叔结点C为黑色或无叔叔结点,且新结点D位于其父结点B的左孩子,而B结点位于其自身父结点的左孩子上。
此时,以新结点D的祖父结点A为轴进行右旋,使父结点B替代A的位置,原来的祖父结点A作为新的祖父结点B的右孩子,且原来B的右子树3作为新局面中A的左子树。
由于右旋之后根的右子树上多了一个黑结点,违背了特性5;且树的根结点的颜色为红色,也违背了特性2。因此需要使B结点变为黑色,A结点变色为红色。
到底为止,调整后的树满足了红黑树的5个特性。
注意:当情况4、5中的父结点B是祖父节点A的右孩子时,情况4:新结点D是B的左孩子,此时以B为轴右旋进入情况5;情况5:新结点D是B的右孩子,此时以祖父节点A为轴左旋,再变色。
3、实例
在下图基础上插入21结点。
(1)按照二叉查找树的规则插入21结点。
(2)调整结点21:判断插入21属于插入操作的哪种情况,并调整。
经判断,发现新插入的21结点的父结点及叔叔结点都是红色,符合情况3。因此需要进行变色操作:22变为黑色,25变为红色,27变为黑色。
调整之后,以25为根的子树满足了红黑树的5个特性。但是25与其父结点17都为红色,不符合特性4。
(3)调整25结点:将结点25看作新结点,往上进行调整。
此时符合情况5的变形:即新结点25的父结点17为红色,叔叔结点15为黑色,且25是17的右孩子,父结点17为祖父节点13的右孩子,需要先左旋再变色。
左旋:以13为轴左旋后,17结点替代13结点的位置,变为根结点。而13变为17的左孩子,以15为根的子树变为13的右子树。
变色:使17变色为黑色,13变色为红色。此时,这棵树的调整完毕。
4、红黑树的删除操作
1、二叉查找树删除操作的3种情况
(1)待删除的结点是叶子结点,则直接删除。
(2)待删除的结点有1个孩子:让其孩子结点直接替代它。
(3)待删除结点有2个孩子。
5有两个孩子,需要在其子树中选择与5最接近的结点替代它。一般习惯选择5的后继结点(按照中序排序)替代它,此处为结点6。
将6复制到5的位置上,然后原来的6结点按照情况1或2进行删除。
2、红黑树删除操作的3个步骤
此处红黑树的删除操作是在二叉查找树删除操作基础上展开的。
(1)步骤1:若待删除结点有2个非空孩子,则需将其变为只有一个孩子或没有孩子。
例如删除结点8。首先根据二叉查找树进行删除操作:结点8有两个孩子,因此使用中序排序中8的后继结点10复制到8的位置,结点颜色是待删除结点的颜色,然后删除原来位置的10。
此时,由中序遍历的性质得知10结点没有左孩子,因此转化为了删除结点10,且10结点只有一个右孩子,进入步骤2。
(2)步骤2:根据待删除结点及其唯一的孩子结点颜色,分为以下3种情况。
A、待删除结点为红色,孩子为黑色。
直接按照二叉查找树的方法,进行删除操作,即用结点2替代结点1。
B、待删除结点为黑色,孩子为红色。
首先按照二叉查找树的方法,删除结点1。
但是2结点所在的这条路径上黑结点的数目少了一个,因此需要变色:将2变为黑色。
C、待删除结点为黑色,孩子也为黑色或空的叶节点。
首先按照二叉查找树的方法删除结点1。
但此时2所在的路径上的黑结点数目减少了一个,且无法通过变色解决,因此跳转到步骤3。
(3)步骤3:主要解决双黑结点,即父结点与唯一子结点都是黑色。子结点替代父结点后,有6种情况。
A、不变:结点2为树的根。此时所有路径的黑结点都少了1个,因此满足特性5,不需调整。
B、变色:结点2的父亲、兄弟、侄子都为黑色。
将其兄弟B变为红色。
此时,A的两棵子树的路径上都少了一个黑结点,因此满足了特性5。但可能又会使A以外的路径不满足特性5,因此将A看作此处的2结点,进行递归调整。
C、左旋 + 变色:结点2的兄弟为红色,父亲、侄子为黑色。
左旋:以2的父结点A为轴左旋。
变色:使A变为红色,B变为黑色。这样操作之后会变为情况D或情况E或情况F。
D、变色:结点2的父亲为红色,兄弟、侄子为黑色。
变色:将结点2的父亲A变成黑色,兄弟B变成红色。这样的结果会增加2所在路径的黑结点,同时也不会缩减B所在路径的黑结点,满足了特性5。
E、右旋 + 变色:结点2的父结点无限制,兄弟B为黑色右孩子,右侄子为黑色,左侄子为红色。
右旋:此时,以结点2的兄弟B为轴右旋,使B的左孩子C旋转到B的位置上。
变色:使B变成红色,C变成黑色,然后跳转到情况F。
F、左旋+变色:结点2的父亲颜色无限制,兄弟B为黑色右孩子,右侄子为红色。
左旋:以2结点的父亲A为轴左旋,使A的右孩子B旋转到A的位置上。
变色:将A与B的颜色交换,D的颜色置为黑色。
这时,2所在路径由原来的“任意-黑”转化为了“任意-黑-黑”,而在步骤2中2替代了其父结点,因此2所在路径缺少1个黑结点,本次调整完后刚好补上了之前缺的黑结点,满足了特性5;D所在路径由原来的“任意-黑-红”转化为了“任意-黑”,黑结点数目始终不变。
3、实例
在下面红黑树的基础上删除结点17。
步骤1:分析得17有两个孩子,因此使用中序遍历中17的后继结点25复制到17的位置上,颜色为黑色。
步骤2:此时转变为了删除原来的结点25,符合删除操作步骤2的情况C。
删除原来的结点25
步骤3:此时对应于删除操作步骤3的情况5的镜像。
这时进行左旋、变色:以结点null的兄弟15为轴进行左旋,使16旋转至15的位置;再将16变为黑,15变为红,进入情况6的镜像。
再进行右旋和变色:以结点null的父亲25为轴进行右旋,使25的左孩子16旋转至25的位置;再将16与25颜色互换,15结点的颜色置为黑色。至此,这颗红黑树删除结点17的操作完成。
5、总结
本文主要介绍了红黑树的相关原理。首先通过二叉查找树的不足引出红黑树,然后针对红黑树的5大特性,红黑树的插入操作,删除操作,都使用了大量的图形来加以说明。红黑树的应用也非常广泛,如JAVA中的TreeMap和TreeSet都是基于红黑树实现的,且JDK8中HashMap当链表长度大于8时也会转化为红黑树。
区块链and语义研究实验室
与你分享学术科研。
以上是关于红黑树原理分析的主要内容,如果未能解决你的问题,请参考以下文章