红黑树的插入相比较其删除是比较简单的。总的分为两步:
第一步,找到节点位置,插入节点即可,默认插入的节点是红色的(这样不会影响平衡)。
第二步,将调整颜色,避免出现红—红的出现,这是红黑树不允许的。
再次强调红黑树的定义:
(1)每个节点或者是黑色,或者是红色。
(2)根节点是黑色。
(3)每个叶子节点(NIL)是黑色。 [注意:这里叶子节点,是指为空(NIL或NULL)的叶子节点!]
(4)如果一个节点是红色的,则它的子节点必须是黑色的。
(5)从一个节点到该节点的子孙节点的所有路径上包含相同数目的黑节点。
默认插入点的颜色为红色。记住这些,就可以开始红黑树的插入啦,这里我将用RBT简化红黑树的名称。
插入操作Case分析
我们假设插入点为I,其父为P,其兄为S,其祖父为G。
首先,如果P是黑色,那么就直接插入I即可,无需其他后序调整,所以,我们主要讨论的是P为红色的一些情况。
case1:P红,U黑,I是左子树
这种情况下,为了避免红—红我们需要将P改为黑色,G变成红色,此时左端平衡,但是右边少了黑点,为了平衡,再执行一次以P为根右旋。
此时左右平衡,满足RBT的定义。
case2:P红,U黑,I是右子树
此时需要将以I为根节点执行一次左旋,如图右;此时虽然还是存在红—红情况,但是此时这不就是case1所说的情况嘛?于是case2→case1,达到平衡。
case3:P红,U黑,I是P的左右子树无关
将P、U变成黑色,G变成红色,此时左边不存在红—红点,但是G变成了红色;这时我们就需要将G看成新的I节点,将问题往上抛,如果之后的情况还是case3,那么再次继续,,直到不能抛,也就是到达整个树的根节点,此时只需要将G变成黑色的即可。
从上面可知,对于P是红色的情况下,各种其他不同的case都是通过操作变成case1的情况后达到平衡。
实例
下面的实例出现了上面所有的case。
一开始是Case3,然后变成了Case2,此时新的I为60.
Case2→Case1,此时新的I还为60.
在Case1情况下,我们执行一次右旋和变色操作,使树成为标准的RBT。