产生原因

有了AVL树为啥需要红黑树呢,我们知道AVL树可以保证查询的时间复杂度为O(long 2^N),但是我们知道AVL树的插入操作,结点之间调整非常复杂,导致AVL树的性能非常低下。

红黑树,是一个二叉搜索树,但是每个结点增加一个表示颜色的存储位置,可以是red,black,通过着色方式的限定,使得没有一个路径比其他路径长两倍,因此接近平衡。


上述就是一个标准的红黑树:
那需要成为一个红黑树需要满足哪些性质?
红黑树的性质:

  • 结点的颜色只有两种,红色或者黑色。
  • 根结点必须为黑。
  • 如果一个结点为红色,那么它两个孩子结点必须为黑色。(两个红色结点不能相连)
  • 根结点到每个子节点路径黑色结点数量相同,其孩子结点也满足该性质。
  • 孩子结点都为空。

    可能就有人问,这个叶子结点不就是红色的吗?
    事实上该结点还有两个孩子结点,只不过该孩子结点为空,这块说的叶子结点其实是指这些不存在的孩子结点。

为什么需要这么复杂的性质呢?

  • 一切为了平衡。这样保证最长路径的结点个数不会超过最短路径结点个数的两倍。

查询效率

既然红黑树的要求这么高,那它一定在某些方面具有其他优势。红黑树查询的时间复杂度是O(log2^N),二叉搜索树查询效率为O(N),二叉树的插入时间复杂度为 O(log2N),红黑树的插入操作涉及到颜色的调整,所以比二叉树的插入效率稍微低一点,但是插入的时间复杂度也为O(log2N)

红黑树的调整

那底层怎么调整使得满足上面的性质呢?
红黑树是在二叉搜索树的基础上加上平衡限制条件的,因此红黑树插入新节点分为两步。

  1. 按照二叉搜索树,插入新结点。
  2. 检测红黑树的性质,是否发生改变,如果发生改变,则对其进行调整。
  3. 调整完后保证红黑树的性质不变。
  • 左旋转
    作用:使得左子树的高度增加。
  • 右旋转
    作用:使得右子树的高度增加。

红黑树的插入操作

  1. 查找元素插入的位置。由于红黑树也属于一种二叉搜索树,所以判断插入结点的方法相同。
  2. 创建一个结点,我们可以对其结点给予默认颜色(红色或者黑色都可以),但是我们为了保证红黑树的任何一个路径上的黑色结点数相同,我们给出默认结点颜色为红色。
  3. 但是特性3:如果一个结点为红色,那么它两个孩子结点必须为黑色。有可能会发生冲突,我们需要根据父节点不同对其进行调整。
  • 具体情况1:
    如果插入结点时父节点,我们需要将结点颜色设置为黑色。我们假定插入结点为n
if(n->parent == nullptr)n->color = Black;
  • 情况2:
    如果插入结点的父结点为黑色,则不需要进行调整。(因为我们默认结点的颜色为红色)
if(n->parent->color == Black)return true;
  • 情况3:
    3.1: 如果插入结点的父结点为红色,同时其叔叔结点存在也为红色。

    如上图,待插入结点为红色,父亲结点为红色,叔叔结点也为红色。
    以上情况不满足性质3:两个红色结点不能相邻。,我们需要对其进行调整。

解决办法:
将叔叔结点与父亲结点都设置为黑色,同时将祖父结点设置为红色,如果祖父结点为根节点我们需要将祖父结点重新设置为黑色。例如这样:

3.2: 父结点为红色,祖父结点为黑色,叔叔结点不存在或者为黑色。

  • 3.2.1:父结点为祖父结点的左孩子,待插入结点为父结点的左孩子,则将父结点进行右旋。
  • 3.2.2:父结点为祖父结点的右孩子,待插入结点为父结点的右孩子,则将父结点进行左旋。

3.3 父结点为红色,祖父结点为黑色,叔叔结点为黑色或者不存在。

  • 3.3.1: 父结点为祖父结点的左孩子,待插入结点为父结点的右孩子,将父结点进行左单旋。
  • 3.3.2:父结点为祖父结点的右孩子,待插入结点为父结点的左孩子,将父结点进行右单旋。
  • 则转成情况3.2。

红黑树的验证

因为红黑树也是一种二叉搜索树,所以我们可以通过中序遍历,检验其是否有序。同时,我们可以检验其是否满足红黑树的一些性质

红黑树与AVL树的比较

红黑树与AVL树都是高效的二叉搜索树,增删改查的时间复杂度都为O(log2^N),AVL树追求的是绝对平衡,所以其插入的效率有点低,但是红黑树不追求绝对平衡,它只要求最长路径不超过最短路径的2倍,降低了插入时的旋转次数,所以红黑树的性能比AVL树性能高一点,同时实现简单。

