红黑树插入-自己总结篇

来源:互联网 发布:孤独啊网络歌手 编辑:程序博客网 时间:2024/06/03 23:11


红黑树插入


红黑树的节点插入默认是节点为红色的。我自己理解是,其实插入红还是黑都可以,但就要看后面的调整是否麻烦。

插入黑点,会增加路径上黑点的数目,一定会破坏性质5;
插入红点:

当其父节点为黑色时,不影响平衡,继续保持红黑性质;
当其父节点为红色时,可能破坏性质2(根节点是黑色的)、性质4(红色节点的子节点一定是黑色节点),需要进行修正。

首先,理论已经证明:黑节点至少是红节点的两倍,这说明插入红节点OK的概率高很多(因为父节点为黑,插入子节点为红色就不会和性质冲突),这样插入就省事多了,嘿嘿,这也是红黑树为什么战胜AVL树的原因之一,插入效率高啊,节点贴上去就ok了,都不用什么左转右转调整了,多省事啊;再说,如果插入子节点为黑色,黑高度变化了,得调整,如果每次都插入黑节点,都得调整,没事闲的蛋疼啊。。。


红黑树插入分一下几种情况:


1、黑父

如下图所示,如果新节点的父结点为黑色结点,那么插入一个红点将不会影响红黑树的平衡,此时插入操作完成。红黑树比AVL树优秀的地方之一在于黑父的情况比较常见,从而使红黑树需要旋转的几率相对AVL树来说会少一些。


2、红父


     如果新节点的父结点为红色,这时就需要进行一系列操作以保证整棵树红黑性质。如下图所示,由于父结点为红色,此时可以判定,祖父结点必定为黑色。这时需要根据叔父结点的颜色来决定做什么样的操作。青色结点表示颜色未知。由于有可能需要根结点到新点的路径上进行多次旋转操作,而每次进行不平衡判断的起始点(我们可将其视为新点)都不一样。所以我们在此使用一个蓝色箭头指向这个起始点,并称之为判定点。
图一
    2.1
当叔父结点为红色时,如下图所示,无需进行旋转操作,只要将父和叔结点变为黑色,将祖父结点变为红色即可。但由于祖父结点的父结点有可能为红色,从而违反红黑树性质。此时必须将祖父结点作为新的判定点继续向上迭代进行平衡操作。(注意这里是需要迭代的,并且当调整到根节点时,即:需要把根调整成红色时,此时的做法是:不要将根着成红色,而是采取把它(即:根节点)的两个孩子都给着成黑色即可,此时迭代到此全部结束。)

图二
需要注意的是,无论“父节点”在“叔节点”的左边还是右边,无论“新节点”是“父节点”的左孩子还是右孩子,它们的操作都是完全一样的(其实这种情况包括4种,这里我就省略不一一介绍了,这些场景都是只需调整颜色,不需要旋转树形)。


  2.2
当叔父结点为黑色时,需要进行旋转,以下图示了所有的旋转可能:(case1 和caes 2 都是把左边较大的节点调整到上面去

         Case 1:先旋转、再变色(顶节点必须是黑色,它的两个子节点必须是红色,叔叔保持黑色不变)


图三

         Case 2: 【case 2 需要L变换成case 1 的情形


图四

         其实这里case 2的图示进行了简化,就是case 2 需要L变换成case 1 的情形(如五)然后再进行R旋转,得到最后的结果。当然,下面case 3 和case 4 的处理 也和这个类似。

图五(图中省略了哨兵结点

         Case 3:case 3 需要L变换成case 4 的情形


         Case 4:case 4 的旋转处理和case 1 的情形类似


                 可以观察到,当旋转完成后,新的旋转根全部为黑色,此时不需要再向上回溯进行平衡操作,插入操作完成。

          需要注意,上面四张图的“叔”、“1”、“2”、“3”结点有可能为黑哨兵结点。


上面就是红黑树插入的所有情况了,采用流程分支的图示表示,具体如下:



0 0
原创粉丝点击