算法:什么是红黑树

article/2025/4/24 19:20:28

红黑树的定义

红黑树的英文是“Red-Black Tree”,简称 R-B Tree。它是一种不严格的平衡二叉查找树。顾名思义,红黑树中的节点,一类被标记为黑色,一类被标记为红色。除此之外,一棵红黑树还需要满足这样几个要求:

  • 每个节点要么是红色,要么是黑色。

  • 根节点必须是黑色, 每个叶子节点是黑色(叶子节点包含NULL,也就是说,叶子节点不存储数据)。

    • 为什么黑节点必须是黑色呢?根节点要么对应2-3树的2-节点或者3-节点,而这两者的根节点都是黑色的,因而根节点必然是黑色。
    • 为什么叶子节点必须是黑色的空节点呢?这主要是为了简化红黑树的代码实现而设置的。
      在这里插入图片描述
  • 红色节点不能连续

    • 红色节点的孩子和父亲都不能都是红色,即如果一个节点是红色的,则它的子节点必须是黑色的
    • 也就是说任何相邻的节点都不能同时为空色,红色节点是被黑色节点隔开的。
    • 由于红黑树的每个节点都由2-3树转换而来,红色节点连接的节点必然是一个2-节点或者3-节点,而无论是2-节点还是3-节点,其根节点都是黑色的,因此红色节点的子节点必然是黑色的
  • 从任意节点出发,到其所有叶子节点的简单路径上都包含相同数目的黑色节点.

红黑树的发明过程

平衡二叉查找树

我们以这样一个数组为例 [42,37,18,12,11,6,5] 构建一棵二叉搜索树,由于数组中任意一点都可以作为二叉搜索树的根节点,因此这棵二叉搜索树并不唯一,我们来看一个极端的例子(以42作为根节点,顺序插入元素)

在这个例子中,二叉搜索树退化成了链表,搜索的时间复杂度为 O(n),失去了作为一棵二叉搜索树的意义。

为了让二叉搜索树不至于太“倾斜”,我们需要构建一棵平衡二叉搜索树
在这里插入图片描述
可以看出,平衡二叉搜索树的搜索时间复杂度为O(logn),避免了因为随机选取根节点构建二叉搜索树而可能造成的退化成链表的情况。下面再抄一段平衡二叉搜索树的官方定义:

平衡二叉查找树:简称平衡二叉树。是由前苏联的数学家 Adelse-Velskil和 Landis 在 1962 年提出的高度平衡的二叉树,根据科学家的英文名也称为 AVL 树。它具有如下几个性质:

  • 可以是空树。
  • 假如不是空树,任何一个结点的左子树与右子树都是平衡二叉树,并且高度之差的绝对值不超过 1

2-3树

经过上面的例子,我们可以知道,构建一颗平衡二叉搜索树的关键在于选取“正确”的根节点, 那么我们如何在每次构建平衡二叉搜索树的时候都能选取合适的根节点呢?这里就要另一种重要的树:2-3树(读作二三树),2-3树和红黑树是等价的,理解2-3树对理解红黑树以及B类树都有很大的帮助。

为什么有了2-3树还需要有红黑树呢?

既然2-3树已经能够保持自平衡,为什么我们还需要一颗红黑树呢?

首先2-3树就是一个节点有1个或者2个元素,而实际上2-3树转红黑树是由概念模型2-3-4树转换而来的。4叉就是一个节点里有3个元素,这在2-3树中会被调整,但是在概念模型中是会被保留的。

虽然2-3-4树也是具备2-3树同样的平衡树的特性,但是如果直接把这样的模型用代码实现就会很麻烦,且效率不高,这里的复杂点包括;

  • 2-叉、3-叉、4-叉,三种结构的节点类型,互相转换复杂度较高
  • 3-叉、4-叉,节点在数据比较上需要进行多次,不像2-叉节点,直接布尔类型比较即可非左即右
  • 代码实现上对每种差异,都需要有额外的代码,规则不够标准化

所以,希望找到一种平衡关系,既保持2-3树平衡和O(logn)的特性,又能在代码实现上更加方便,那么就诞生了红黑树。

也就是说:2-3树这种每个节点存储1-2个元素以及拆分节点向上融合的性质不便于代码操作。因此我们希望通过一些规则,将2-3树转换成二叉树,而且转换后的二叉树依然能够保持平衡。

红黑树实际上就是2-3树的二分搜索树表示,其中红节点于其父节点组合形成3节点,没有红色孩子节点的节点就是2节点
在这里插入图片描述

