K:红黑树
红黑树由AVL树改进而来,红黑树与AVL都是平衡结构的树。对于AVL树,其每次插入操作都需要从根节点处开始判断该树是否失去平衡,从而做出相应的调整。且其调整过程较为麻烦,每次都需要判断其左右两棵子AVL树的深度情况。相对于红黑树,其将关注点从AVL树的左右两棵子树的深度的失衡情况(也就是平衡因子)转变为了树的节点的颜色。从原先的由于AVL树的深度不一导致的失衡而对该二叉树进行调整转变为了由于该二叉树的相关节点的颜色不符合规则,而对该二叉树进行相应的调整的情况。
红黑树的相关规则:
- 每个节点要么是黑色,要么是红色
- 根节点是黑色的
- 每个叶节点(NULL或空节点)是黑色
- 每个红色节点的两个叶子节点都是黑色的(也就是说并不存在两个连续的红色节点)
- 从任意一个节点到其子树中的所有路径都包含相同数目的黑色节点
如下图所示:

通过这五条性质,可以通过数学证明来证明,满足这五条性质的二叉树可以将查找和删除操作维持在对数时间内。当我们插入和删除操作时,所做的一切操作都是为了调整树使之符合这五条性质。以下介绍调整树的相关结构的两个基本操作:
- 左旋:

- 右旋:

旋转的目的是将节点多的一支出让节点给另一个节点少的一支
在讲解相关的操作之前,明确下各个节点的叫法:

以下讨论红黑树的两个基本操作:
1. 插入:
对于插入操作,我们插入的节点均将其着色为红色,如果插入的节点为黑色节点,那就违背了性质五,需要进行大规模的调整,如果我们插入的是红色节点,那就在插入节点的父节点也是也是红色的时候违反性质四或者是当插入的节点是根节点时,违反性质二。相对而言,其调整程度小于插入节点为黑色节点的情况。需要注意的是红黑树的插入过程与二叉搜索树的相同,只是之后再进行相应的调整。
下面是可能遇到的插入的几种情况:
当插入的节点为根节点的时候,只需要直接将该节点涂黑即可。
当要插入的节点的父节点为黑色的时候,这时插入一个红色的节点并没有对着五个性质产生破坏。所以直接插入不用进行调整。
如果插入的节点的父节点是红色节点,这时就需要分情况进行相应的调整操作,以保证红黑树的相关性质
插入的节点的父节点为红色节点,且其父节点是祖父节点的左分支的情况:
这时,也需要分两种情况进行讨论:- 叔叔节点为红色节点,如下情况所示:

这时,只需要将父节点和叔叔节点涂成黑色,将祖父节点涂成红色即可。
叔叔节点为黑色节点
当叔叔节点为黑色节点的时候,也分两种情况:
- 插入节点是父节点的左分支,如下情况所示:

这时,违背了性质四,我们需要对其进行相应的调整,使满足红黑树的相关性质。我们可以通通过对其祖父节点进行右旋同时将祖父节点和父节点的颜色进行互换,这样就变成了:

经过调整之后的红黑树可以符合性质四并且不对其它性质产生破坏
- 插入节点为父节点的右分支,如下情况所示:

我们可以先对父节点进行左旋操作,变成如下所示:
如果我们把原先的父节点看做是新的要插入的节点,把原先要插入的节点看做是新的父节点,那就变成了当要插入的节点在父节点的左支的情况,这样就可以按照当要插入的节点在父节点的左分支的情况进行旋转,旋转后变成如下的情况:

插入的节点的父节点为红色节点,且其父节点是祖父节点的右分支,这种情况与插入的节点的父节点为红色节点,且其父节点为祖父节点的右分支的情况互为镜像。为此,只需要将其左节点和右节点进行互换即可。
2. 删除:
对于删除操作,其过程类似于普通的二叉搜索树的删除过程,分为以下三种情况:
当删除的元素为叶节点的时候,直接将其进行删除
当删除的元素有一个子节点时,可以将子节点直接移动到被删除元素的位置,代替被删除的元素
被删除节点有两个儿子。那么,先找出它的后继节点;然后把“它的后继节点的内容”复制给“该节点的内容”;之后,删除“它的后继节点”。在这里,后继节点相当于替身,在将后继节点的内容复制给"被删除节点"之后,再将后继节点删除。这样就巧妙的将问题转换为"删除后继节点"的情况了,下面就考虑后继节点。 在"被删除节点"有两个非空子节点的情况下,它的后继节点不可能是双子非空。既然"被删除节点的后继节点"不可能双子都非空,就意味着"该节点的后继节点"要么没有儿子,要么只有一个儿子。若没有儿子,则按"情况1 "进行处理;若只有一个儿子,则按"情况2 "进行处理。如图:

将被删除元素与其右支的最小元素互换,变成如下图所示:

然后再将被删除元素删除:

加入颜色之后,被删除元素和后继元素互换只是值得互换,并不互换颜色,这个要注意。以下所讲的被删除元素,均指互换后的被删除元素
下面开始讲一下红黑树删除的规则:
当被删除元素为红时,对五条性质没有什么影响,直接删除。
当被删除元素为黑且为根节点时,直接删除。
当被删除元素为黑,且有一个右子节点为红时,将右子节点涂黑放到被删除元素的位置,如图:

其中节点a为替换后的被删除节点
变成:

- 当被删除元素为黑,且兄弟节点为黑,兄弟节点两个孩子也为黑,父节点为红,此时,交换兄弟节点与父节点的颜色;NULL元素是指每个叶节点都有两个空的,颜色为黑的NULL元素,需要他的时候就可以把它看成两个黑元素,不需要的时候可以忽视他。
如图:
由

变成:

5.当被删除元素为黑、并且为父节点的左支,且兄弟颜色为黑,兄弟的右支为红色,这个时候需要交换兄弟与父亲的颜色,并把父亲涂黑、兄弟的右支涂黑,并以父节点为中心左转。如图:
由:

变成:

6.当被删除元素为黑、并且为父节点的左支,且兄弟颜色为黑,兄弟的左支为红色,这个时候需要先把兄弟与兄弟的左子节点颜色互换,进行右转,然后就变成了规则5一样了,在按照规则5进行旋转。如图:
由

先兄弟与兄弟的左子节点颜色互换,进行右转,变成:

然后在按照规则5进行旋转,变成:

7.当被删除元素为黑且为父元素的右支时,跟情况5.情况6 互为镜像。
8.被删除元素为黑且兄弟节点为黑,兄弟节点的孩子为黑,父亲为黑,这个时候需要将兄弟节点变为红,再把父亲看做那个被删除的元素(只是看做,实际上不删除),看看父亲符合哪一条删除规则,进行处理变化如图:
由:

变成:

9.当被删除的元素为黑,且为父元素的左支,兄弟节点为红色的时候,需要交换兄弟节点与父亲结点的颜色,以父亲结点进行左旋,就变成了情况4,在按照情况四进行操作即可,变化如下:
由:

交换兄弟节点与父亲结点的颜色,以父亲结点进行左旋 变成:

在按照情况四进行操作,变成:

