【转载】完整简单的红黑树算法

原文:

完整简单的红黑树算法

最近组内定个规矩,每周分享一个算法,上周是第一周,分享的是红黑树,下面是自己学习总结的,感觉网上的都不是特别清楚,要么是写的特别复杂,没有一点条理。

一、红黑树性质

1.每个结点要么是红的要么是黑的

2.根结点是黑的

3.每个叶结点(叶结点即指树尾端NIL指针或NULL结点)都是黑的

4.如果一个结点是红的,那么它的两个儿子都是黑的

5.对于任意结点而言,其到叶结点树尾端NIL指针的每条路径都包含相同数目的黑结点

总结:平衡状态下红黑树要么单支黑-红,要么有两个子节点

二、复杂度

O(lgn)

三、结点插入

将一个节点插入到红黑树中,需要执行哪些步骤呢?首先,将红黑树当作一颗二叉查找树,将节点插入;然后,将节点着色为红色;最后,通过旋转和重新着色等方法来修正该树,使之重新成为一颗红黑树。

1.将插入的节点着色为红色,不会违背"特性(5)"!少违背一条特性,就意味着我们需要处理的情况越少。接下来,就要努力的让这棵树满足其它性质即可;满足了的话,它就又是一颗红黑树了

2.对于"特性4",是有可能违背的!

总之:新插入的结点是红色!

3.插入的5种情况:

(1)如果插入的是根结点,由于原树是空树,此情况只会违反性质2,因此直接把此结点涂为黑色;

(2) 如果插入的结点的父结点是黑色,由于此不会违反性质2和性质4,红黑树没有被破坏,所以此时什么也不做。

(3) 如果当前结点的父结点是红色且祖父结点的另一个子结点(叔叔结点)是红色;

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

以下(4)(5)都以左孩子为例,右孩子进行对称操作即可

(4)当前节点的父节点是红色,叔叔节点是黑色,当前节点是其父节点的左孩子;

解决: 父节点变为黑色,祖父节点变为红色,在祖父节点为支点右旋。

(5)当前节点的父节点是红色,叔叔节点是黑色,当前节点是其父节点的右子;

解决:当前节点的父节点做为新的当前节点,以新当前节点为支点左旋。问题转为(4)

总结:整个过程就是解决以上几个问题,关键是整个过程要更新当前节点是哪个结点

四、结点删除

需要执行的操作依次是:首先,将红黑树当作一颗二叉查找树,将该节点从二叉查找树中删除;然后,通过"旋转和重新着色"等一系列来修正该树,使之重新成为一棵红黑树。

待删除的节点按照儿子的个数可以分为三种:

1.删除叶结点(没有子结点)

(1)如果叶结点为红色,直接删除

(2)如果叶结点为黑色,兄弟结点没有子结点

解决: 兄弟节点B绘为红色,父节点P绘为黑色。

注意:之后操作的结点全为左孩子,右孩子进行对称操作即可

(3)叶结点为黑色,兄弟结点有一个孩子不为NIL。若这个孩子为右孩子。

解决:将B的这个右孩子绘为黑色,B绘为其父节点P原来的颜色,P绘为黑色,然后对P进行一次左旋转。

 

 

(4)叶结点为黑色,兄弟结点有一个孩子不为NIL,若这个孩子为左孩子。

解决:将B的这个左孩子绘为黑色,B绘为红色,然后对B进行一次右旋转,问题转化为右孩子的情况。

 

 

(5)叶结点为黑色,兄弟结点有两个孩子。 若兄弟结点(B)为红色,则B的两个孩子一定为黑色。

解决:将B绘为黑色,B的左孩子绘为红色,然后对P(父结点)进行一次左旋转。

 

(6)叶结点为黑色,兄弟结点(B)有两个孩子。 若B为黑色,则B的两个孩子一定为红色。

解决:将B的父节点P绘为黑色,B的右孩子绘为黑色,B绘为其父节点P原来的颜色,然后对P进行一次左旋转。

2.删除结点有一个外部结点(有一个子结点, 这个结点C一定是红色节点,否则从D到各个NIL节点的路径上的黑色节点数目就会不同)

解决:交换D(删除结点)和C(子结点)的内容(颜色保持不变),被删除节点变为C,问题转化为被删除节点的两个孩子都为NIL的情况。重新查看树是否满足红黑树。

3.删除结点有两个外部结点(有两个子结点)

解决:按照二叉查找树删除节点的方法找到D的后继节点S,交换D和S的内容(颜色保持不变),被删除节点变为S,如果S有不为NIL的节点,那么继续用S的后继节点替换S(此过程可能是一级一级找,也可能是直接找左子树的最大值,取决于本来要删除的结点和实际删除结点的值的大小,要删除的结点比实际删除的结点小,一级一级找,否则相反),直到被删除节点的两个孩子都为NIL,问题转化为被删除节点D的两个孩子都为NIL的情况。

其中的左旋右旋其实也很简单,有不清楚的大家上网查查,此处不再详细叙述了。

五、应用场景

1.著名的linux进程调度Completely Fair Scheduler,用红黑树管理进程控制块

2.epoll在内核中的实现,用红黑树管理事件块

3.nginx中,用红黑树管理timer等

4.Java的TreeMap实现

5.广泛用在C++的STL中。map和set都是用红黑树实现的。

六、其他

从头到尾的插入和删除操作案例插图:

http://blog.csdn.net/v_july_v/article/details/6284050

nginx 红黑树的实现(c实现)

http://blog.csdn.net/liuxuejiang158blog/article/details/21417145

c的红黑树实现