例如这颗红黑树中,这个红色的节点与其父节点(元素11所在的节点)组成一个3节点,这颗红黑树等价于以下的2-3树
在这里插入图片描述

总结:我们怎么将2-3树转换为红黑树

  • 对于2节点,可以直接转换为红黑树中的一个黑节点
  • 对于3节点:
    • 将3节点拆开,成为一棵树,并且3节点的左元素作为又元素的子树
    • 将原来的左元素标记为红色(表示红色节点于其父节点在2-3树种曾经是平衡关系)
      在这里插入图片描述
      推论:由于红色节点是由3节点拆分而来,因此所有的红色节点只会出现在左子树上。
      在这里插入图片描述

为什么说红黑树是“近似平衡”的

平衡二叉查找树的初衷,是为了解决二叉查找树因为动态更新导致的性能退化问题。所以,“平衡”的意思可以等价为性能不退化。“近似平衡”可以等价为性能不会退化的太严重

二叉查找树很多操作的性能都跟树的高度成正比。一棵极其平衡的二叉树(满二叉树或完全二叉树)的高度大约是 l o g 2 n log_2n log2n,所以如果要证明红黑树是近似平衡的,我们只需要分析,红黑树的高度是否比较稳定地趋近 l o g 2 n log_2n log2n 就好了。

那怎么推导红黑树的高度呢?

(1)首先,我们来看,如果我们将红色节点从红黑树中去掉,那单纯包含黑色节点的红黑树的高度是多少呢?

  • 红色节点删除之后,有些节点就没有父节点了,它们会直接拿这些节点的祖父节点(父节点的父节点)作为父节点。所以,之前的二叉树就变成了四叉树。

在这里插入图片描述

  • 红黑树中的定义有这么一条:从任意节点到可达的叶子节点的每个路径包含相同数组的黑色节点。我们从四叉树中取出某些节点,放到叶节点位置,四叉树就变成了完全二叉树。所以,仅包含黑色节点的四叉树的高度,比包含相同个数的完全二叉树的高度还要小。

  • 完全二叉树的高度近似 l o g 2 n log_2n log2n,这里的四叉“黑树”的高度要低于完全二叉树,所以去掉红色节点的“黑树”的高度也不会超过 l o g 2 n log_2n log2n

(2)那我们现在把红色节点加回去,高度会变成多少呢?

  • 在红黑树中,红色节点不能相邻,也就是说,有一个红色节点就要至少有一个黑色节点,将它跟其他红色节点隔开。
  • 红黑树中包含最多黑色节点的路径不会超过 l o g 2 n log_2n log2n,所以加入红色节点之后,最长路径不会超过 2 l o g 2 n 2log_2n 2log2n,也就是说,红黑树的高度近似 2 l o g 2 n 2log_2n 2log2n

所以,红黑树的高度只比高度平衡的AVL树的高度 l o g 2 n log_2n log2n仅仅大了一倍,在性能上,下降的并不多。这样推导出来的结果不够精确,实际上红黑树的性能更好。

为什么工程中都用红黑树这种二叉树?

平衡二叉查找树其实有很多,比如,Splay Tree(伸展树)、Treap(树堆)等,但是我们提到平衡二叉查找树,听到的基本都是红黑树。它的出镜率甚至要高于“平衡二叉查找树”这几个字,有时候,我们甚至默认平衡二叉查找树就是红黑树,那为什么工程中都喜欢用红黑树,而不是其他平衡二叉查找树呢?

  • 类似Treap、Splay Tree,绝大部分情况下,它们操作的效率都很高,但是也无法避免极端情况下时间复杂度的退化。尽管这种情况出现的概率不大,但是对于单次操作时间非常敏感的场景来说,它们并不适用
  • avl树是一种高度平衡的二叉树,所以查找的效率非常高。但是,有利就有弊,avl树为了维持这种高度的平衡,需要付出更多的代价。每次插入、删除都要做调整,就比较复杂、耗时。所以,对于有频繁的插入、删除操作的数据集合,使用avl树的代价就有些高了
  • 红黑树只是做到了近似平衡,并不是严格的平衡,所以在维护平衡的成本上,要比avl树要低。

所以,红黑树的插入、删除、查找各种操作性能都比较稳定。对于工程应用来说,要面对各种异常情况,为了支撑这种工业级的应用,我们更倾向于这种性能稳定的平衡二叉查找树

