红黑树介绍与算法分析
来源:互联网 发布:js选下一个兄弟节点 编辑:程序博客网 时间:2024/06/06 05:08
描述
红黑树是一种特殊的二叉查找树,二叉查找树的性质在这不详细介绍。红黑树的节点除了需要存储key值外,还需要保存一个color信息。下图是一个简单的红黑树
属性
1.所有节点都是有颜色的,red orblack
2.root节点是black
3.叶节点都是black
4.red节点的左右子节点的颜色必须是black
5.从任何一个内部节点(包括根节点)开始,到任何一个叶节点,所有路径上的黑色节点数量相等,计算黑色节点时,不包括起始节点。
我们通常画红黑树的时候常常忽略叶节点,如下
常用操作
Insert:插入一个节点
红黑树的插入操作完成后需要保证新的红黑树不违反红黑树的5条性质。
算法设计(来自《算法导论》):
每次插入一个新的节点时,我们都将新的节点设置为红色,然后按照二叉查找树的插入算法进行操作。
插入完成后,我们分析一下新的树可能会违反哪些属性。重新复习一下红黑树的性质:
1.所有节点都是有颜色的,red or black
2.root节点是black
3.叶节点都是black
4.red节点的左右子节点的颜色必须是black
5.从任何一个内部节点(包括根节点)开始,到任何一个叶节点,所有路径上的黑色节点数量相等,计算黑色节点时,不包括起始节点。
因为插入的是一个red节点,所以性质1,3,5不会受到影响,那么2和4在哪些情况下被违反呢?
Case1:如果我们插入的节点刚好是作为根节点,那么违反了性质2
对于case1,只需改变节点颜色即可,红色变黑色即可。
Case2:如果插入节点的父节点是red,那么就违反了性质4。
但是对于case2,需要分析了。先记这个新插入的节点为z,他的父节点为p(z),祖父节点是p(p(z))。
因为color[z]=red, color[p(z)]=red,根据性质4,所以color[p(p(z))]=black,因为要保持属性5,即从p(p(z))到叶节点的黑色节点数量一致,所以p(p(z))如果有另外的一个子树,那么另外一个子节点肯定是red。
因为z与p(z) ,p(z) 与p(p(z))的左右子树的关系,可以分4种情况,我们可以穷举:z是p(z)左树;z是p(z)右树; p(z)是 p(p(z))左树;p(z)是 p(p(z))右树。两两组合,共四种情况。
如下图:
针对这种情况,设计算法:
首先,改变z的父节点和兄弟节点,祖父节点为相反的颜色,即color[p(z)]=black,color[p(p(z))]=red, color[w]= black,同时让z指向他的祖父节点。拿第一种图做说明,如图所示:
此时,分两种情况讨论
1.如果z是根节点,直接设置color[z]=black,算法结束
2.如果z不是根节点,那么他的父节点会有红黑两种情况:
2.1如果color[p(z)]=black,算法就结束,红黑树性质调整完毕。
2.2如果color[p(z)]=red,那么根据z与p(z)的左右子树关系,分为两种情况,如图:
不管哪种情况,如果p(z)是根节点,直接color[p(z)]=black,调整完毕。
所以我们讨论的是p(z)不是根节点,p(z)是有父节点的,所以图更新如下:
我们先不关心这个A节点与B节点的左右关系。
我们先讨论第二种情况。因为第一种情况会经第一种演变出来。
首先将z指到他的父节点,然后做左旋。如图:
经过这样的左旋转换,这样就到了我们上面所讨论的第一种情况了。
然后我们讨论第一种情况的处理方案,我们做如下变更,如图所示:
首先设置color[p(z)]=black, color[p(p(z))]=red,然后以p(p(z))位锚点,做右旋。这样就完成了整个树的调整。
梳理一下我们的逻辑过程:
删除一个节点
首先思考一下二叉查找树的删掉算法
删除一个节点,按照节点是否有左右子树,可以分为以下几种情况
1.删掉的节点左右子树都存在
2.删除的节点只有左子树
3.删除的节点只有右子树
4.删除的节点无子树
如下图所示,不同情况的Z节点
删掉的节点左右子树都存在
就用上图分析,假如删除的是B节点,即左右子树都存在,那么算法应该是这样的:
首先沿着B节点的右子树寻找最小的节点x。
然后将最小节点x的值赋值到B节点处,删除x,x如果有右子树,保持x子树的关系。
在这幅图中,就是沿着B的右子树的左子树,寻找到了F这个节点,然后将F的值赋值给B,S节点保持在F节点的父节点N的左子树上。
也就是说我们实际上删除的是F,而不是B,只不过B节点的值改变而已。
这种情况下,就会归结到下面两种场景了。
删除的节点只有右子树
删除的节点无子树
如下图所示过程:
删除的节点只有左子树
将N节点的左子树的父节点设置为N节点的父节点D,判断D与N的左右关系,将F设置为D的左/右子树。如图删除的节点只有右子树
逻辑类似上面,不在赘述。
删除的节点无子树
直接删除。
红黑树的删除操作是需要在上述算法的基础上进行红黑树调整,以达到保持红黑树的性质。
针对上述四种情况,删除的节点分别是F,N,P,K。在一个红黑树中,如果这些节点的颜色都是红色,他会违背红黑树性质吗?复习一下红黑树性质
1.所有节点都是有颜色的,red or black
2.root节点是black
3.叶节点都是black
4.red节点的左右子节点的颜色必须是black
5.从任何一个内部节点(包括根节点)开始,到任何一个叶节点,所有路径上的黑色节点数量相等,计算黑色节点时,不包括起始节点。
第1,3,5性质不会违背。
分析剩下的性质在何种场景下会违背:
1. 当删除的节点是root节点,并且它只要一个红色的后续节点,那么就会违背性质2,但是root节点不可能是红色的节点,所以删除红色节点不可能违反性质2。
2. 当删除的节点的是红色节点,那么它的父节点肯定是black,它的子节点肯定是black,,所以也没有问题。
综上所述,如果删除的是红色的节点,不用做任何处理。
所以只需要处理删除的节点color是black的情况。而且根据我们的对二叉查找树的删除操作算法的分析,最后被真正删除的节点无非就三种情况
删除的节点只有左子树
删除的节点只有右子树
删除的节点无子树
而且删除的节点是黑色的,那么他们的父节点的颜色呢?兄弟节点的颜色呢?我们逐一分析。
我们对上面这个图进行分析,颜色不确定的节点用黄色代替。
假设D节点是我们要删除的节点,用y表示。y的子树用x表示,x可能为空节点,即y没有子树。
如果x是空节点,那么图就应该是这样的在这种情况下,删除y,
如果B是黑色的,那么将C直接变成red即可
如果B是红色,那么以B作为锚点,进行左旋,即可。
继续分析x不为空的情况:
如果X是红色的情况下,删除了y,我们只需将y的黑色让x继承,即X的节点由红色变成黑色即可。
上面的情况都很好处理,需要我们认真分析的情况是X是黑色,Y是黑色的情况。看图:
B的颜色,C的颜色,B与y的左右关系都是我们需要分析的。
对于右边的结果,可以有两种场景:
1.C如果是red,那么B只能是black
2.C如果是black,那么B的颜色黑红都可以就在这两种情况下分析,穷举所有情况
C如果是red,那么B只能是black
w指向C,根据红黑树的性质,那么w的后代必须都是黑
对于这种情况,我们将B和C的颜色分别设置为red和black,然后以B为锚点进行左旋,w重新指向x父节点的另外一个子节点。过程如图所示:
经过这样的转换,最后的结果其实也是第二种情况的一个子情况。
C如果是black,那么B的颜色黑红都可以
因为B(X的父节点)的颜色不确定,所以我们暂时先不关心B,以C(用w表示,X的兄弟节点)为切入点进行分析,根据w的子节点的情况可以分为如上图所示的4种情况,那么就对上述4中情况逐一分析。
Case2.1
将w的颜色变成红色,x指向他的父节点B。此时分析B的颜色:
1.如果B是黑色,算法执行完毕,调整完毕
2.如果B是红色,设置B的颜色为黑色即可。调整完毕
Case2.2与 Case2.4
其实就是w的右子树的颜色为red的情况
我们执行如下操作:
Color[w]=color[p(x)]
Color[p(x)]=black
Color[right[w]]=black
然后以B为锚点进行左旋。
具体的解释:
1.设置w的颜色为B的颜色
2.B的颜色设置为黑色
3.w的右子树的颜色设置为黑色
由于B的颜色不确定,经过上述操作后,w的颜色也不确定,但是我们不必关系。
4. 以B为锚点进行左旋。
因为我们使用要保持树的根节点为黑色,这个时候需要进行最后一步的处理,将树根节点设置为黑色即可。
Case2.3
即w的左子树是红色,右子树为黑色。
进行如下操作:
w 设置为 红色
w的左子树设置为黑色
以w为锚点进行右旋
如图所示
分析最后的结果,又进入了case2.2和2.4的情况。
- 红黑树介绍与算法分析
- tarjan算法介绍与分析
- JavaGC算法介绍与分析
- 红黑树介绍与分析
- 红黑树介绍与分析
- 几种排序算法介绍与性能分析
- 算法设计与分析: 第一章 算法分析介绍 1.1求任意三个已知数的最小公倍数
- 算法设计与分析:第一张 算法分析介绍 1.2逻辑推理之警察抓小偷
- 算法设计与分析:第一张 算法分析介绍 1.3逻辑推理之谁能预测分数
- 《数据结构与算法分析》第十二章,K-d树,与配对堆简要介绍与实现
- Memcached 介绍与分析
- Memcached 介绍与分析
- SEDA介绍与分析
- SEDA介绍与分析
- Memcached 介绍与分析
- SEDA介绍与分析
- SEDA介绍与分析
- SEDA介绍与分析
- XMPP
- android UI进阶之style和theme的使用
- MSDTC不可用解决办法
- ArcGIS中合并空间有压盖关系的要素属性
- 最新衡孚科技公司
- 红黑树介绍与算法分析
- 串口转键盘输入
- 尊重原创,请保证您的文章为原创作品11
- 你最喜欢的图片替换方法是什么,你如何选择使用?
- unity动态加载之AssetBundle应用
- activity禁止横竖屏切换
- Ubuntu安装JDK1.8
- Hibernate的HQL中in参数设置
- android反编译APK后,是smali文件,能反编译成dex文件