本帖最后由 sanguodouble1 于 2014-6-4 00:39 编辑
下面详细解析(下面电脑图中的X、W和我手绘图中N、S含义是相同的,分部代表被删除的点和它的兄弟点): 情况A:x的兄弟w是红色的(此时父节点P和S的子节点都是黑的,这时因为特性4)
处理方法:B点变红,D点变黑,然后以B点为轴左旋。相当于把右枝的红色移到了左支,但A的兄弟却从红色变成了黑色,使它符合情况B 情况B:X的兄弟W是黑色的,并且W的两儿子也是黑色的
处理方法:因为X和W都是黑色的,所以我们可以将他们的黑色上推(上推的含义参加我上一篇文章)一层,这时D变成了红色,但X因为有双重黑色,所以被推去一层后,还有一层。 这时候会有两种可能,情况我手绘图的二、三。如果是情况二,也就意味着被删点的父亲原来是黑色的,那么它现在变成了双重黑色,然后我们可以以它父亲为新的判定点(new x)来从新处理。 如果是情况三,就是被删点的父亲原来是红色的,那么它现在变成了单重黑色,那么就直接平衡了,OK,完工。 情况C:X的兄弟W是黑色的,W的左儿子是红色的,W的右儿子是黑色的。
处理方法:将W的颜色变成红,它左儿子C变成黑(互换),然后以W为支点进行右旋。使它符合情况D 情况D:X的兄弟W是黑色的,W的右儿子是红色的,W的左儿子颜色随意。
处理方法:将父亲C的颜色给兄弟W,父亲自己变成黑色,W的右儿子也变成黑色。然后以父亲为支点,进行左旋,OK,大功告成。 这个参看我手绘图六七八九更醒目,因为当X被删掉后,左边就少了一个黑节点,这样性质5就被破坏了,为了弥补,把父亲变黑,然后移到左边来。但这样一来,定点的颜色也可能变化,所以就先把父亲的颜色给兄弟W。这样左边和中间都满足了,只剩下右边少了一个黑(兄弟被当成顶点了嘛),正好右边有一个红色(原兄弟W的右儿子),那直接把它变黑,皆大欢喜。 情况E:被删点是根元素,并且整个树就它一个 处理方法:这种情况相当简单,直接变空树。
好了,关于被删点的接替点颜色是黑+黑(2.2,2.3)的处理,通过我手绘图的10种详细情况,归纳出5种普遍情况(其实是4种,情况E实在太简单),到此为止全部剖析完毕。再回顾一下: 红黑树删除的几种情况:
一、被删点是红色,那么直接删除,用后续点接替就好了 二、被删点是黑色的,那么把它删除,并把它的黑色继承给它的儿子。 这时根据他儿子的双重颜色,有可以分为: 2.1:它儿子是红+黑,那么直接变黑,over。
2.2:它儿子是黑+黑,又可分为5种:
2.2.A:x的兄弟w是红色的。
2.2.B:x的兄弟w是黑色的,且w的俩个孩子都是黑色的。
2.2.C:x的兄弟w是黑色的,w的左孩子是红色,w的右孩子是黑色。
2.2.D:x的兄弟w是黑色的,且w的右孩子时红色的。
2.2.E:被删点是根元素,并且整个树就它一个。
结语:只要牢牢抓住红黑树的5个性质不放,无论是插入还是删除,左旋还是右旋,目的只有一个——都只为了保持和修复红黑树的5个性质而已。
还有点遗漏,就是关于红黑树遍历部分和java实现,明天再搞 |