小结我们学习数据结构和算法,要学习它的由来、特性、适用的场

红黑树它算是最难掌握的一种数据结构。不过呢,我认为,我们其实不应该把学习的侧重点,放到它的实现上。我们学习数据结构和算法,要学习它的由来、特性、适用的场景以及它能解决的问题。对于红黑树,也不例外。你如果能搞懂这几个问题,其实就已经足够了。

  • 红黑树是一种平衡二叉查找树,它是为了解决普通二叉查找树在数据更新的过程中,复杂度退化的问题而产生的。红黑树的高度近似 l o g 2 n log_2n log2n,所以它是近似平衡,插入、删除、查找操作的时间复杂度都是O(logn)
  • 因为红黑树是一种性能非常稳定的二叉查找树,所以,在工程中,但凡是用到动态插入、删除、查找数据的场景,都可以用到它。不过,它实现起来比较复杂,如果自己写代码实现,难度会有些高。这个时候,我们其实更倾向于用跳表替代它

所谓的动态数据结构是什么意思:

  • 动态数据结构是支持动态的更新操作,里面存储的数据是时刻在变化的,通俗的一点讲,它不仅仅支持动态查询,还支持删除、插入数据。而且这些操作都非常高效。如果不高兴,也就是算不上有效的动态数据结构了
  • 所以,这里的红黑树算一个,支持动态的插入、删除、查找,而且效率都很高。链表、队列、栈实际上算不上,因为操作非常有限,查询效率不高。
  • 跳表,跳表也支持动态插入,删除,查询,也很快,不同点是跳表还能支持快速的范围查询。除此之外,跳表还支持多写多读,而红黑树不可以,这些场景下显然用跳表合适。

面试题

红黑树 VS 二叉平衡树

  • 二叉平衡树有可能导致斜树,为此引入了红黑树,红黑树通过选择自己保持大致平衡

参考

红黑树
面经手册 · 第6篇《带着面试题学习红黑树操作原理,解析什么时候染色、怎么进行旋转、与2-3树有什么关联》


http://chatgpt.dhexx.cn/article/0qvjIUfX.shtml

相关文章

pygraphviz的安装与红黑树可视化

大家好,我是小小明,今天我将带大家安装pygraphviz,并通过它对红黑树这种数据结构进行可视化。 pygraphviz的安装与红黑树的可视化 安装graphviz 下载地址:http://www.graphviz.org/download/ windows平台下可以选择&#xff1…

到底什么是红黑树?

到底什么是红黑树? 首先,可以这么简单粗暴的理解,红黑树≈平衡的二叉排序树。 那么很显然,要想弄懂红黑树,得先明白什么是树、二叉树、二叉排序树、平衡树以及不平衡树。下面我们一个个来了解。 1.第一个问题&#x…

面试常问:什么是红黑树?

什么是红黑树? ———————————— 二叉查找树(BST)具备什么特性呢? 1.左子树上所有结点的值均小于或等于它的根结点的值。 2.右子树上所有结点的值均大于或等于它的根结点的值。 3.左、右子树也分别为二叉排序树。 下图…

红黑树简介

