【数据结构】什么是红黑树(Red Black Tree)?

news2024/11/15 6:05:22

🦄个人主页:修修修也

🎏所属专栏:数据结构

⚙️操作环境:Visual Studio 2022


目录

📌红黑树的概念

📌红黑树的操作

🎏红黑树的插入操作

🎏红黑树的删除操作

结语


📌红黑树的概念

        我们之前学过了二叉搜索树和平衡二叉搜索(AVL)树, 除了它们, 还有一个被广泛运用的平衡二叉搜索树是红黑树(RB-Tree)

        红黑树是一种平衡二叉搜索树的变体, 它的左右子树高差有可能大于 1,所以红黑树不是严格意义上的平衡二叉搜索树(AVL),但对之进行平衡的代价较低, 其平均统计性能要强于 AVL 。

        红黑树在每个结点上增加一个存储位表示结点的颜色,可以是Red或Black。 通过对任何一条从根到叶子的路径上各个结点着色方式的限制,红黑树确保没有一条路径会比其他路径长出俩倍,因而是接近平衡的。

        红黑树的规则如下:

  1. 每个结点不是红色就是黑色
  2. 根结点是黑色
  3. 如果一个结点是红色的,则它的子结点一定是黑色
  4. 任一结点到NULL(树尾)的任何路径上,所含的黑色结点数一定相同
  5. 每个NULL(树尾)空结点都是黑色的

        依照红黑树的规则,红黑树能确保没有一条路径会比其他路径长出俩倍的原因是:

        因此假设所有路径的黑节点数是n,那么最短路径的长度为n,而最长路径的长度为2n-1.

        红黑树和AVL树的效率差异:

        因为AVL树是较严格的平衡二叉搜索树,因此当数据量为n时,它的查询效率最坏大概在log_{2}n。而对于红黑树来讲,假设它的最短路径层高和AVL树的层高一样,那它的最坏查询效率大概就在2log_{2}n。虽然略逊AVL树,但两者的效率仍然处于一个量级,即使有10亿数据,AVL树的查询次数在30次左右,而红黑树的查询次数在60次左右,差距不是很大,但是在插入时红黑树对于AVL树的消耗却少了不少,因此STL库中set和map的底层都是通过封装红黑树实现的.


📌红黑树的操作

🎏红黑树的插入操作

        我们同样以一组数据为例, 在模拟红黑树插入的过程中学习红黑树对于插入结点的处理方法

        在此之前,我们需要先搞清楚一个问题, 那就是每个结点都有颜色,或红色或黑色,那么新插入的结点应该是红色还是黑色呢?答案是, 必须是红色!

        我们简单分析一下插入新结点的情况, 假设我们现在需要给下面这颗红黑树中插入一个新结点7:

        我们先来看看如果这个结点为黑节点的情况:

        给大家举一个例子, 想来大家或多或少都有听说过或者经历过被人催婚的经历, 有一个很有趣的现象, 不知道大家有没有观察到, 那就是催婚的力度, 和年龄的关系不是很大,但是和同辈人有没有结婚生子关系非常大,也就是说,当家里亲戚里同辈人都没有结婚生子时,催婚的力度可能就是"天街小雨润如酥"。但是一旦同辈人中有人已经结婚生子了,那催婚的力度可就是"涧底松摇千尺雨"了。

        上图中新插入黑节点的行为就像是第一个结婚生子的同辈人,明明同辈人大家一起在坚守战线, 但是他却叛变了, 这下剩下所有的结点的平衡都因为它而打破, 破坏力简直是毁灭级的, 所以我们新插入的结点一定不能是黑色的。

        那假如我们插入的新节点是红结点呢?

        我们可以看到,如果插入的红结点父亲是黑节点,那么红结点的插入就不会破坏任何红黑树的规则, 这就相当于同辈人没有直接结婚生子,而只是谈了一个男/女朋友,并不会真正影响到平衡的格局, 只是偶尔会遇到父节点也是红结点的情况,这个时候我们按后面学到的处理方法将他们处理一下就可以.

        如果我们遇到了插入后违反红黑树规则的情况,那么红黑树的调整规则如下:

  1. 插入结点是根节点(即破坏了根节点是黑色的规则)--->解决方法,直接将该节点变黑
  2. 插入结点的父节点也是红色(即破坏了红结点的孩子必须是黑色的规则),分两种情况
  • 插入结点的叔叔结点是红色: 将叔叔和父亲变为黑色, 爷爷结点变为红色, 然后继续向上判定爷爷结点是否违反了红黑树的规则并进行调整
  • 插入结点的叔叔结点不存在或是黑色: 根据形态进行相应的旋转操作,旋转完成后,将旋转后的根节点变黑,将祖父结点变红即可

         接下来我们就一起按照这组数据来模拟红黑树的插入过程:

17 18 23 34 27 15 9 6 8 5 25 

         首先插入第一个结点17:

        可以看到,插入根节点时,我们违反了根结点为黑的性质,解决办法也很简单,把根节点变黑就行:

        继续插入下一个结点18:

        插入后没有破坏红黑树的任何性质,继续插入

         插入下一个结点23:

        此时违反了红黑树不能有两个连续红结点的性质,并且对新插入的结点23来讲,它的叔叔结点不存在,因此我们考虑使用旋转来解决,观察发现此时是RR型的旋转,因此我们通过左旋来解决:

        左旋之后,我们需要将新的父亲结点变为黑色,原来的爷爷结点变为红色就完成了:

        继续插入下一个结点34:

        此时违反了红黑树不能有两个连续红结点的性质,并且对新插入的结点34来讲,它的叔叔结点是红色的,因此我们需要对将父亲叔叔变为黑色,爷爷变为红色:

        然后继续将爷爷结点18作为新插入结点继续向上判定,发现他不符合根结点是黑色结点的性质,因此我们将根节点18变为黑色即可:

        向上判定到了根节点就结束了, 我们继续插入下一个结点.

        继续插入下一个结点27:

        发现此时新插入结点27和它的父亲结点34违反了不能有两个相同红结点的规则,通过观察,我们发现他没有叔叔结点, 又因为是RL型,因此我们选择右左双旋来解决这个问题:

        旋转好后,再对旋转后的根节点27和祖父结点23进行变色:

        变色完成,我们的红黑树也就插入成功了.

        继续插入下一个结点15:

        发现并没有破坏红黑树的任何性质, 继续插入下一个结点.

        继续插入下一个结点9:

        发现新插入的9和其父亲结点15违反了不能有两个连续红结点的性质,同时其叔叔结点也不存在,通过观察是LL型旋转,因此我们选择右旋来解决这个问题:

        右旋完成后,我们更改旋转后的根节点15和爷爷结点17进行变色,就调整好了:

        继续插入下一个结点6:

        发现新插入的6和其父亲结点9违反了不能有两个连续红结点的性质,同时其叔叔是红色,因此我们选择将父亲结点叔叔结点和爷爷结点变色来解决这个问题:

        变色完成后,我们继续判断爷爷结点是否有违反红黑树的性质,发现没有,插入完成.

        继续插入下一个结点8:

        发现新插入的8和其父亲结点6违反了不能有两个连续红结点的性质,同时其叔叔结点也不存在,通过观察是LR型旋转,因此我们选择左右双旋来解决这个问题:

        旋转完成后,我们再对旋转后的根节点8,和爷爷结点9进行变色, 既可完成插入:

        继续插入下一个结点5:

        发现新插入的5和其父亲结点6违反了不能有两个连续红结点的性质,同时其叔叔是红色,因此我们选择将父亲结点叔叔结点和爷爷结点变色来解决这个问题:

        变色完成后,我们继续判断爷爷结点8是否有违反红黑树的性质,发现结点8和其父亲结点15违反了不能有两个连续红结点的性质,同时其叔叔结点27是黑色,通过观察是LL型旋转,因此我们选择右旋来解决这个问题:

        右旋完成后,我们更改旋转后的根节点15和爷爷结点18进行变色,就调整好了:

        继续插入最后一个结点25:

        发现新插入的25和其父亲结点23违反了不能有两个连续红结点的性质,同时其叔叔34是红色,因此我们选择将父亲结点叔叔结点和爷爷结点变色来解决这个问题:

        变色之后,继续判断爷爷结点27是否违反红黑树性质,发现结点27和它的父亲结点18违反了不能有两个连续红结点的性质,同时其叔叔结点8是红色,因此我们选择将父亲结点18叔叔结点8和爷爷结点15变色来解决这个问题:

        变色之后,继续判断新的爷爷结点15是否违反红黑树性质,发现他违反了根节点必须为黑的性质,因此我们将他变黑,又因为已经判断到根节点, 插入操作完成.

        将所有元素插入进红黑树后,我们显示出所有的空结点,验证红黑树的性质,发现是符合红黑树的性质的:


🎏红黑树的删除操作

        红黑树和AVL树一样,都是要在二叉搜索树的删除插入基础上然后保持其树本身的特性.

