【算法】最容易懂得的红黑树

news2024/9/17 8:27:12

红黑树是一个平衡的二叉树,但不是一个完美的平衡二叉树。虽然我们希望一个所有查找都能在~lgN次比较内结束,但是这样在动态插入中保持树的完美平衡代价太高,所以,我们稍微放松逛一下限制,希望找到一个能在对数时间内完成查找的数据结构。这个时候,红黑树站了出来。 
阅读以下需要了解普通二叉树的插入以及删除操作。 
红黑树是在普通二叉树上,对没个节点添加一个颜色属性形成的,同时整个红黑二叉树需要同时满足一下五条性质 
红黑树需要满足的五条性质: 
性质一:节点是红色或者是黑色; 
在树里面的节点不是红色的就是黑色的,没有其他颜色,要不怎么叫红黑树呢,是吧。 
性质二:根节点是黑色; 
根节点总是黑色的。它不能为红。 
性质三:每个叶节点(NIL或空节点)是黑色; 
这个可能有点理解困难,可以看图:

这个图片就是一个红黑树,NIL节点是个空节点,并且是黑色的。 
性质四:每个红色节点的两个子节点都是黑色的(也就是说不存在两个连续的红色节点); 
就是连续的两个节点不能是连续的红色,连续的两个节点的意思就是父节点与子节点不能是连续的红色。

**性质五:从任一节点到其没个叶节点的所有路径都包含相同数目的黑色节点;**
还是看图:

从根节点到每一个NIL节点的路径中,都包含了相同数量的黑色节点。 
这五条性质约束了红黑树,可以通过数学证明来证明,满足这五条性质的二叉树可以将查找删除维持在对数时间内。 
当我们进行插入或者删除操作时所作的一切操作都是为了调整树使之符合这五条性质。 
下面我们先介绍两个基本操作,旋转。 
旋转的目的是将节点多的一支出让节点给另一个节点少的一支,旋转操作在插入和删除操作中经常会用到,所以要熟记。

下面是左旋和右旋:
左旋:

右旋: 

下面讲讲插入

我们先明确一下各节点的叫法

因为要满足红黑树的这五条性质,如果我们插入的是黑色节点,那就违反了性质五,需要进行大规模调整,如果我们插入的是红色节点,那就只有在要插入节点的父节点也是红色的时候违反性质四或者是当插入的节点是根节点时,违反性质二,所以,我们把要插入的节点的颜色变成红色。

下面是可能遇到的插入的几种状况: 
1、当插入的节点是根节点时,直接涂黑即可; 
2、当要插入的节点的父节点是黑色的时候。

这个时候插入一个红色的节点并没有对这五个性质产生破坏。所以直接插入不用在进行调整操作。

3、如果要插入的节点的父节点是红色且父节点是祖父节点的左支的时候。 
这个要分两种情况,一种是叔叔节点为黑的情况,一种是叔叔节点为红的情况。 
当叔叔为黑时,也分为两种情况,一种是要插入的节点是父节点的左支,另一种是要插入的节点是父亲的右支。 
我们先看一下当要插入的节点是父节点的左支的情况:

这个时候违反了性质四,我们就需要进行调整操作,使之符合性质四,我们可以通过对祖父节点进行右旋同时将祖父节点和父节点的颜色进行互换,这样就变成了:

经过这样的调整可以符合性质四并且不对其他性质产生破坏。 
当插入的节点是父节点的右支的时候:

当要插入的节点是父节点的右支的时候,我们可以先对父节点进行左旋,变成如下:

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

4、如果要插入的节点的父节点是红色且父节点是祖父节点的右支的时候; 
这个时候的情况跟情况3所表述的情况是一个镜像,将情况3的左和右互换一下就可以了。 
5、如果要插入的节点的父节点是红色并且叔叔节点也为红色,如下:

这个时候,只需将父亲节点和叔叔节点涂黑,将祖父节点涂红。

以上就是插入的全部过程。 
下面我们再讲讲删除的操作:

首先你要了解普通二叉树的删除操作: 
1.如果删除的是叶节点,可以直接删除; 
2.如果被删除的元素有一个子节点,可以将子节点直接移到被删除元素的位置; 
3.如果有两个子节点,这时候就可以把被删除元素的右支的最小节点(被删除元素右支的最左边的节点)和被删除元素互换,我们把被删除元素右支的最左边的节点称之为后继节点(后继元素),然后在根据情况1或者情况2进行操作。如图:

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

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

我们下面所称的被删除元素,皆是指已经互换之后的被删除元素。 
加入颜色之后,被删除元素和后继元素互换只是值得互换,并不互换颜色,这个要注意。

下面开始讲一下红黑树删除的规则: 
1.当被删除元素为红时,对五条性质没有什么影响,直接删除。 
2.当被删除元素为黑且为根节点时,直接删除。 
3.当被删除元素为黑,且有一个右子节点为红时,将右子节点涂黑放到被删除元素的位置,如图: 