一、什么是红黑树 红黑树(Red Black Tree) 是一种自平衡二叉查找树,是在计算机科学中用到的一种数据结构,典型的用途是实现关联数组。 红黑树是在1972年由Rudolf Bayer发明的,当时被称为平衡二叉B树(symme…

什么是红黑树?

一、红黑树的产生 1.二叉树 定义:二叉树(binary tree)是指树中节点的度不大于2的有序树,它是一种最简单且最重要的树。二叉树的递归定义为:二叉树是一棵空树,或者是一棵由一个根节点和两棵互不相交的&…

说说什么是红黑树?

分析&回答 红黑树介绍 R-B Tree,全称是Red-Black Tree,又称为“红黑树”,红黑树就是一种平衡的二叉查找树,说他平衡的意思是他不会变成“瘸子”,左腿特别长或者右腿特别长。除了符合二叉查找树的特性之外&#xf…

漫画:什么是红黑树?(整合版)

前段时间,小灰发布了红黑树相关的文章,分成上下篇来讲解。 这一次,小灰把两篇文章做了整合,并且修正了红黑树删除部分的图片错误,感谢大家的指正。 ————— 第二天 ————— ———————————— 二叉查找…

抗性基因数据库CARD介绍

随着抗生素药物的发现及使用,越来越多的耐药菌株由此产生。而耐药菌株的发展则会增加疾病治疗的难度和成本,因此耐药微生物的研究则显得尤为重要。目前,通过对耐药基因的鉴定挖掘能够一定程度上帮助我们揭开耐药机制,为疾病的治疗…

关于 GIL

目录 GIL是什么GIL产生的原因如何避免受到GIL的影响什么时候会释放GIL锁互斥锁和Gil锁的关系 参考链接 python中的GIL详解 python面试不得不知道的点——GIL 《Python面试每日一题》之GIL Python GIL 是功能和性能之间权衡后的产物,它尤其存在的合理性&#xff0…

gin介绍

Gin的介绍与应用 Gin是一个golang的web框架,Gin像是一些常用函数或者工具的集合。具有快速灵活,容错方便等特点。Gin自身的net/http足够简单,性能也非常不错。 Gin的官网:https://github.com/gin-gonic/gin 安装前保证git和go都安…

gin_gorm

一、使用形式 1、引入gorm包 import "github.com/jinzhu/gorm" 2、导入数据库驱动 import _ "github.com/go-sql-driver/mysql"为了方便记住导入路径,GORM包装了一些驱动: import _ "github.com/jinzhu/gorm/dialects/mysq…

【GIC】配置GIC

本章介绍如何在裸机环境中启用和配置兼容GICv3的中断控制器。 目录 一、全局设置 二、单独PE设置 2.1 Redistributor配置 2.2 CPU接口配置 2.3 PE配置 三、SPI, PPI, SGI配置 3.1设置SPI的目标PE 附:寄存器介绍 附1:GICD_CTLR 附2:…

大寰AG-95夹爪指尖更换、结构示意图及通讯协议转换器说明

注意: 在对手爪进行任何操作之前,请先关闭机器人和夹持电源。 大寰AG-95夹爪指尖更换更换步骤: 1. 使用 M3 内六角螺丝刀卸下指尖螺丝,拆卸磨损的指尖。 2. 清洁手指件并彻底擦干。 3. 取出指尖上φ3x6 mm 定位销。 4. 将…

使用Landsat系列数据来检测喜马拉雅地区的冰湖溃决(Georg Veha等人,RSE,2018)

一、背景 这是一篇做冰湖溃决的文章,作者主要使用了random forest来检测喜马拉雅地区的冰湖溃决现象,这项成果发表在了Remote Sensing of Environment上。 文献连接:https://doi.org/10.1016/j.rse.2017.12.025 文献引用:Georg Ve…

App设计灵感之十二组精美的智能家居App设计案例

通过手机远程启动家里的各种家用电器,让我们回到家后可以享受到舒适的环境,这便是智能家居给我们带来的便利。 ① Smart Hub Application design by Ariuka ② Smart Home by Srgi Mi ③ Smart Home Mobile App by Ghulam Rasool ④ Smart Home Mobile …

基恩士KV8000通过HT3S-EIS-MDN网关与大寰机器人交换数据

一、概述 本文主要介绍使用HI-TOP网关 HT3S-EIS-MDN在基恩士KV8000 PLC和大寰RGI系列旋转抓手之间进行数据交换。 解决的问题:基恩士PLC KV8000监控和大寰RGI系列旋转抓手。 解决方法:使用HI-TOP网关 HT3S-EIS-MDN。基恩士KV8000支持EthterNet/IP协议…

CARD耐药数据库Linux使用

一、背景 关于耐药性有很多数据库可以使用,但是CARD的优势在于数据库较为准确,只有经过文章进行验证后的基因才会被记录 二、软件链接 软件github: GitHub - arpcard/rgi: Resistance Gene Identifier (RGI). Software to predict resistomes from p…

(原创)用红黄蓝RYB色相环(伊登色相环)代替RGB(RGI/RGV)色相环

作者:❄️固态二氧化碳❄️ (主页) 链接:(原创)用红黄蓝RYB色相环(伊登色相环)代替RGB(RGI/RGV)色相环 - 固态二氧化碳的博客 - CSDN博客 来源:CSDN博客 发表时间:2019年05月28日 12:33:57 著作权归作者所有。商业转载请联系作者获…

APT、ET、RGI、ICQ

越来越大的屏幕尺寸和越来越多的需要显示屏常亮应用,要求手机厂商必须从各个方向考虑来提升电池续航时间。一般而言,手机上常用的有两种 PA 的省电技术,一种是平均功率跟踪技术(APT),另外一种是包络跟踪&am…