红黑树的删除难点主要在于删除叶子黑节点

        因为有孩子结点时我们只需要按二叉搜索树的逻辑让孩子结点代替它,并让孩子结点变黑即可。

        对于叶子红结点呢,因为删除它不会影响任何红黑树的性质,所以直接删除即可, 但是对于删除叶子黑节点就非常复杂,我放一张红黑树的删除操作逻辑图和二叉搜索树的删除逻辑在这里,有兴趣的朋友可以参考研究一下,这里就不详细展开了:



结语

希望这篇关于 红黑树(RB-Tree) 的博客能对大家有所帮助,欢迎大佬们留言或私信与我交流.

学海漫浩浩,我亦苦作舟!关注我,大家一起学习,一起进步!

相关文章推荐

【数据结构】什么是平衡二叉搜索树(AVL Tree)?

【C++】STL标准模板库容器map

【C++】STL标准模板库容器set

【C++】模拟实现二叉搜索(排序)树

【数据结构】C语言实现链式二叉树(附完整运行代码)

【数据结构】什么是二叉搜索(排序)树?

【C++】模拟实现priority_queue(优先级队列)

【C++】模拟实现queue

【C++】模拟实现stack

【C++】模拟实现list

【C++】模拟实现vector

【C++】标准库类型vector

【C++】模拟实现string类

【C++】标准库类型string

【C++】构建第一个C++类:Date类

【C++】类的六大默认成员函数及其特性(万字详解)

【C++】什么是类与对象?


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2185411.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

资源《Arduino 扩展板3-WS2812》说明。

资源链接: Arduino 扩展板3-WS2812 1.文件明细: 2.文件内容说明 包含:AD工程、原理图、PCB。 3.内容展示 4.简述 该文件为PCB工程,采用AD做的。 该文件打板后配合Arduino使用,属于Arduino的扩展板。 该文件主要…

通义千问“百宝箱”:效率神器,解放你的双手!

你在为播客转文字、音视频转写和长文本阅读而烦恼吗?今天,就让通义千问的“百宝箱”来帮你解决这些难题! 最近,我发现通义千问首页隐藏着一个效率神器——“百宝箱”(现在更名为工具箱),简直是…

batch和momentum

🚀 机器学习系列前期回顾 1、初识机器学习 2、线性模型到神经网络 3、local minima的问题如何解决 🚀在初识机器学习中,了解了机器学习是如何工作的并引入了线性模型,在线性模型到神经网络这节,将线性模型进一步改进为…

FireRedTTS - 小红书最新开源AI语音克隆合成系统 免训练一键音频克隆 本地一键整合包下载

小红书技术团队FireRed最近推出了一款名为FireRedTTS的先进语音合成系统,该系统能够基于少量参考音频快速模仿任意音色和说话风格,实现独特的音频内容创造。 FireRedTTS 只需要给定文本和几秒钟参考音频,无需训练,就可模仿任意音色…

【Golang】关于Go语言字符串转换strconv

✨✨ 欢迎大家来到景天科技苑✨✨ 🎈🎈 养成好习惯,先赞后看哦~🎈🎈 🏆 作者简介:景天科技苑 🏆《头衔》:大厂架构师,华为云开发者社区专家博主,…

ProtoBuf快速上手

文章目录 创建 .proto文件编译 .proto文件编译后生成的文件序列化与反序列化的使用 此篇文章实现内容: 对一个通讯录的联系人信息,使用PB进行序列化,并将结果输出对序列化的内容使用PB进行反序列化,解析联系人信息并输出联系人信…

【成神之路】Ambari实战-015-代码生命周期-metainfo-category详解

1.Redis 集群 metainfo.xml 示例 <?xml version"1.0"?> <metainfo><schemaVersion>2.0</schemaVersion><services><service><!-- Redis 集群服务的基本信息 --><name>REDIS</name><displayName>Redi…

MongoDB的安装与增删改查基本操作

MongoDB是一种非关系型数据库&#xff0c;是NoSQL语言&#xff0c;但是又是最接近关系型数据库的。内部存储不是表结构&#xff0c;但是可以对数据进行表结构的操作。 一、安装 在官网&#xff1a;Download MongoDB Community Server | MongoDB下载系统对应的版本进行安装即可…

html+css+js实现Collapse 折叠面板

实现效果&#xff1a; HTML部分 <div class"collapse"><ul><li><div class"header"><h4>一致性 Consistency</h4><span class"iconfont icon-jiantou"></span></div><div class"…

UFS 3.1架构简介