变成

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

变成:

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

变成:

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

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

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

7.当被删除元素为黑且为父元素的右支时,跟情况5.情况6 互为镜像。 
8.被删除元素为黑且兄弟节点为黑,兄弟节点的孩子为黑,父亲为黑,这个时候需要将兄弟节点变为红,再把父亲看做那个被删除的元素(只是看做,实际上不删除),看看父亲符和哪一条删除规则,进行处理变化如图: 
由:

变成:

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

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

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

 

好了,删除的步骤也讲完,没有讲到的一点就是,在添加删除的时候,时刻要记得更改根元素的颜色为黑。 
这里并没有语言实现,只是讲了一下红黑树的插入删除步骤,你可以根据步骤自己把红黑树实现。

点击这里,照着规则一步一步的构建一个红黑树吧。

最后: 
1.红黑树的实现其实是一个2、3、4树,只是将双节点或者三节点用红色进行了标示,如果你将红色节点放到和它父元素相同的高度,并把它和父元素看做是一个元素,你就会发现,变成了一个高度为lgN的二叉树,这个2.3.4树对红黑树很有启发意义。 
2.上面的步骤其实可以不用死记硬背,是可以推导出来的,因为我们是把一个平衡但通过插入或者删除破坏了平衡的红黑树再次平衡,同过旋转让位,改变红黑颜 色,使之符合那五条基本性质。比如遇到删除操作情况四的时候,我们可以把那个删除元素去除,发现左边比右边少一个黑元素,这个时候,怎么办,我们发现兄弟 节点的子元素有一个红元素,操作这个不会影响那五条性质,所以我们通过变换颜色,旋转,即可让左右两边的的黑色数目一样。 
3.旋转操作的目的是出让一个元素到另外的地方并且符合二叉树左小右大的性质,交换颜色的目的是为了保持红黑树的那五条性质。 
4.要时刻记得 ,一切的操作都是为了保持那五条性质。

最后的最后,其实还有一种更为简单的红黑二叉树,这个简单的红黑二叉树实际上是一个2.3树,他只允许左节点为红节点,但是性能上肯定是不如这个红黑树。这个简单的红黑二叉树在《算法》第四版有介绍,掌握完之后再看这个简单的红黑二叉树,就会觉着简单 easy。 
最后的最后的最后,一定要尝试着自己推导一下插入删除规则啊,不然经常忘,是睡一觉起来再看就有点懵逼的那种忘。

RBT 操作动画:https://www.cs.usfca.edu/~galles/visualization/RedBlack.html

https://www.cs.usfca.edu/~galles/visualization/Algorithms.html

https://www.jianshu.com/p/e136ec79235c
 

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

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

相关文章

【iOS】AVPlayer 视频播放

视频播放器的类别 iOS开发中不可避免地会遇到音视频播放方面的需求。 常用的音频播放器有 AVAudioPlayer、AVPlayer 等。不同的是,AVAudioPlayer 只支持本地音频的播放,而 AVPlayer 既支持本地音频播放,也支持网络音频播放。 常用的视频播放…

python学习——【第八弹】

前言 上篇文章 python学习——【第七弹】学习了python中的可变序列集合,自此python中的序列的学习就完成啦,这篇文章开始学习python中的函数。 函数 在学习其他编程语言的时候我们就了解过函数:函数就是执行特定任何以完成特定功能的一段代…

【JWT】token jwt-跨域认证的问题、JWT 的原理、java JWT实用案例

本文是向大家介绍token JWT的相关学习,它能够实现登录认证功能的实现,了解它能够让我们对系统有更加全面系统的理解 JSON Web Token(缩写 JWT)是目前最流行的跨域认证解决方案,本文介绍它的原理和用法。 一、跨域认证的问题 互联…

动态组件、keep-alive的使用及自定义指令

目录 1. 动态组件 2.如何实现动态组件渲染 3. 使用keep-alive保持状态 4. keep-alive对应的生命周期函数 5. keep-alive的include属性 自定义指令 1.什么是自定义指令 2. 自定义指令的分类 3. 私有自定义指令 4. update函数 5. 函数简写 全局自定义指令: …

媒体沟通会 | 云擎未来 智信天下:移动云大会终极预告

4月24日,“云擎未来 智信天下”2023移动云大会媒体沟通会在苏州举办,百余家主流新闻媒体参会。在媒体沟通会现场,中国移动云能力中心副总经理吴世俊致欢迎词,市场部副总经理吴炯详细介绍了移动云大会盛况,并透露在本届…

三问 ThreadLocal —— 有什么用 ? 使用时有什么潜在风险?原理 ?

最近想实现一些功能,求诸于网络之后,得到了使用 ThreadLocal 实现的方式,那么 ThreadLocal 到底是什么呢 ? 遂写此文,抽丝剥茧的来看一下这个 Java 并发类 。 最近,me 的 gpt 账号没了,所以不能…

