红黑树的插入和删除分析

来源:互联网 发布:saas软件销售术语 编辑:程序博客网 时间:2024/04/24 14:43

   红黑树,一种二叉查找树,但在每个结点上增加一个存储位表示结点的颜色,可以是Red或Black。通过对任何一条从根到叶子的路径上各个结点着色方式的限制,红黑树确保没有一条路径会比其他路径长出俩倍,因而是接近平衡的。

  五个性质:

   1、每个节点要么是黑的,要么是红的。

   2、根节点是黑的。

   3、叶子节点,即空节点(NIL)是黑的。

   4、如果一个节点是红的,那么它的两个孩子节点是黑的。

   5、每个节点到其子孙节点的所有路径上有相同数量的黑色节点。

性质5保证了没有一条路径会比其他路径长出俩倍。

   红黑树的查找操作和二叉查找树是一样的。

   为了实现红黑树的插入和删除操作,这里引用两个基本操作:左旋和右旋。

  

                        

                               对S节点左旋                                                            对S节点右旋

(图片来源:http://www.cnblogs.com/yangecnu/p/Introduce-Red-Black-Tree.html)

左旋代码:

LEFT-ROTATE(T, x)
1  y ← right[x] ▹ Set y.
2  right[x] ← left[y]      ▹ Turn y's left subtree into x's right subtree.
3  p[left[y]] ← x
4  p[y] ← p[x]             ▹ Link x's parent to y.
5  if p[x] = nil[T]
6     then root[T] ← y
7     else if x = left[p[x]]
8             then left[p[x]] ← y
9             else right[p[x]] ← y
10  left[y] ← x             ▹ Put x on y's left.
11  p[x] ← y

右旋与左旋类似。

插入操作,有以下几种情况:

插入新节点初始化为红色节点。

1 、为根节点
       方案:若新插入的节点N没有父节点,则直接当做根据节点插入即可,同时将颜色设置为黑色。

2、父节点为黑色

       方案:满足性质,什么也不做。

3、若父节点P和叔叔节点U都为红色

       方案:将当前节点的父节点和叔叔节点涂黑,祖父结点涂红,把当前结点指向祖父节点,从新的当前节点重新开始算法。

4、当前节点的父节点是红色,叔叔节点是黑色,当前节点是其父节点的右子。

      方案:对当前节点左旋,转换为情况5,如图。

转换前:7为当前节点。


转换后:


(图中15节点应是14节点的右孩子,但不影响,特此指出)。

5、当前节点的父节点是红色,叔叔节点是黑色,当前节点是其父节点的左子。

      方案:父节点变为黑色,祖父节点变为红色,对父节点右旋,如图,N为当前节点。




删除操作,有以下几种情况:

红黑树的删除与二叉树类似,都是用前驱(左子树的最右边)或后继(右子树的最左边)来代替被删除的结点。这样一来,删除操作可以看作。把待删除结点与它的前驱或后继结点数据交换,真实删除其前驱或后继结点(若待删除结点有两个NIL孩子结点,则把空节点看作待替换结点)。设真实删除的结点为N(可能为空),则N最多有一个非空孩子结点,非空孩子结点不可能为黑色,因为这会违背性质5。对N分析:
1、N为空,原待删除结点为红色。
这种情况对原待删除结点直接删除即可,不会影响树的结构。
2、N为空,原待删除结点为黑色。
把N设为黑色,替代原待删除结点的位置,然后按情况3,4,5,6,7处理。
3、N有一个非空孩子结点(红色),N的兄弟节点W为红色。
W为红色,那么其子节点X1、X2必定全部为黑色,父节点P也为黑色。处理策略是:改变W、P的颜色,然后对P进行一次左旋转。这样处理后将情况4转变为4、5、6中的一种。


4、N的兄弟w是黑色的,且w的俩个孩子都是黑色的,父节点P为黑。

把W变为红色,把P当成新的当前节点,重新进入算法。

5、N的兄弟w是黑色的,且w的俩个孩子都是黑色的,父节点P为红。

把W变为红色,P变为黑色。

6、N的兄弟w为黑色,S 的左儿子是红色,S 的右儿子是黑色,而N是它父亲的左儿子。

将节点W和其左子节点进行颜色交换,然后对W进行右旋转处理,接下来按情况7处理。


7、N的兄弟w是黑色的,且w的右孩子是红色的。

交换W和父节点P的颜色,同时对P进行左旋转操作。这样就把左边缺失的黑色节点给补回来了。同时将W的右子节点X2置黑。


最后,删去N,将N的红色子节点连接N的父节点上。



0 0