整个UFS协议栈可以分为三层:应用层(UFS Application Layer(UAP)),传输层(UFS Transport Layer(UTP)),链路层(UIC InterConnect Layer(UIC))。应用层发出SCSI命令(UFS没有自己的命令使用的是简化的SCSI命令),在传输层将SCSI分装为UPIU,再经过链路层将命令发送给Devices。下…

通信工程学习:什么是TCP传输控制协议

TCP&#xff1a;传输控制协议 TCP&#xff08;Transmission Control Protocol&#xff0c;传输控制协议&#xff09;是因特网协议套件中最重要的协议之一&#xff0c;它为应用程序提供了可靠、面向连接的通信服务。以下是TCP协议的详细解释&#xff1a; 一、TCP传输控制协议的…

双十一有哪些值得入手的好物?这五款宝藏好物不容错过!

在这个金秋送爽、收获满满的季节里&#xff0c;我们迎来了万众瞩目的双十一购物狂欢节。这不仅仅是一场简单的消费盛宴&#xff0c;更是每一位消费者期待已久、精心筹备的年度购物盛典。随着电商平台的不断革新与优惠力度的持续加码&#xff0c;双十一已经从一个简单的促销日成…

使用百度文心智能体创建多风格表情包设计助手

文章目录 一、智能定制&#xff0c;个性飞扬二、多元风格&#xff0c;创意无限 百度文心智能体平台为你开启。百度文心智能体平台&#xff0c;创建属于自己的智能体应用。百度文心智能体平台是百度旗下的智能AI平台&#xff0c;集成了先进的自然语言处理技术和人工智能技术&…

单目3d重建DUSt3R 笔记

目录 DUSt3R 三维重建 报错RecursionError: maximum recursion depth exceeded in comparison 报错 numpy.core.multiarray failed to import 报错Numpy is not available 解决 升级版mast3r 速度变慢 修改了参数设置脚本&#xff1a; 测试效果 操作技巧 DUSt3R 三维重…

[已解决] Install PyTorch 报错 —— OpenOccupancy 配环境

目录 关于 常见的初始化报错 环境推荐 torch, torchvision & torchaudio cudatoolkit 本地pip安装方法 关于 OpenOccupancy: 语义占用感知对于自动驾驶至关重要&#xff0c;因为自动驾驶汽车需要对3D城市结构进行细粒度感知。然而&#xff0c;现有的相关基准在城市场…

torchvision.transforms.Resize()的用法

今天我在使用torchvision.transforms.Resize()的时候发现&#xff0c;一般Resize中放的是size或者是(size,size)这样的二元数。 这两个里面&#xff0c;torchvision.transforms.Resize((size,size))&#xff0c;大家都很清楚&#xff0c;会将图像的h和w大小都变成size。 但是…

【python实操】python小程序之过七游戏以及单词单复数分类

引言 python小程序之过7游戏、单词单复数分类 文章目录 引言一、过7游戏1.1 题目1.2 代码1.2.1 while循环1.2.2 for循环1.2.3 调用函数形式 1.3 代码解释 二、单词单复数分类2.1 题目2.2 代码2.3 代码解释 三、思考3.1 过七游戏3.2 单词单复数分类 一、过7游戏 1.1 题目 7的倍…

大模型 LLaMA-Omni 低延迟高质量语音交互,开源!

最近这一两周看到不少互联网公司都已经开始秋招发放Offer。 不同以往的是&#xff0c;当前职场环境已不再是那个双向奔赴时代了。求职者在变多&#xff0c;HC 在变少&#xff0c;岗位要求还更高了。 最近&#xff0c;我们又陆续整理了很多大厂的面试题&#xff0c;帮助一些球…

python-patterns:Python 设计模式大全

python-patterns 是一个开源的 Python 项目&#xff0c;它提供了各种经典的设计模式的 Python 实现。设计模式是一种针对常见软件设计问题的可复用解决方案&#xff0c;通过使用设计模式&#xff0c;开发者可以编写出结构更加合理、易于维护和扩展的代码。 Python 是一门动态语…

GraphEval: A Knowledge-Graph Based LLM Hallucination Evaluation Framework

文章目录 题目摘要引言问题陈述相关工作GraphEval:我们的评估方法使用LLM构建知识GraphCorrect:使用GraphEval纠正幻觉实验讨论结论 题目 GraphEval:一个基于知识图的LLM幻觉评估框架 论文地址&#xff1a;https://arxiv.org/abs/2407.10793 摘要 评估大型语言模型(LLM)响应和…