红黑树 学习概要(1)

来源:互联网 发布:录音数据恢复 编辑:程序博客网 时间:2024/04/29 19:28

一、什么是红黑树

R-B Tree,全称是Red-Black Tree,又称为“红黑树”,它一种特殊的二叉查找树。红黑树的每个节点上都有存储位表示节点的颜色,可以是红(Red)或黑(Black)。

红黑树的特性:
(1)每个节点或者是黑色,或者是红色。
(2)根节点是黑色。
(3)每个叶子节点(NIL)是黑色。 [注意:这里叶子节点,是指为空(NIL或NULL)的叶子节点!]
(4)如果一个节点是红色的,则它的子节点必须是黑色的。
(5)从一个节点到该节点的叶子节点的所有路径上包含相同数目的黑节点。

注意
(01) 特性(3)中的叶子节点,是只为空(NIL或null)的节点。
(02) 特性(5),确保没有一条路径会比其他路径长出俩倍。因而,红黑树是相对是接近平衡的二叉树。


插入节点(I)着色为红色,然后需要进行一系列操作(BUILD)使其重新成为红黑树:

一、I点 是根节点:直接将 I 着色为红色

二、I点 的父节点是黑色:什么都不用作

三、I点 的父节点是红色:

此情况又分为三种状况{

1、I的 叔叔节点也是红色:[则 I.parent=黑色; I.叔叔 = 黑色; I.parent.parent = 红色;(这样能保证 特性5)] 将 祖父节点设为 当前节点 递归进行操作。

2、I的 叔叔节点是黑色,I是父节点的右孩子:将 父节点 作为当前节点, 然后以当前节点 进行左旋 继续对当前节点操作。

3、I的 叔叔节点是黑色,I是父节点的左孩子:将 父节点 设为黑色,祖父节点设为 红色,围绕祖父节点 右旋

}



删除节点:(后继节点:某个节点的后继节点,是指比该节点大的所有节点中的最小的一个节点。例:若一个节点有右子树,那么该节点的后继节点是其右子树中val值最小的节点(也就是右子树中所谓的leftMostNode)

   这和"删除常规二叉查找树中删除节点的方法是一样的"。分3种情况:
       ① 被删除节点没有儿子,即为叶节点。那么,直接将该节点删除就OK了。
       ② 被删除节点只有一个儿子。那么,直接删除该节点,并用该节点的唯一子节点顶替它的位置。
       ③ 被删除节点有两个儿子。那么,先找出它的后继节点;然后把“它的后继节点的内容”复制给“该节点的内容”;之后,删除“它的后继节点”。在这里,后继节点相当于替身,在将后继节点的内容复制给"被删除节点"之后,再将后继节点删除。这样就巧妙的将问题转换为"删除后继节点"的情况了,下面就考虑后继节点。 在"被删除节点"有两个非空子节点的情况下,它的后继节点不可能是双子非空。既然"的后继节点"不可能双子都非空,就意味着"该节点的后继节点"要么没有儿子,要么只有一个儿子。若没有儿子,则按"情况① "进行处理;若只有一个儿子,则按"情况② "进行处理。


删除节点y之后,x占据了原来节点y的位置。 既然删除y(y是黑色)(y红色就不用继续啦因为没少黑色节点),意味着减少一个黑色节点;那么,再在该位置上增加一个黑色即可。这样,当我们假设"x包含一个额外的黑色",就正好弥补了"删除y所丢失的黑色节点",也就不会违反"特性(5)"。 因此,假设"x包含一个额外的黑色"(x原本的颜色还存在),这样就不会违反"特性(5)"。
      现在,x不仅包含它原本的颜色属性,x还包含一个额外的黑色。即x的颜色属性是"红+黑"或"黑+黑",它违反了"特性(1)"。

      现在,我们面临的问题,由解决"违反了特性(2)、(4)、(5)三个特性"转换成了"解决违反特性(1)、(2)、(4)三个特性"。RB-DELETE-FIXUP需要做的就是通过算法恢复红黑树的特性(1)、(2)、(4)。RB-DELETE-FIXUP的思想是:将x所包含的额外的黑色不断沿树上移(向根方向移动)[重点]

将上面的姿态,可以概括为3种情况。
一、情况说明:x是“红+黑”节点。
    处理方法:直接把x设为黑色,结束。此时红黑树性质全部恢复。
二、情况说明:x是“黑+黑”节点,且x是根。
    处理方法:什么都不做,结束。此时红黑树性质全部恢复。
三、情况说明:x是“黑+黑”节点,且x不是根。[重复执行三将额外的黑色向根方向移动,直到出现一或二的情况]
    处理方法:这种情况又可以划分为4种子情况。这4种子情况如下表所示:

1、x是"黑+黑"节点,x的兄弟节点是红色:

(01) 将x的兄弟节点设为“黑色”。
(02) 将x的父节点设为“红色”。
(03) 对x的父节点进行左旋。
(04) 左旋后,重新设置x的兄弟节点。

2、x是“黑+黑”节点,x的兄弟节点是黑色,x的兄弟节点的两个孩子都是黑色:

(01) 将x的兄弟节点设为“红色”。
(02) 设置“x的父节点”为“新的x节点”。

3、x是“黑+黑”节点,x的兄弟节点是黑色;x的兄弟节点的左孩子是红色,右孩子是黑色的。

(01) 将x兄弟节点的左孩子设为“黑色”。
(02) 将x兄弟节点设为“红色”。
(03) 对x的兄弟节点进行右旋。
(04) 右旋后,重新设置x的兄弟节点。

4、x是“黑+黑”节点,x的兄弟节点是黑色;x的兄弟节点的右孩子是红色的,x的兄弟节点的左孩子任意颜色。

(01) 将x父节点颜色 赋值给 x的兄弟节点。
(02) 将x父节点设为“黑色”。
(03) 将x兄弟节点的右子节设为“黑色”。
(04) 对x的父节点进行左旋。
(05) 设置“x”为“根节点”。


参考:

http://www.cnblogs.com/skywang12345/p/3245399.html (由于本人比较懒所以本文大量内容出自该博文,外加部分本人的理解。感谢该博主)

http://blog.csdn.net/v_JULY_v/article/details/6105630
0 0
原创粉丝点击