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

红黑树是一个平衡的二叉树,但不是一个完美的平衡二叉树。虽然我们希望一个所有查找都能在~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
 

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

PS学习笔记(零基础PS学习教程)

很多新手学习PS不知从何下手,做设计的第一阶段肯定是打牢基础,把工具用熟练;本期特别为大家整理了PS入门的学习笔记,把每个工具的用法整理了下来,在使用过程中有哪里不清楚的可以翻看来看看~ 一、ps的工作界面的介绍 …

Python程序员想要转行,可以从这几个方面着手

最近有很多朋友问我一个问题,不论是我们做程序员还是做产品经理或者其他行业,到了30岁或35岁之后,都会面临各种各样的问题,比如达到职业天花板。有没有一种方法能够解决这种问题呢?我想分享一下我的观点和身边的案例。…

网络攻击与防御

1.什么是数据认证,有什么作用,有哪些实现的技术手段? 数字认证证书它是以数字证书为核心的加密技术可以对网络上传输的信息进行加密和解密、数字签名和签名验证,确保网上传递信息的安全性、完整性。 使用了数字证书,即使您发送的…

ChatGPT是什么?ChatGPT里的G、P、T分别指什么

文章目录 ChatGPT是什么GTP中的 生成式 是什么意思GTP中的 预训练 是什么意思GTP中的 变换模型 是什么意思 什么是Transformer什么是注意力机制 监督学Xi、无监督学Xi、强化学Xi ChatGPT是什么 GPT: Generative Pre-trained Transformer 生成式预训练变换模型 ChatGPT是由Ope…

用ChatGPT问DotNet的相关问题,发现DotNet工程师的前景还不错

本人最近费了九牛二虎之力注册了一个ChatGPT账号,现在就给大家分享一下,问一下关于.NET的问题,看看ChatGPT的AI功能具体如何? 一、C#跟其它语言比较的优势 回答: C#是一门编程语言,它是为 Microsoft 的 …

第十三章 移动和旋转(上)

移动和旋转是游戏对象最频繁地操作。我们上个章节简单介绍了Cube的移动和旋转。移动是修改transform的position属性,旋转是修改transform的eulerAngles(欧拉角)属性,两者属性值均可以使用Vector3向量来实现。需要大家注意的是&…

B/S 结构系统的 缓存机制(Cookie) 以及基于 cookie 机制实现 oa 十天免登录的功能

B/S 结构系统的 缓存机制(Cookie) 以及基于 cookie 机制实现 oa 十天免登录的功能 文章目录 B/S 结构系统的 缓存机制(Cookie) 以及基于 cookie 机制实现 oa 十天免登录的功能每博一文案1. Cookie 的概述2. session 与 Cookie 之间的联系:3. Cookie 的作用&#xff…

盈泰德带你了解产品表面缺陷检测系统

与前几年相比,机器视觉行业在表面检测方面有了很大的突破。检测产品表面的划痕、污渍不再困难,广泛应用于金属、玻璃、手机屏幕、液晶面板等行业的表面检测。 机器视觉检测有以下四种常用的检查和照明方法: 同轴照明、低角度照明、背光照明…

Python一行命令搭建HTTP服务器并外网访问 - 内网穿透

文章目录 1.前言2.本地http服务器搭建2.1.Python的安装和设置2.2.Python服务器设置和测试 3.cpolar的安装和注册3.1 Cpolar云端设置3.2 Cpolar本地设置 4.公网访问测试5.结语 转载自远程内网穿透的文章:【Python】快速简单搭建HTTP服务器并公网访问「cpolar内网穿透…

Java 基础进阶篇(五)—— 抽象类与模板方法设计模式

文章目录 一、抽象类、抽象方法概述二、抽象类的特征三、模板方法设计模式3.1使用场景3.2 实现步骤3.3 写作文案例 补充:final 和 abstract 是什么关系? 一、抽象类、抽象方法概述 在 Java 中 abstract 是抽象的意思,可以修饰类、成员方法。 abstract …

win10远程桌面控制Ubuntu服务器 - 内网穿透实现公网远程

文章目录 前言视频教程1. ubuntu安装XRDP2.局域网测试连接3. Ubuntu安装cpolar内网穿透4.cpolar公网地址测试访问5.固定域名公网地址 转载自远程穿透文章:Windows通过RDP异地远程桌面Ubuntu【内网穿透】 前言 XRDP是一种开源工具,它允许用户通过Windows…

机械硬盘(HDD)与固态硬盘(SSD)

目录 机械硬盘(HDD) 最小组成单元是扇区 硬盘结构 硬盘工作原理 硬盘上的数据组织 硬盘指标 影响性能的因素 固态硬盘(SSD) 最小存储单元是Cell SSD的特点 SSD架构 NAND Flash 闪存介质 地址映射管理 FTL闪存转换层 机械硬盘&…

JAVA IO 模型详解

什么是IO I/O(Input/Outpu) 即输入/输出 。 从计算机结构的视角来看的话, I/O 描述了计算机系统与外部设备之间通信的过程。 从应用程序的视角来看的话,我们的应用程序对操作系统的内核发起 IO 调用(系统调…

微信小程序定义模板

微信小程序提供模板(template)功能,把一些可以共用的,复用的代码在模板中定义为代码片段,然后在不同的地方调用,可以实现一次编写,多次引用的效果。 首先我们看一下官网是如何操作的 一般的情…

JavaWeb学习--RequestResponse

目录 JavaWeb学习--Request&Response 1,Request和Response的概述 request:获取请求数据 response:设置响应数据 **小结** 2,Request对象 **小结** 2.2 Request获取请求数据 **小结** 2.4 请求参数中文乱码问题 URL编码 2.5 Request请求转…

【前端技术】Vue3 01:初识 Vue.js

Vue 可以说是非常流行了,至少在国内是这样,他是个轻量级的 JavaScript 框架,非常适合构建大型和中小型的 Web 应用程序,如果想和前端打交道,应该绕不过这个框架吧。 目录 1 Vue.js 介绍 2 IDE 选择 2.1 vscode 2.…

Eplan 部件库导入部件的方法

1. 部件宏文件如何下载 1.1 西门子部件宏文件下载 EPLAN 的部件库是可以更新的,一般元器件厂商会提供其部件文件,以 SIEMENS 为例 进入网站,点击EPLAN 的图标 https://www.automation.siemens.com/bilddb/index.aspx?lang=en 在订货号中输入所需部件订货号,点击搜索。点…

【Java笔试强训 27】

🎉🎉🎉点进来你就是我的人了博主主页:🙈🙈🙈戳一戳,欢迎大佬指点! 欢迎志同道合的朋友一起加油喔🤺🤺🤺 目录 一、选择题 二、编程题 🔥 不用加…

sed编辑器基础命令

shell脚本编程系列 学习sed编辑器 sed编辑器被称作流编辑器(stream editor),与普通的交互式文本编辑器不同,在交互式文本编辑器可以用键盘命令交互式插入、删除或替换文本数据。流编辑器则是根据事先设计好的一组规则编辑数据流。 sed编辑器…

Mybatis 框架 ( 三 ) Mybatis-Plus

4.Mybatis-plus 官网 : https://www.baomidou.com/ MyBatis-Plus 是一个 MyBatis 的增强工具&#xff0c;在 MyBatis 的基础上封装了大量常规操作&#xff0c;减少了SQL的编写量。 4.1.Maven依赖 使用时通常通过Springboot框架整合使用 并且使用Lombok框架简化实体类 <…