红黑树由AVL树改进而来,红黑树与AVL都是平衡结构的树。对于AVL树,其每次插入操作都需要从根节点处开始判断该树是否失去平衡,从而做出相应的调整。且其调整过程较为麻烦,每次都需要判断其左右两棵子AVL树的深度情况。相对于红黑树,其将关注点从AVL树的左右两棵子树的深度的失衡情况(也就是平衡因子)转变为了树的节点的颜色。从原先的由于AVL树的深度不一导致的失衡而对该二叉树进行调整转变为了由于该二叉树的相关节点的颜色不符合规则,而对该二叉树进行相应的调整的情况。

红黑树的相关规则:

  1. 每个节点要么是黑色,要么是红色
  2. 根节点是黑色的
  3. 每个叶节点(NULL或空节点)是黑色
  4. 每个红色节点的两个叶子节点都是黑色的(也就是说并不存在两个连续的红色节点)
  5. 从任意一个节点到其子树中的所有路径都包含相同数目的黑色节点

如下图所示:

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

  1. 左旋:

  1. 右旋:

旋转的目的是将节点多的一支出让节点给另一个节点少的一支

在讲解相关的操作之前,明确下各个节点的叫法:

以下讨论红黑树的两个基本操作:

1. 插入:

  对于插入操作,我们插入的节点均将其着色为红色,如果插入的节点为黑色节点,那就违背了性质五,需要进行大规模的调整,如果我们插入的是红色节点,那就在插入节点的父节点也是也是红色的时候违反性质四或者是当插入的节点是根节点时,违反性质二。相对而言,其调整程度小于插入节点为黑色节点的情况。需要注意的是红黑树的插入过程与二叉搜索树的相同,只是之后再进行相应的调整。

下面是可能遇到的插入的几种情况:

  1. 当插入的节点为根节点的时候,只需要直接将该节点涂黑即可。

  2. 当要插入的节点的父节点为黑色的时候,这时插入一个红色的节点并没有对着五个性质产生破坏。所以直接插入不用进行调整。

  3. 如果插入的节点的父节点是红色节点,这时就需要分情况进行相应的调整操作,以保证红黑树的相关性质

    1. 插入的节点的父节点为红色节点,且其父节点是祖父节点的左分支的情况:
      这时,也需要分两种情况进行讨论:

      1. 叔叔节点为红色节点,如下情况所示:

      这时,只需要将父节点和叔叔节点涂成黑色,将祖父节点涂成红色即可。

      1. 叔叔节点为黑色节点

        当叔叔节点为黑色节点的时候,也分两种情况:

        1. 插入节点是父节点的左分支,如下情况所示:

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

        经过调整之后的红黑树可以符合性质四并且不对其它性质产生破坏

        1. 插入节点为父节点的右分支,如下情况所示:


        我们可以先对父节点进行左旋操作,变成如下所示:

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

    2. 插入的节点的父节点为红色节点,且其父节点是祖父节点的右分支,这种情况与插入的节点的父节点为红色节点,且其父节点为祖父节点的右分支的情况互为镜像。为此,只需要将其左节点和右节点进行互换即可。

2. 删除:

  对于删除操作,其过程类似于普通的二叉搜索树的删除过程,分为以下三种情况:

  1. 当删除的元素为叶节点的时候,直接将其进行删除

  2. 当删除的元素有一个子节点时,可以将子节点直接移动到被删除元素的位置,代替被删除的元素

  3. 被删除节点有两个儿子。那么,先找出它的后继节点;然后把“它的后继节点的内容”复制给“该节点的内容”;之后,删除“它的后继节点”。在这里,后继节点相当于替身,在将后继节点的内容复制给"被删除节点"之后,再将后继节点删除。这样就巧妙的将问题转换为"删除后继节点"的情况了,下面就考虑后继节点。 在"被删除节点"有两个非空子节点的情况下,它的后继节点不可能是双子非空。既然"被删除节点的后继节点"不可能双子都非空,就意味着"该节点的后继节点"要么没有儿子,要么只有一个儿子。若没有儿子,则按"情况1 "进行处理;若只有一个儿子,则按"情况2 "进行处理。如图:

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

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

加入颜色之后,被删除元素和后继元素互换只是值得互换,并不互换颜色,这个要注意。以下所讲的被删除元素,均指互换后的被删除元素

下面开始讲一下红黑树删除的规则:

  1. 当被删除元素为红时,对五条性质没有什么影响,直接删除。

  2. 当被删除元素为黑且为根节点时,直接删除。

  3. 当被删除元素为黑,且有一个右子节点为红时,将右子节点涂黑放到被删除元素的位置,如图:

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

变成:

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

变成:

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

变成:

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

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

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

7.当被删除元素为黑且为父元素的右支时,跟情况5.情况6 互为镜像。

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

变成:

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

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

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

博文参考自:最容易懂得红黑树