数据结构---红黑树的原理相关推荐

  1. 数据结构 - 红黑树

    数据结构 - 红黑树 - 面试常问知识点 数据结构是面试中必定考查的知识点,面试者需要掌握几种经典的数据结构:线性表(数组.链表).栈与队列.树(二叉树.二叉查找树.平衡二叉树.红黑树).图. 本文主 ...

  2. 左倾红黑树的原理及简单实现

    (注:以下图片全部源于<算法 第4版>) 左倾红黑树的原理及简单实现 左倾红黑树的简介 左倾红黑树的定义 左倾红黑树与2-3树的对比 左倾红黑树的颜色表示 左倾红黑树的一些基本操作 1.颜 ...

  3. 数据结构-红黑树插入结点示例

    数据结构-红黑树插入结点示例 1.红黑树简介 2.在线可视化生成红黑树工具 3.红黑树插入结点性质和规则 3.1.红黑树插入结点性质 3.2.红黑树插入结点规则 4.红黑树插入结点示例 4.1.红黑树 ...

  4. 红黑树结构原理的图文讲解(非代码)

    1.引言 HashMap的基本结构是数组,链表和红黑树.以数组为基本形态,数组中的元素先以链表形式储存,当链表的长度超过8时(包含数组上的那个链表头)就会将链表转换为红黑树,以加快修改和查询效率.当然 ...

  5. 数据结构 红黑树(RBTree)的原理与实现

    学习红黑树之前你应该保证你学过AVL树,也就是平衡二叉搜索树 数据结构 AVL树 AVL树是一棵高度平衡的二叉搜索树,其要求每个结点的高度差不能大于1,这样子就保证了其查询的时间复杂度为log2(N) ...

  6. 数据结构-红黑树原理分析

    前言 在阅读HashMap源码的时候发现,java1.8的HashMap的链表实现增加了红黑树,当链表长度超过指定阈值8的时候回进行树化. 为了提高增删查的效率. 而红黑树又比较复杂,所以专门写一篇关 ...

  7. 红黑树 之 原理和算法详细介绍

    概要 目录 1 红黑树的介绍 2 红黑树的应用 3 红黑树的时间复杂度和相关证明 4 红黑树的基本操作(一) 左旋和右旋 5 红黑树的基本操作(二) 添加 6 红黑树的基本操作(三) 删除 作者:Sk ...

  8. java数据结构红黑树上旋下旋_存储系统的基本数据结构之一: 跳表 (SkipList)

    在接下来的系列文章中,我们将介绍一系列应用于存储以及IO子系统的数据结构.这些数据结构相互关联又有着巨大的区别,希望我们能够不辱使命的将他们分门别类的介绍清楚.本文为第一节,介绍一个简单而又有用的数据 ...

  9. 红黑树的原理以及实现

    红黑树 红黑树基于二叉查找树的附加特性 节点是红色或黑色. 根节点是黑色. 每个叶子节点都是黑色的空节点(叶子结点指为空的叶子结点). 每个红色节点的两个子节点都是黑色的(从每个叶子到根的所有路径上不 ...

最新文章

  1. 定位导致物化视图无法快速刷新的原因
  2. Linux下安装oracle的过程
  3. Special Permutation CodeForces - 1352G(构造)
  4. 欢乐纪中A组赛【2019.8.20】
  5. 超时时间已到,但是尚未从池中获取连接。出现这种情况可能是因为所有池连接均在使用,并且达到了最大池大[转]...
  6. C++之一个函数链的简单例子(分文件实现)
  7. 解决coding上的hexo博客访问不了的问题
  8. 机器学习数学基础学习总结(一)
  9. 快速批量改变图片格式
  10. 【操作系统⑩】——进程死锁【银行家算法+详细样例 进程死锁的预防机制、避免机制、检测与解决】
  11. c语言误差椭圆,平差计算
  12. java读取txt存入数据库,Java 读取txt文件,读取结果保存到数据库
  13. html选择日期选择器
  14. 【Linux】Linux系统学习
  15. 【调剂】西安工业大学刘欢教授“宽光谱量子点成像”科研团队接收5名调剂学生...
  16. android 安全知识总结
  17. SEBASTIEN KWOK 2022春夏系列发布
  18. CSDN学院专属推荐--从Python小白走向Python工程师你只需要它!
  19. composer 安装laravel 5.5 苹果终端
  20. 秉火429笔记之九 中断应用概述

热门文章

  1. 史上最简单的UIScrollView+Autolayout出坑指南
  2. Fit项目分页组件的编写
  3. Java VisualVM无法检测到本地java程序 的 解决办法
  4. Android内存分配的注意事项
  5. LVS--NAT模型
  6. 为什么当拖拽窗口时画面停止渲染?
  7. CentOS 使用spawn-fcgi配置Nginx+PHP 启动脚本
  8. PowerDesigner物理模型用法总结
  9. 当点击ListView的列头时,对ListView排序
  10. [导入]RSS商业应用和电子商务的结合