红黑树删除操作

若被删除的结点有两个非叶子结点,那么可以转换为删除一个“替代点”的问题,该替代点最多只有一个非叶子孩子结点。可以通过前驱或者后继(都最多有一个非叶子孩子结点)来替代最初要被删除的结点,所以下面只关注只有一个非叶子孩子结点的问题,一旦我们解决了这个问题,那么解决方法将同样适用于两种情形:
1、原本想删除的结点最多有一个非叶子孩子结点
2、原本想删除的结点有两个非叶子孩子结点(通过前驱和后继可以转化为最多有一个非叶子孩子结点)

好了,现在用N来表示替代结点(要是被删除的结点没有替代结点,那么N就表示原本要被删除的结点,由红黑树的属性可以推出该结点不可能有孙子结点),替代结点要么是前驱,要么是后继,但是都最多只有一个非叶子孩子结点(程序中使用的是前驱)。结点N为不同颜色时,处理方式不一样,具体如下。

结点N为红色:

若结点N为红色,那么它的孩子结点必须是黑色的,而且两个孩子结点都是叶子结点(因为结点N最多只能有一个非叶子孩子结点,所以只能是一边是一个黑色的非叶子孩子结点,另一边是一个黑色叶子结点,这样通过结点N的路径的黑色结点的数目就不一样了(因为黑色的非叶子孩子结点至少有两个黑色叶子结点),这样就违反了性质5)。此时直接将N删除即可,删除之后N被空叶子结点(NULL)替代,而NULL结点都是黑色的,所以属性5依然保持。好了,结点N为红色的情形比较简单,下面看结点N为黑色的情形。

结点N为黑色:

结点N为黑色时,可以分为两种情况:
第1种情况:若其孩子结点M有一个是非叶子结点,另外一个是黑色空叶子结点,那么非叶子结点M必须是红色。因为如果非叶子结点也是黑色的,这样通过结点N的路径的黑色结点的数目将不一样(通过空叶子结点这边的黑色结点的数目是2,而通过黑色非叶子结点这边的至少是3),由此违反了性质5。所以非叶子结点M只能是红色的,这种情况比较简单,只需用M代替N,并将M变为黑色,则不违反任何属性,此时依然是一棵合格的红黑树。

第2种情况:若两个孩子结点都为空叶子结点(叶子结点都为黑色,并且是NULL),则此时用空叶子结点NULL替代N后,通过原始替代结点N的路径的黑色结点的数目将比原来减少1,此时就要分类讨论了,将替代结点N的父结点表示为P,兄弟结点表示为S。具体分类如下:

case 1:

N是根结点,在这种情况下,我们已经做完了(仅仅通过直接返回就可以达到这个效果!),因为这种情况下整棵树只有一个结点(注意大前提:N的两个孩子结点都是空叶子结点,所以整棵树只有一个结点),要删除的结点正是根结点,直接返回之后,在上一层函数中用N的子结点(NULL)替代N,相当于将N删除掉了。

注意:在case 2,case 5,case 6中,我们假设N是父结点P的左孩子结点,如果是右孩子结点,那么“左”和“右”应该对调。

case 2:

N的兄弟结点S是红色的(从case 3开始S都是黑色的)。此时对调父结点P(肯定是黑色的)和兄弟结点S的颜色,然后将父结点P左旋。注意此时如果直接将N删掉而结束,那么P结点的左边只有一个黑色结点(NULL),而右边有两个黑色结点(S的左孩子和S的孙子结点(黑色的空叶子结点)),这样就违反了属性5,所以左旋之后将接着按case 4、case 5或case 6来处理。

case 3:

结点N的父结点P,兄弟结点S以及S的孩子结点都是黑色的。此时简单的将S设为红色,这样做可以让通过S的所有路径都少一个黑色节点,与通过N的路径的黑色结点就相同了。但是,通过P的所有路径现在比不通过P的路径少了一个黑色节点,所以仍然违反性质5。要修正这个问题,我们要从case 1开始,在P上做重新平衡处理,并且一直递归到根结点为止,到根结点时,通过根结点的所有路径都少了一个黑色结点,然后再从case 1返回。

case 4:

结点N的父结点P是红色的,兄弟结点S以及S的两个孩子结点(都是空叶子结点)都是黑色。此时将P和S的颜色对调,这不影响通过S的黑色结点数量,但是在通过N的路径上增加了一个黑色结点,正好和要删除的结点N相抵消,这样属性5被满足了。

case 5:

结点N的兄弟结点S的左孩子是红色,右孩子是黑色(左红右黑),并且结点N是父结点P的左孩子。此时将S与其左孩子的颜色对调,然后右旋S。注意此时通过父结点P的路径都有相同的黑色结点数目,但是如果直接将N删掉会违反属性5(与case 2中类似),所以我们继续按照case 6来处理。

case 6:

结点N的兄弟结点S是黑色的,S的右孩子是红色的(右红),并且结点N是父结点P的左孩子。此时将父结点P和兄弟结点S的颜色,再将S的右孩子变为黑色,然后左旋父结点P。(未完待续)

时间: 2024-11-08 21:56:25

红黑树删除操作的相关文章

红黑树删除节点