【模板】Hexo Docker Nginx 个人博客服务器部署

上文:基于 Hexo 的 Github 博客搭建 注意:通过验证部署,确定无误。AI生成的部分有🤖图标。 🤖 TLDR By ChatGPT 本指南提供了在服务器上设置Git仓库、将本地Hexo页面推送到服务器仓库、在服务器上创建Nginx配置文件以…

数字信封例程不支持的bug,以及卸载安装配置Node.js

文章目录 前言一、运行错误:0308010C:数字信封例程:不支持二、卸载Node.js三、重新安装Node.js总结 前言 下载了若依项目,但是在前端项目运行打包都出现了bug。最后,卸载了Node.js,并重新安装了低版本的Node.js。 一、运行错误:0308010C:数字…

[算法前沿]--003-AGI通用人工智能模型对安全的影响和开源的大模型

文章目录 0.ChatGPT大模型带来的影响0.1 ChatGPT带来信息化革命性创新,目前尚不能处理专业知识但成长很快0.2 Chat GPT为网安行业带来新的创新方向,也将引领新一轮投融资热潮0.2.1 攻击方发起网络攻击的门槛降低0.2.2 防守方合理使用ChatGPT可大幅减少安…

组态王与PLC之间1主多从自组网无线通信

本方案是基于三菱专用协议下实现的1主多从自组网无线通信形式,主站为组态王,从站为三菱FX3U PLC和485BD扩展。采用日系PLC专用无线通讯终端DTD435MC-V96,作为实现无线通讯的硬件设备,来解决组态王与PLC之间的通讯问题。 一、方案…

百度AI模型“文心一言”新鲜体验

今天收到通知可以体验百度的AI模型“文心一言”,等了一个多月迫不及待的去体验了一把,以下是体验的相关记录。 1、简单介绍 通过文心一言官网链接https://yiyan.baidu.com/进入,看到如下界面: 在文心一言的自我介绍中&#xff0c…

seetaface6 GPU版本windows编译

目录 1. seetaface6概述2. 编译说明2.1 编译工具2.2 编译顺序 3. 编译OpenRoleZoo4. 编译SeetaAuthorize5. 编译TenniS6. 编译FaceTracker6 1. seetaface6概述 seetaface6源码以及模型文件github下载路径:https://github.com/SeetaFace6Open/index 由于项目性能需求…

华为为何要搞相对冷门的ERP?

大家都知道华为的研发实力很强,但几天前他们宣布研发出超大规模云原生的ERP时,还是有些吃惊。 20日,在东莞的一场“英雄强渡大渡河”表彰会上,华为抛出一个大多数公司都难以做到的成果:三年时间,数千人&am…

从零开始写ChatGLM大模型的微调代码

cursor 的下载及安装(免费版每月100次,升级pro 20刀/月) cursor是一款与openai合作的,使用gpt-4的一款编程工具,它可以让你通过gpt-4进行辅助编程,以此提高效率。 下载地址:https://www.curso…

CentOS系统安装Intel E810 25G网卡驱动

因特尔网卡驱动给的都是二进制包,需要编译环境。 首先去Intel下载最新的驱动 E810驱动下载:https://www.intel.com/content/www/us/en/download/19630/intel-network-adapter-driver-for-e810-series-devices-under-linux.html?wapkwe810 里面有三个驱…

量子计算新进展!瑞典和芬兰率先研发芯片

(图片来源:网络) 芬兰和瑞典在北欧率先推出了独立的量子计算机项目,并在未来量子技术方面取得了可喜的新进展。 在瑞典,查尔姆斯理工大学 (Chalmers UoT) 获得了追加的900万欧元(约合6774万元人民币&#x…

风力发电系统的随机调度研究(matlab代码实现)

💥💥💞💞欢迎来到本博客❤️❤️💥💥 🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。 ⛳️座右铭&a…

【神经网络】tensorflow实验8--梯度下降法

1. 实验目的 ①掌握TensorFlow的可训练变量和自动求导机制 ②能够使用TensorFlow实现梯度下降法,求解一元和多元线性回归问题 2. 实验内容 下载波士顿房价数据集,使用线性回归模型实现对波士顿房价的预测,并以可视化的形式输出模型训练的过…

【Git】—— 版本控制(忽略文件、查看修改内容,撤销未提交的修改、查看历史提交记录)

目录 一、准备工作 二、忽略文件 三、查看修改内容 四、撤销未提交的修改 五、查看提交记录 前面学习了Git最基本的用法,包括安装Git、创建代码仓库以及提交本地代码。 下面将要学习版本控制。 一、准备工作 先选择一个项目,给它创建一个代码仓库&a…

Linux环境定时备份MySQL数据库

数据库备份常有,实现备份,大概需要3个步骤: 目录 1.创建数据库备份用户 2.创建数据库备份shell脚本 3.创建定时任务 1.创建数据库备份用户 为了数据安全,不建议使用root用户。举例:创建数据库备份用户 dump&#…