K:红黑树的更多相关文章

  1. 编程算法 - 最小的k个数 红黑树 代码(C++)

    最小的k个数 红黑树 代码(C++) 本文地址: http://blog.csdn.net/caroline_wendy 题目: 输入n个整数, 找出当中的最小k个数. 使用红黑树(multiset) ...

  2. jdk源码分析红黑树——插入篇

    红黑树是自平衡的排序树,自平衡的优点是减少遍历的节点,所以效率会高.如果是非平衡的二叉树,当顺序或逆序插入的时候,查找动作很可能会遍历n个节点 红黑树的规则很容易理解,但是维护这个规则难. 一.规则 ...

  3. 谈c++ pb_ds库(二) 红黑树大法好

    厉害了,没想到翻翻pb_ds库看到这么多好东西,封装好的.现成的splay.红黑树.avl... 即使不能在考场上使用也可以用来对拍哦 声明/头文件 #include <ext/pb_ds/tr ...

  4. 算法设计和数据结构学习_5(BST&AVL&红黑树简单介绍)

    前言: 节主要是给出BST,AVL和红黑树的C++代码,方便自己以后的查阅,其代码依旧是data structures and algorithm analysis in c++ (second ed ...

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

    本文转载自http://www.ibm.com/developerworks/cn/java/j-lo-tree/ 目录: TreeSet 和 TreeMap 的关系 TreeMap 的添加节点 Tr ...

  6. 研究jdk关于TreeMap 红黑树算法实现

    因为TreeMap的实现方式是用红黑树这种数据结构进行存储的,所以呢我主要通过分析红黑树的实现在看待TreeMap,侧重点也在于如何实现红黑树,因为网上已经有非常都的关于红黑树的实现.我也看了些,但是 ...

  7. BZOJ-3227 红黑树(tree) 树形DP

    个人认为比较好的(高端)树形DP,也有可能是人傻 3227: [Sdoi2008]红黑树(tree) Time Limit: 10 Sec Memory Limit: 128 MB Submit: 1 ...

  8. 浅谈算法和数据结构: 七 二叉查找树 八 平衡查找树之2-3树 九 平衡查找树之红黑树 十 平衡查找树之B树

    http://www.cnblogs.com/yangecnu/p/Introduce-Binary-Search-Tree.html 前文介绍了符号表的两种实现,无序链表和有序数组,无序链表在插入的 ...

  9. java中treemap和treeset实现(红黑树)

    java中treemap和treeset实现(红黑树)   TreeMap 的实现就是红黑树数据结构,也就说是一棵自平衡的排序二叉树,这样就可以保证当需要快速检索指定节点. TreeSet 和 Tre ...

随机推荐

  1. Mac OS 10.12 - 安装Homebrew,像Ubuntu里面的apt一样简单地安装和删除软件!

    Homebrew — macOS 不可或缺的套件管理器,Homebrew官方网站如此介绍自己!!! 中文官网:https://brew.sh/index_zh-cn.html 一,安装 打开shell ...

  2. 初识面向对象-封装、property装饰器、staticmathod(静态的方法)、classmethod(类方法) (五)

    封装 # class Room:# def __init__(self,name,length,width):# self.__name = name# self.__length = length# ...

  3. 2018-2019-2 20175306实验三敏捷开发与XP实践《Java开发环境的熟悉》实验报告

    2018-2019-2 20175306实验三敏捷开发与XP实践<Java开发环境的熟悉>实验报告 实验内容 XP基础 XP核心实践 相关工具 实验要求 1.没有Linux基础的同学建议先 ...

  4. iOS多线程---NSOperation介绍和使用

    1.  NSOperation实现多线程编程,需要和NSOperationQueue一起使用. (1)先将要执行的操作封装到NSOperation中 (2)将NSOperation对象添加到NSOpe ...

  5. linux 从0开始

    网络配置: http://blog.51yip.com/linux/1120.html 网络配置为自动获取 vi命令参考: http://c.biancheng.net/cpp/html/2735.h ...

  6. eclipseGUI的可视化开发工具插件

    一   各种GUI开发插件的特色 Eclipse并不自带GUI的可视化开发工具,那么如果要在Eclipse进行可视化的GUI开发,就需要依靠第三方的插件. 1. Visual Editor Eclip ...

  7. error 'there is already an open datareader associated with this command which must be closed first'

    This can be easily solved by allowing MARS in your connection string. Add MultipleActiveResultSets=t ...

  8. Linux grep命令详解[备份]

    linux grep命令 1.作用Linux系统中grep命令是一种强大的文本搜索工具,它能使用正则表达式搜索文本,并把匹 配的行打印出来.grep全称是Global Regular Expressi ...

  9. Tomcat改端口号;修改访问路径,以及配置Context 标签以后Tomcat启动不了

    修改tomcat端口号: <Connector port="8080" protocol="HTTP/1.1" connectionTimeout=&qu ...

  10. 如何使用Android Studio提高App质量

    Android Studio作为现在谷歌主推的Android开发功能,除了提供了大量的功能帮助快速开发Android代码之外,在代码质量控制方面也提供了很多工具,这些工具都放在Analyze菜单下, ...