参考<算法导论第三版> 红黑树删除方法比较. 传统方法: RB-Delete(T, z) if ((T.Nil == z.left) || (T.Nil == z.right)) y = z else y = RB-Min(z.right) if (T.Nil != y.left) x = y.left else x = y.right RB-Transplate(y, x) x.p = y.p if (z != y) copy y.data to z.data if (BLACK == y.

红黑树-插入操作

红黑树的五个性质: 1)每个结点要么是红的,要么是黑的. 2)根结点是黑的. 3)每个叶结点,即空结点(NIL)是黑的. 4)如果一个结点是红的,那么它的俩个儿子都是黑的. 5)对每个结点,从该结点到其子孙结点的所有路径上包含相同数目的黑结点. 红黑树插入的几种情况: 1.树是空的,直接将节点设置为根节点,颜色为黑: public void case1(RBnode T,RBnode newNode){        if(newNode.getParent()==null){         

红黑树插入操作

通过具体分析每一步的操作来理解插入过程,将每一步操作之后的树结构打印出来可以帮助我们理解,在图中"#"表示黑色,"~"表示红色,空结点(NULL)都为黑色,但是没有被打印出来,看图像的时候注意一下就可以了. 下面将整个过程贴出来,所有的步骤都是通过程序实现的. Inserting 61 ----------------------------------------------------- case 1 <61> (若当前结点是根结点,则将其颜色设置为

红黑树的删除操作详解

注:本文转载自博客园,博主原址:http://www.cnblogs.com/tongy0/p/5460623.html,感谢博主帮我弄清楚了红黑树删除操作,转载做收藏用. 红黑树的删除操作 1:节点命名约定 D表示要被删除的节点.即:取 Delete 的首字母: P 表示父节点.即:取 Parent 的首字母: S表示兄弟姐妹节点.即:取 Sibling的首字母: U表示叔伯节点.即:取Uncle的首字母: G表示祖父节点.即:取 Grandfather的首字母: L表示左树.即:取Left的

算法导论之红黑树的学习

最近学习了二叉搜索树中的红黑树,感觉收获颇丰,在此写一篇文章小结一下学到的知识,顺便手写一下Java代码. 1.引言 先来讲讲什么是二叉搜索树,二叉搜索树有如下特点:他是以一颗二叉树(最多有两个子结点)来组织的,对于树中的某个节点,其左子树的所有元素均小于该节点,其右子树的元素均大于该节点.我们知道一颗有N个节点的二叉树的高度至少为lgN,然后在树上的操作都与其高度有关,因此限制树的高度就显得非常有必要.当一个二叉搜索树的高度是lgN时,在该树上的插入删除搜索等操作均为O(lgN)的时间复杂度,

红黑树并没有我们想象的那么难(上)

红黑树并没有想象的那么难, 初学者觉得晦涩难读可能是因为情况太多. 红黑树的情况可以通过归结, 通过合并来得到更少的情况, 如此可以加深对红黑树的理解. 网络上的大部分红黑树的讲解因为没有「合并」. 红黑树的五个性质: 性质1. 节点是红色或黑色. 性质2. 根是黑色. 性质3. 所有叶子都是黑色(叶子是NIL节点). 性质4. 每个红色节点的两个子节点都是黑色.(从每个叶子到根的所有路径上不能有两个连续的红色节点) 性质5. 从任一节点到其每个叶子的所有简单路径 都包含相同数目的黑色节点. 红

算法-树(2)—2-3树,红黑树

本篇文章主要介绍2-3树,并由2-3树重点介绍RB树(红黑树) 后附完整代码 2-3树 1. 2-3树 2-3树概念: 一颗2-3查找树,或为空树,或为由2-结点,3-结点构成的树. 2-结点:含有一个键值对和两个链接,左链接的结点均小于该结点,右链接的结点均大于该结点. 3-结点:含有两个键值对和三个链接,左链接的结点小于该节点的小的键值,中链接介于该结点的两个键值之间,右链接大于改结点的大的键值. 2. 2-3树的查找添加 1).查找: 参照上一篇文章,实现较为简单,即比较需要查找的key值

红黑树数据结构剖析

红黑树是计算机科学内比较常用的一种数据结构,它使得对数据的搜索,插入和删除操作都能保持在O(lgn)的时间复杂度.然而,相比于一般的数据结构,红黑树的实现的难度有所增加.网络上关于红黑树的实现资料汗牛充栋,但是乏于系统介绍红黑树实现的资料.本文通过一个自己实现的红黑树数据结构以及必要的搜索,插入和删除操作算法,为大家更系统地剖析红黑树数据结构的实现. 对于大部分数据结构,一般都会使用抽象数据类型的方式实现,C++提供的模板机制可以做到数据结构与具体数据类型无关,就像STL实现的那样.不过本文并非

红黑树分析,看了都说好

红黑树简介 红黑树是一种自平衡的二叉查找树,是一种高效的查找树.它是由 Rudolf Bayer 于1978年发明,在当时被称为对称二叉 B 树(symmetric binary B-trees).后来,在1978年被 Leo J. Guibas 和 Robert Sedgewick 修改为如今的红黑树.红黑树具有良好的效率,它可在 O(logN) 时间内完成查找.增加.删除等操作.因此,红黑树在业界应用很广泛,比如 Java 中的 TreeMap,JDK 1.8 中的 HashMap.C++