红黑树和二叉树有什么区别?

什么是二叉树?什么是红黑树?

二叉树(Binary Tree)是指每个节点最多只有两个分支的树结构,即不存在分支大于 2 的节点,二叉树的数据结构如下图所示

这是一棵拥有 6 个节点深度为 2(深度从 0 开始),并且根节点为 3 的二叉树

二叉树有两个分支通常被称作“左子树”和“右子树”,而且这些分支具有左右次序不能随意地颠倒

一棵空树或者满足以下性质的二叉树被称之为二叉查找树

  • 若任意节点的左子树不为空,则左子树上所有节点的值均小于它的根节点的值;
  • 若任意节点的右子树不为空,则右子树上所有节点的值均大于或等于它的根节点的值;
  • 任意节点的左、右子树分别为二叉查找树

如下图所示,这就是一个标准的二叉查找树

二叉查找树(Binary Search Tree)也被称为二叉搜索树、有序二叉树(Ordered Binary Tree)或排序二叉树(Sorted Binary Tree

红黑树(Red Black Tree)是一种自平衡二叉查找树,它最早被称之为“对称二叉 B 树”,它现在的名字源于 1978 年的一篇论文,之后便被称之为红黑树了,所谓的平衡树是指一种改进的二叉查找树,顾名思义平衡树就是将二叉查找树平衡均匀地分布,这样的好处就是可以减少二叉查找树的深度

一般情况下二叉查找树的查询复杂度取决于目标节点到树根的距离(即深度),当节点的深度普遍较大时,查询的平均复杂度就会上升,因此为了实现更高效的查询就有了平衡树

非平衡二叉树如下图所示

平衡二叉树如下图所示

可以看出使用平衡二叉树可以有效的减少二叉树的深度,从而提高了查询的效率

红黑树除了具备二叉查找树的基本特性之外,还具备以下特性

  • 节点是红色或黑色;
  • 根节点是黑色;
  • 所有叶子都是黑色的空节点(NIL 节点);
  • 每个红色节点必须有两个黑色的子节点,也就是说从每个叶子到根的所有路径上,不能有两个连续的红色节点;
  • 从一个节点到该节点的子孙节点的所有路径上包含相同数目的黑色节点

红黑树结构如下图所示

红黑树的优势

红黑树的优势在于它是一个平衡二叉查找树,对于普通的二叉查找树(非平衡二叉查找树)在极端情况下可能会退化为链表的结构,例如,当我们依次插入 3、4、5、6、7、8 这些数据时,二叉树会退化为如下链表结构

当二叉查找树退化为链表数据结构后,再进行元素的添加、删除以及查询时,它的时间复杂度就会退化为 O(n);而如果使用红黑树的话,它就会将以上数据转化为平衡二叉查找树,这样就可以更加高效的添加、删除以及查询数据了,这就是红黑树的优势

红黑树的高度近似 log2n,它的添加、删除以及查询数据的时间复杂度为 O(logn)

在表示算法的执行时间时,通常会使用大 O 表示法,常见的标识类型有以下这些

  • O(1):常量时间,计算时间与数据量大小没关系;
  • O(n):计算时间与数据量成线性正比关系;
  • O(logn):计算时间与数据量成对数关系;

自平衡的红黑树

红黑树能够实现自平衡和保持红黑树特征的主要手段是:变色、左旋和右旋

左旋指的是围绕某个节点向左旋转,也就是逆时针旋转某个节点,使得父节点被自己的右子节点所替代,如下图所示

在 TreeMap 源码中左旋的实现源码如下

// 源码基于 JDK 1.8
private void rotateLeft(Entry<K,V> p) {if (p != null) {// 右子节点Entry<K,V> r = p.right; // p 节点的右子节点为 r 的左子节点p.right = r.left;// r 左子节点如果非空,r 左子节点的父节点设置为 p 节点if (r.left != null) r.left.parent = p; r.parent = p.parent; // r 父节点等于 p 父节点// p 父节点如果为空,那么讲根节点设置为 r 节点if (p.parent == null)root = r;// p 父节点的左子节点如果等于 p 节点,那么 p 父节点的左子节点设置 r 节点else if (p.parent.left == p)p.parent.left = r;elsep.parent.right = r;r.left = p; p.parent = r;}
}

左旋代码说明:在刚开始时,p 为父节点,r 为子节点,在左旋操作后,r 节点代替 p 节点的位置,p 节点成为 r 节点的左孩子,而 r 节点的左孩子成为 p 节点的右孩子

右旋指的是围绕某个节点向右旋转,也就是顺时针旋转某个节点,此时父节点会被自己的左子节点取代,如下图所示

在 TreeMap 源码中右旋的实现源码如下

private void rotateRight(Entry<K,V> p) {if (p != null) {Entry<K,V> l = p.left;// p 节点的左子节点为 l 的右子节点p.left = l.right;// l 节点的右子节点非空时,设置 l 的右子节点的父节点为 pif (l.right != null) l.right.parent = p;l.parent = p.parent;// p 节点的父节点为空时,根节点设置成 l 节点if (p.parent == null)root = l;// p 节点的父节点的右子节点等于 p 节点时,p 的父节点的右子节点设置为 lelse if (p.parent.right == p)p.parent.right = l;else p.parent.left = l;l.right = p;p.parent = l;}
}

右旋代码说明:在刚开始时,p 为父节点 l 为子节点,在右旋操作后,l 节点代替 p 节点,p 节点成为 l 节点的右孩子,l 节点的右孩子成为 p 节点的左孩子

对于红黑树来说,如果当前节点的左、右子节点均为红色时,因为需要满足红黑树定义的第四条特征,所以需要执行变色操作,如下图所示

红黑树和二叉树有什么区别?相关推荐

  1. 【算法】红黑树(二叉树)概念与查询(一)

    诶,算法这个东西,其实没那么简单,但是也没那么难. 红黑树,其实已经有很多大佬都整理过了,而且文章博客都写得超好,我写这篇文章的目的是:自己整理一次,这些知识才是自己的,否则永远是别人的~ 该系列已经 ...

  2. 一文弄懂数据结构中的红黑树、二叉树

    前言 红黑树 在讲红黑树之前,我们需要先了解几种树:二叉树,二叉查找树以及平衡二叉树. 二叉树 最多有 2 个孩子的树称为二叉树.由于二叉树中的每个元素只能有 2 个孩子,我们通常将它们命名为左孩子和 ...

  3. nyoj202 红黑树 (二叉树的左旋右旋)

    题目202 题目信息 运行结果 本题排行 讨论区 红黑树 时间限制:3000 ms  |  内存限制:65535 KB 难度:3 描述 什么是红黑树呢?顾名思义,跟枣树类似,红黑树是一种叶子是黑色果子 ...

  4. 二叉树 红黑树 B树 B+树的优缺点

    前言 在MySQL中,无论是Innodb还是MyIsam,都使用了B+树作索引结构(这里不考虑hash等其他索引).本文将从最普通的二叉查找树开始,逐步说明各种树解决的问题以及面临的新问题,从而说明M ...

  5. 二叉树、红黑树 、平衡二叉树

    二叉搜索树的概念 二叉搜索树又称为二叉排序树,它或者是一棵空树,或者是具有以下性质的二叉树: 若它的左子树不为空,则左子树上所有结点的值都小于根结点的值. 若它的右子树不为空,则右子树上所有结点的值都 ...

  6. 红黑树和平衡二叉树的区别_面试题精选红黑树(c/c++版本)

    红黑树的使用场景非常广泛,比如nginx中用来管理timer.epoll中用红黑树管理事件块(文件描述符).Linux进程调度Completely Fair Scheduler用红黑树管理进程控制块. ...

  7. 二叉树、二叉查找树与红黑树的原理及Java实现

    JAVA二叉树 1. 二叉树简介 在数据量较小的情况下,采用链表可以获得较高的性能(查询时为O(n)),在数据量较大的情况下,链表的检索性能会下降,这时使用二叉树(Binary Tree)进行存储,查 ...

  8. NGINX下的红黑树源码详解(附 流程图和GIF)

    之前博主稍微讲解了下红黑树的原理,那么在这篇博客博主想要把红黑树讲的更加的透彻,以便于更多的人了解红黑树 (本博客会更加详细的介绍之前的博客没介绍到的,所以各位看官不同再回去翻看博主之前那篇红黑树的原 ...

  9. 红黑树(更高级的二叉查找树)

    目录 介绍及性质 红黑树的基本定义 黑高度 时间复杂度 接近于"平衡"操作 红黑树的旋转 红黑树中插入新结点 红黑树中删除结点 红黑树与AVL树的区别 介绍及性质 红黑树(R-B ...

最新文章

  1. ssh-keygen
  2. ionic 项目中添加modal的步骤流程
  3. jvm在创建对象时采用哪些并发安全机制
  4. 使用Qt的多线程编程
  5. Android-Frame布局,UI布局切换,录音,照相机,影音播放器,音频播放器
  6. 领域应用 | 阿里发布藏经阁计划,打造 AI 落地最强知识引擎
  7. java环形队列测试,JAVA数据结构之循环队列的实现
  8. java8 64x下载_jdk8 u102 64位下载
  9. [bzoj 3226]校门外的区间
  10. python安装及配置
  11. gradle 替换java类_Gradle字符串替换
  12. ES测试数据,kibana命令
  13. Word设置每页不同的页眉/修改或去掉页眉横线/页眉标题在横线上下方的设置
  14. 06.Spring Cloud OpenFeign:基于Ribbon和Hystrix的声明式服务调用
  15. COOC2.0一键做邻接表(多元组)+共现矩阵+相异矩阵+频次统计
  16. 2021SCAU数据结构复习(实验1-实验3)
  17. python中使用大写字母来分割字符串
  18. Oracle11g下载地址Oracle下载
  19. 国产充电宝有哪些,国产充电宝哪个牌子的质量好?
  20. 纯CSS实现文字通知无缝衔接无限循环滚动

热门文章

  1. 数据挖掘需要掌握的技能
  2. 13个创意爆棚的广告图片
  3. 如何给图片降噪?看完你就学会了
  4. JAVA语言对接报警类语音通知接口demo示例
  5. java读书网站课程设计_Java课程设计
  6. 魔兽 服务器 角色 最多,魔兽科普:国服人最多的几个服务器都什么来头
  7. office2020与2016版的不同_不同的office哪个版本最好用,比如Office 2016 和 Office 2013?...
  8. Office2019 VOL版本 自定义安装组件
  9. nginx作为图片服务器
  10. java 9宫格抽奖_js 实现9宫格抽奖(react)