必须要把红黑树讲清楚,看完还不明白请直接找我之3(共四篇)—红黑树的删除
来源:互联网 发布:linux怎么保存文件 编辑:程序博客网 时间:2024/05/16 19:53
红黑树的删除操作是红黑树最复杂的操作了,只要搞明白这个,基本上就明白红黑树的调整。删除的情况大致可以分为四种。
case 1. .删除节点z,,子节点少于两个时,左儿子为T.NIL,用右儿子代替z
case 2. 删除节点z,子节点少于两个时,右儿子为T.NIL,用左儿子代替z
case 3 删除节点z,有两个子节点时,找出后继节点y,如果后继节点y是右儿子,直接用y子树替换z节点
case 4删除节点z,有两个子节点时,找出后继节点y,如果后继节点不是右儿子,用后继节点的右儿子x子树替换y子树,再用后继节点y子树替换z节点。
下面看看图形展示这四种删除情况,其中z节点表示想要删除的节点,y节点表示真正删除的节点(从删除节点的颜色角度来看),x表示要替换y的节点。由于y的颜色可能改变,用y-original-color表示y颜色改变之前的颜色
伪代码如下:
RB-DELETE(T, z) y = z; y-original-color = y.color; if z.left == T.NIL x = z.right; RB-TRANSPLANT(T, z, z.right); else if z.right == T.NIL x = z.left; RB-TRANSPLANT(T, z, z.left); else y = TREE-MINMUM(z.right) y-original-color = y.color; x = y.right; if y.p = z; x.p = y; else RB-TRANSPLANT(T, y, y.right) y.right = z.right; y.right.p = y; RB-TRANSPLANT(T, z, y) y.left = z.left; y.left.p = y; y.color = z.color; if y-original-color == black RB-DELETE-FIXUP(T, x)
可以看到,如果y是黑色的,就肯定破坏了红黑树的性质了。如果y是红色的,红黑树性质依然保持,因为树的黑高没有改变,也不存在两个相邻的的红色节点,性质4和5没有任何改变。所以y是黑色的时候需要通过RB-DELETE-FIXUP来调整修正。下面来看看如何调整。
违反性质2的情况:如果y是原来的根节点,而y的一个红色孩子成为新的根几点,就违反了性质2,但是这很容易解决,直接染黑就是了,不再继续讨论这种情况。
违反性质4的情况:x节点为红色,x的父节点也为红色,这种情况也很容易解决,染黑x就是了。
剩下的情况就是只违反了性质5,只要调整好性质5就好了,这里有一个技巧,就是把x节点视为还有一层黑色,问题就变成了解决违反性质1了,也就是把x看成既红又黑,我们只要把这层额外的黑色不断往上推,直到推给了一个红色节点,那么子树的黑高就恢复了。和插入一样,有个关键思想是,转换过程中千万不能破坏其他任何的性质。经过分析,破坏性质1(本质上是破坏性质5)有以下五种情况:
case 1 x是红色的
case 2. x的兄弟节点w是红色的
case 3 x的兄弟节点w是黑色的,而且w的两个子节点都是黑色的
case 4 x的兄弟节点w是黑色的,w的左儿子是红色的,w的右孩子是黑色的
case 5 x的兄弟节点w是黑色的,且w的右孩子是红色的。
如下图所示:
case 1是最容易解决的,直接染黑就是了。
case 2的话,改变w和x.p的颜色,左旋转x.p,这样子不改变任何性质的同时,把case 2转变为case 3,4,5。不做详细讨论
伪代码为:
w.color = black;x.p.color = red;LEFT-ROTATE(T, x.p)w = x.p.right;
case 3的话,可以认为从x和w去掉一层黑色给x.p,如果x.p为原本为红色的话,那么x的子树黑高加一,w子树黑高不变,性质就恢复好了,如果x.p原来为黑色的,那么认为x.p的整个子树黑高都少了1,多了的一层黑色就给了x.p,case3就转为case 2,3,4,5了。
伪代码如下:
w.color = red; x = x.p
case 4的情况左侄儿为红,右侄儿为黑,这种情况统一转case 5来处理。
这里右旋w并且没有改变红黑树的五大性质,转为了case5。伪代码如下:
w.left.color = black;w.color = red;RIGHT-ROTATE(T, w)w = x.p.right;
case 5的情况是红黑树调整的出口,只要到达了case 5,调整完就能恢复所有性质了。调整如下图所示:
接下来分析case5的转换过程,这里的思路是这样的:首先我们要让x子树黑高加一,那么就左旋转a,左旋转后d的左子树没有任何问题,但是右子树黑高可能减少了1(如果a原来是黑色的情况),为了解决这个问题,可以把a和d颜色交换,然后染黑c,这样左旋转后的d的右子树的黑高也就不会有任何改变了。伪代码如下:
w.color = x.p.color;x.p.color = black;w.right.color = black;LEFT-ROTATE(T, x.p);x = T.root;
为了能在全局下看到调整情况,下面展示整个删除调整的过程伪代码:
RB-DELETE-FIXUP(T, x) while x != T.root && x.color = black if x == x.p.left w = x.p.right // case 2 if w.color = red w.color = black; x.p.color = red; LEFT-ROTATE(T, x.p) w = x.p.right; // case 3 if w.left.color == black && w.right.color == black w.color = red; x = x.p; // case 4 else if w.right.color == black w.left.color = black; w.color = red; RIGHT-ROTATE(T, w) w = x.p.right; // case 5 w.color = x.p.color; x.p.color = black; w.right.color = black; LEFT-ROTATE(T, x.p); x = T.root;
- 必须要把红黑树讲清楚,看完还不明白请直接找我之3(共四篇)—红黑树的删除
- 必须要把红黑树讲清楚,看完还不明白请直接找我之2(共四篇)—红黑树的插入
- 必须要把红黑树讲清楚,看完还不明白请直接找我之1(共四篇)——红黑树的基本性质
- 必须要把红黑树讲清楚,看完还不明白请直接找我之4(共四篇)—JDK8 HashMap的实现
- 职场新人面试误区:我的技术好,所以你必须要请我?
- 职场新人面试误区:我的技术好,所以你必须要请我?
- 职场新人面试误区:我的技术好,所以你必须要请我?
- 今后工作必须要调查清楚的事情
- 我的管理之旅——做管理必须要明确的四个概念
- webpack-dev-server使用方法,看完还不会的来找我~
- javascript之必须要知道的概念
- 在SAP中进行黏贴时必须要把之前的数据删掉后才能黏贴,不能直接使用黏贴来覆盖之前的数据,这个怎麼解?
- 必须要记住的
- 工厂模式的简单用例(看完不敢保证懂,但我觉得已经写的很清楚)
- 安装fedora13后我必须要干的几件事
- 我不明白的几个问题
- CPU调度的故事(请看完)
- ThreadLocal——神一样的东东,我今天把它彻底解释清楚了
- maven+Spring+Struts2+Hibernate 整合
- 国外知名音频库一站式资料和简介
- A Text Clustering Algorithm Using an Online Clustering Scheme for Initialization(基于在线聚类策略的文本聚类算法)
- 38.top10热门品类之join品类与点击下单支付次数
- 循环结构
- 必须要把红黑树讲清楚,看完还不明白请直接找我之3(共四篇)—红黑树的删除
- 带有期限的作业排序java实现
- node.js基础知识 (一)
- 博客
- [JZOJ5055]树上路径
- hdoj-2016-数据的交换输出(解题报告)
- leetcodeOJ 80. Remove Duplicates from Sorted Array II
- 命令行wifi配置 wpa_supplicant 配置与应用
- Window sum