红黑树
一、定义:
红黑树是一个自平衡二叉查找树,平衡二叉树是一棵空树或它的左右两个子树的高度差的绝对值不超过1,并且左右两个子树都是一棵平衡二叉树。作为二叉查找树,红黑树广泛的被应用于各种数据结构中,例如HashMap(jdk8之后),TreeMap。
二、性质:
为了实现红黑树的自平衡及二叉查找树的特点,红黑树具有如下性质:
三、红黑树的旋转:
四、红黑树构建:
以下面这颗红黑树举例,演示节点增加和删除的过程:
图1
新增节点步骤
1、将新增节点按照普通的二叉查找树插入到原来的红黑树中,并涂成红色。
将图1的红黑树新增“节点12”,按照二叉查找树的特征,将此节点插入到“节点11”的右侧,形成如下图2新的树状结构,恰好此结构也保持了红黑树的特征,插入完成。
图2
2、通过重新涂色以及旋转将新的二叉查找树的树重新构建成红黑树。
将红色新节点插入到红黑树中,可能会违背红黑树的那些性质?
处理新节点(以下称新节点为z)父节点为红色节点可能会遭遇三种情况,处理方案建立在z的父结点是左孩子基础上,相反情况判断方法及旋转方向均相反:
- 考虑我们将21节点插入图2的红黑树中:形成图3,z节点为21
-
-
- 将父节点和叔父节点涂成黑色,祖父节点涂成红色,z指向祖父节点25:形成图4,z节点为25
-
图4
-
-
- 依然符合情况1,节点z的父节点与叔父节点均为红色,祖父节点黑色,将父节点及叔父节点均涂为黑色,祖父节点涂为红色,由于祖父节点为根节点,再涂为黑色形成新的红黑树,见图5
-
图5
情况2:z节点的叔父节点为黑色,且z节点为右孩子,需要将z节点指向其父节点,再以新的z节点进行左旋。影响:将情况2转化为情况3
-
-
- 考虑图5基础上(此处案例设计问题,将图5中的22改成23,结构保持不变)插入节点22,形成图6,z节点为22
-
图6
-
-
- 本身为红色,父节点为红色,叔父节点为黑色,且自身为右孩子节点,那么将z指向其父节点21节点,并以21节点进行左旋:形成图7,z节点为21。
-
图7
情况3:z的叔父节点是黑色的且z是一个左孩子,将z的父节点染黑,z的祖父节点染红,然后以z的祖父节点进行右旋。影响:在两次修改颜色后,会导致从根结点向左出发的所有路径的黑高不变,而向右出发的所有路径的黑高减1;而右旋操作会使黑高回归平衡。
-
-
- 考虑图7,z节点为21,z的叔父节点22为黑色且z是一个左孩子,将z的父节点22染黑,z的祖父节点23染红:形成图8,z节点为21
-
图8
-
-
- 考虑图8,z节点为21,以z节点的祖父节点进行右旋,形成图9,此时红黑树重新形成。
-
图9
插入节点总结:
情况1逐步提高z节点的层高,其导致的结果有两个。
1、z节点升高到根节点,将根节点染黑后,整颗树回归红黑树特性;
2、z节点的情况转化为3(直接转化为3或转化成2再转化成3)
情况3执行过后会回归红黑树的特性。
删除节点步骤(删除节点待补充示例图)
1、将红黑树当成普通的二叉查找树,进行节点删除
-
-
-
- 如果被删除的节点没有子节点,则直接删除
- 如果被删除的节点只有一个子节点,则将此子节点顶替被删除节点的位置
- 如果被删除的节点有两个子节点,则找到左子树的最大节点r(或者后继节点也可),将此节点的数据放入被删除的节点,同时删除节点r(因为r是左子树的最右节点,所以没有右节点,删除节点r可以转化成情况1或情况2)
-
-
2、通过旋转和重新着色使二叉查找树恢复红黑树的特性
分析:因为步骤1,可能会对红黑树的哪些特性产生影响?
- N节点为红色节点:那么N节点一定是有两个叶子节点(因为N节点为红色,那么其子节点一定为黑色,如果子节点一个是叶子节点一个是非空子节点,那么N节点左右子树包含的黑色节点个数不相等,违背了红黑树的特性),那么直接删除节点N即可。
- N节点为黑色节点:可以分为两种情况,含有一个红色子节点或含有两个叶子节点(如果含有一个黑色的非空子节点,则左右分支黑色节点个数不等)
1、N节点包含了一个红色非空子节点,则只需要把红色子节点顶替N节点,并涂成黑色(这样不会影响N节点以下各个分支黑色节点的个数),重新满足红黑树的特征;
2、N节点包含了两个叶子节点,删除N节点后,代替N节点的为其NIL子节点,依然命名为N,该路径上的黑色节点比其他路径上的黑色节点个数少了一个,N节点的父节点命名为P,N的兄弟节点命名为B,则还需分为几种case(注意:以下case均以N是父结点P的左孩子结点,如果是右孩子结点,那么“左”和“右”应该对调):
case1:N为根节点为根节点,因为N为NIL,则整颗树为空树,满足了红黑树的特征,结束。
case2:N的兄弟节点为红色,则将P和B节点的颜色对调后,以P节点为支点进行左旋,然后进入case4、case5或case6
case3:N、P、B三个节点都为黑色,则将B节点颜色涂为红色,此时P节点左右分支的黑节点数相等,但比不通过P节点的分支黑节点少一个,仍然需要按照这几个case继续处理P节点。
case4:P位红色,N、B以及B的两个子节点都为黑色,则对调P和B的颜色,此时不影响通过B的黑色结点数量,但是在通过N的路径上增加了一个黑色结点,但是N节点会被删除后,满足了性质5.
case5:B的左节点为红色,右节点为黑色,并且N为P的左孩子,则B与其左孩子颜色对调后右旋,此时进入case6
case6:结点N的兄弟结点B是黑色的,B的右孩子是红色的(右红),并且结点N是父结点P的左孩子。此时将父结点P和兄弟结点S的颜色对调,再将S的右孩子变为黑色,然后左旋父结点P。