**
前言: 234树在大部分的程序语言中实现比较困难,所以等价的用红黑树来实现。
核心思想:红黑树的红色节点上移到父亲节点就变成了一颗234树。
一:红黑树与234树的等价关系如下:
一个234树可以变成多个红黑树,原因在于三节点(有两个元素的节点)变成红黑树后可以变成 下面这两种。
二:现在开始从234树的插入操作来说明红黑树的插入操作。
1.当插入位置为234的2节点位置(只有一个元素),0或2(图一),那么则变成(图二),很明显整个234树的机构不用调整。那么对应红黑树来说可以想象一下当前红黑树只有一个节点,也就是根节点,那么这时插入一个节点,就变成了上黑下红(图三),也就是说当向一个红黑树中插入节点时(新节点都是默认为红色),如果它的父亲P是黑色,则说明此时P节点对应到234树上后P就是一个2节点(只有一个元素)。
(图一)
(图2)
(图三)
2.当插入位置为234的3节点位置(只有两个元素),如图一,可能插入的位置是前中后(4,5,8)。这个时候因为234树的结构没有被破坏(即任何一个节点不能超过3个元素)。所以234树的结构不用改变。也就是说 234树的3节点变成了4节点(2个元素变成了3个元素),
然后我们看一下234树中4节点(只有三个元素)对应于红黑树的结构(图2),一定是一个黑带着两个红子节点,参照234树与红黑树的对应原理,两个红色节点上移到父节点。就变成了一个4节点(3个元素的)234树的一个节点了。
再来看一下下边的图一,插入的位置不同时,对应于红黑树有6种情况:这里我们假设6和7这两个点先以6为父节点,7为6的右子树,(实际上反过来也行,因为一个234树可以变成多个红黑树,但是对我们理解来说都一样)如下。
同理如果以7位父节点,6为7的左子树,则插入时就变成了如下
因此,对比这种情况,如果我们对红黑树做插入操作时,如果可以判断插入的地方是一个3节点,那么我们就可以确定我们插入之后,这个节点的最终形态肯定是一黑二红的颜色,且黑色为父亲。那么我们怎么能知道我们向红黑树中插入时这这种情况呢。下面来分析一下:
a.插入时 新节点X默认为红色,他的父节点为P,如果父节点为黑色,说明父亲是一个没有儿子的节点(234树中的2节点) 或者是只有一个儿子,那么儿子是红色的,那么我们就不需要做结构和颜色的调整了。
b.如果父亲是红色的,说明对于他的父亲P是别人的子节点,那么我看看叔叔是不是红色的,(注意:红黑树中叶子节点是黑子的,叶子节点仅指代nil节点)。如果叔叔也是红色的,说明人家三个人(爷爷父亲,叔叔)玩的好好的,已经满足了一黑二红了,那么我要加进去,势必需要破坏平衡也就是下边要讲的四节点插入,那么如果叔叔是黑色的,说明我根本没有叔叔,可能你会问,为什么叔叔是黑色就说明没有叔叔,因为想一想,你做插入之前,这颗树要不然是空树,要么已经平衡了,就是说所有的节点要么满足一黑一红,要么满足一黑二红,不可能出现这样一个节点 (他的红色的,他的一个儿子黑色,一个儿子红色),或者(他是黑色,其他一个儿子是红色,另一个儿子是黑色)。可以从两个方面去验证,第一个是从红黑树的五大特性中的任何一个节点到达自己最简叶节点的黑节点数量都是相同的。且不可能出现两个红节点相连。另一个是我推荐的从234树的角度上去考虑。234树上每个节点(2节点,3节点,4节点)一定是一黑一红,或者一黑2红。
接着说,如果叔叔是黑色的,那么就说明从234树来看,这个叔叔不是我们节点的,那么我们通过旋转和变色就完成了插入。
关键之图及解释
3.向234树的四节点(有三个元素)中插入新节点,之前人家都满足一黑二红的原则了,即:父亲和叔叔是红色,爷爷是黑色的。说明人家玩的挺好了,我加进来后势必要破坏这种结构,那么按照234树在四节点添加元素的规则,我们需要选出中间元素 4 为父节点然后分裂。最后改色。这时候4变成了红色,可能会对上层结构产生破坏,本质上就像插入了一个新的元素,然后while或者递归就行了
以上插入操作就完成了