博文参考自:最容易懂得红黑树
K:红黑树的更多相关文章
- 编程算法 - 最小的k个数 红黑树 代码(C++)
最小的k个数 红黑树 代码(C++) 本文地址: http://blog.csdn.net/caroline_wendy 题目: 输入n个整数, 找出当中的最小k个数. 使用红黑树(multiset) ...
- jdk源码分析红黑树——插入篇
红黑树是自平衡的排序树,自平衡的优点是减少遍历的节点,所以效率会高.如果是非平衡的二叉树,当顺序或逆序插入的时候,查找动作很可能会遍历n个节点 红黑树的规则很容易理解,但是维护这个规则难. 一.规则 ...
- 谈c++ pb_ds库(二) 红黑树大法好
厉害了,没想到翻翻pb_ds库看到这么多好东西,封装好的.现成的splay.红黑树.avl... 即使不能在考场上使用也可以用来对拍哦 声明/头文件 #include <ext/pb_ds/tr ...
- 算法设计和数据结构学习_5(BST&AVL&红黑树简单介绍)
前言: 节主要是给出BST,AVL和红黑树的C++代码,方便自己以后的查阅,其代码依旧是data structures and algorithm analysis in c++ (second ed ...
- 通过分析 JDK 源代码研究 TreeMap 红黑树算法实现
本文转载自http://www.ibm.com/developerworks/cn/java/j-lo-tree/ 目录: TreeSet 和 TreeMap 的关系 TreeMap 的添加节点 Tr ...
- 研究jdk关于TreeMap 红黑树算法实现
因为TreeMap的实现方式是用红黑树这种数据结构进行存储的,所以呢我主要通过分析红黑树的实现在看待TreeMap,侧重点也在于如何实现红黑树,因为网上已经有非常都的关于红黑树的实现.我也看了些,但是 ...
- BZOJ-3227 红黑树(tree) 树形DP
个人认为比较好的(高端)树形DP,也有可能是人傻 3227: [Sdoi2008]红黑树(tree) Time Limit: 10 Sec Memory Limit: 128 MB Submit: 1 ...
- 浅谈算法和数据结构: 七 二叉查找树 八 平衡查找树之2-3树 九 平衡查找树之红黑树 十 平衡查找树之B树
http://www.cnblogs.com/yangecnu/p/Introduce-Binary-Search-Tree.html 前文介绍了符号表的两种实现,无序链表和有序数组,无序链表在插入的 ...
- java中treemap和treeset实现(红黑树)
java中treemap和treeset实现(红黑树) TreeMap 的实现就是红黑树数据结构,也就说是一棵自平衡的排序二叉树,这样就可以保证当需要快速检索指定节点. TreeSet 和 Tre ...
随机推荐
- KMP Demo
The key of Kmp is to build a look up table that records the match result of prefix and postfix. Valu ...
- sublime text3---Emmet:HTML/CSS代码快速编写神器
Emmet的前身是大名鼎鼎的Zen coding,如果你从事Web前端开发的话,对该插件一定不会陌生.它使用仿CSS选择器的语法来生成代码,大大提高了HTML/CSS代码编写的速度,比如下面的演示: ...
- 请求数据分析 xpath语法 与lxml库
前情提要: 上节学过从网上获取请求,获取返回内容,带理 获取内容之后,第二部就是获取请求的数据分析 一:xpath 语法 浏览器一般会自带xpatn 解析 这里大概讲述一下xpath 的基本操作 二: ...
- (转)MySQL中show语法
MySQL中show语法 1. show tables或show tables from database_name; -- 显示当前数据库中所有表的名称. 2. show databases; -- ...
- Eclipse+jboss5 无法启动
在使用Eclipse luna 配置Jboss5 时,配置成功,但无法在eclipse 控制台上启动. log: Deployment "AttachmentStore" is i ...
- Builder生成器(创建型模式)
一.使用场景: 1.假设要创建一个House设施,该设施的创建由若干个部分组成,而且这若干个部分经常变化. 如果用最直观的设计方式,每一个房屋部分的变化,都将导致整个房屋结构的重新修正,但是这种设计方 ...
- VUE输入框显示时自动聚焦
directives: { focus: { inserted: function (el, {value}) { if (value) { el.focus() } } } } 注意点:1.用v-i ...
- tensorflow进阶篇-3
#-*- coding:utf-8 -*- #Tensorflow的嵌入Layer import numpy as np import tensorflow as tf sess=tf.Session ...
- Qt: QTimer和QThread
让QTimer 跑在其他线程. 一般写法如下. 1. 在main thread中为worker thread指定定时器. QThread* thread = new QThread(this); th ...
- java 实现 HTTP请求(GET、POST)的方法
使用Java进行服务调用时,避免不了要使用模拟HTTP请求来实现模拟,我在开发过程中恰巧遇到了这类的业务需求,所以就对这类的方法进行了一次总结,原理层次的东西暂时不考虑,毕竟HTTP的底层实现啥的,东 ...