http://www.cnblogs.com/skywang12345/p/3624177.html#a3

php的红黑树实现

http://www.zhangley.com/article/php_rbtree/

时间: 2024-08-05 21:39:21

【转载】完整简单的红黑树算法的相关文章

完整简单的红黑树算法

最近组内定个规矩,每周分享一个算法,上周是第一周,分享的是红黑树,下面是自己学习总结的,感觉网上的都不是特别清楚,要么是写的特别复杂,没有一点条理. 一.红黑树性质 1.每个结点要么是红的要么是黑的 2.根结点是黑的 3.每个叶结点(叶结点即指树尾端NIL指针或NULL结点)都是黑的 4.如果一个结点是红的,那么它的两个儿子都是黑的 5.对于任意结点而言,其到叶结点树尾端NIL指针的每条路径都包含相同数目的黑结点 总结:平衡状态下红黑树要么单支黑-红,要么有两个子节点 二.复杂度 O(lgn)

通过分析 JDK 源代码研究 TreeMap 红黑树算法实现

TreeMap 的实现就是红黑树数据结构,也就说是一棵自平衡的排序二叉树,这样就可以保证当需要快速检索指定节点. TreeSet 和 TreeMap 的关系 为了让大家了解 TreeMap 和 TreeSet 之间的关系,下面先看 TreeSet 类的部分源代码: public class TreeSet<E> extends AbstractSet<E> implements NavigableSet<E>, Cloneable, java.io.Serializab

通过分析 JDK 源代码研究 TreeMap 红黑树算法实

TreeMap 和 TreeSet 是 Java Collection Framework 的两个重要成员,其中 TreeMap 是 Map 接口的常用实现类,而 TreeSet 是 Set 接口的常用实现类.虽然 HashMap 和 HashSet 实现的接口规范不同,但 TreeSet 底层是通过 TreeMap 来实现的,因此二者的实现方式完全一样.而 TreeMap 的实现就是红黑树算法. TreeMap 的实现就是红黑树数据结构,也就说是一棵自平衡的排序二叉树,这样就可以保证当需要快速

红黑树算法原理(十三)

前言 最近断断续续花了一个礼拜的时间去看红黑树算法,关于此算法还是比较难,因为涉及到诸多场景要考虑,同时接下来我们要讲解的HashMap.TreeMap等原理都涉及到红黑树算法,所以我们不得不了解其原理,关于一些基础知识这里不再讲解,本文参考博文:<https://www.cnblogs.com/aspirant/p/9084199.html>,参考链接太多文字描述,看过很多关于红黑树的文章,有些越讲越懵逼,有些讲的挺好关键是不说人话(这里不是骂人哈,指的是文章讲解的还是有点抽象),在这里希望

简单聊聊红黑树(Red Black Tree)

? 前言 众所周知,红黑树是非常经典,也很非常重要的数据结构,自从1972年被发明以来,因为其稳定高效的特性,40多年的时间里,红黑树一直应用在许多系统组件和基础类库中,默默无闻的为我们提供服务,身边有很多同学经常问红黑树是怎么实现的,所以在这里想写一篇文章简单和大家聊聊下红黑树 小编看过很多讲红黑树的文章,都不是很容易懂,主要也是因为完整的红黑树很复杂,想通过一篇文章来说清楚实在很难,所以在这篇文章中我想尽量用通俗口语化的语言,再结合 Robert Sedgewick 在<算法>中的改进的版

红黑树&mdash;&mdash;算法导论(15)

1. 什么是红黑树 (1) 简介     上一篇我们介绍了基本动态集合操作时间复杂度均为O(h)的二叉搜索树.但遗憾的是,只有当二叉搜索树高度较低时,这些集合操作才会较快:即当树的高度较高(甚至一种极端情况是树变成了1条链)时,这些集合操作并不比在链表上执行的快.     于是我们需要构建出一种"平衡"的二叉搜索树.     红黑树(red-black tree)正是其中的一种.它可以保证在最坏的情况下,基本集合操作的时间复杂度是O(lgn). (2) 性质     与普通二叉搜索树不

浅析红黑树算法

红黑树简介 红黑树是一种自平衡二叉查找树,也有着二叉搜索树的特性,保持着右边始终大于左边结点key的特性.前面提到过的AVL树,也是二叉搜索树的一种变形,红黑树没有达到AVL树的高度平衡,换句话说,它的高度,并没有AVL树那么高的要求,但他的应用却更加的广泛,实践中是相当高效的,他可以在O(log n)的时间内做查找.插入.删除操作.在C++ STL中,set.multiset.map.multimap等都应用到的红黑树的变体. 红黑树在平衡二叉搜索树的前提下,每个节点新增了 _color 这一

C++实现一个简单的红黑树(RB_TREE)

红黑树遵守的规则:一头(根)一脚(叶子节点)黑(黑色),黑同(从任意节点开始至NULL结点的黑色节点的个数相等)红不连(红色节点不能相连) 以下是红黑树的插入和旋转函数的简易实现: #include <iostream> #include <assert.h> #include <string.h> using namespace std; typedef int Type; typedef enum{RED=0, BLACK}Color; //节点的颜色 typede

红黑树-算法大神的博客-以及java多线程酷炫的知识

http://www.cnblogs.com/skywang12345/p/3245399.html 解释第5条:从 ->根节点(或者任意个结点)到->所有的末端节点的路径中 ->黑色节点 数目相同 <一代宗师>,不比武功比想法 计算机中最为重要的课程 1.数学(线性代数,概率统计,集合论图论,矩阵理论) 2.数据结构与算法 3.操作系统