红黑树的底层讲解

一、红黑树的介绍

红黑树,是一种二叉搜索树,但在每个结点上增加一个存储位表示结点的颜色,可以是红(red)或黑(black)。通过对任何一条从根到叶子的路径上各个结点着色方式的限制,红黑树确保没有一条路径会比其他路径长出两倍,因此是接近平衡的。(近似平衡)AVL树是严格平衡

红黑树有以下性质(规则):

1.每个结点不是红色就是黑色 

2.根结点是黑色的

3.如果一个结点是红色的,则它的两个孩子结点是黑色的。(一条路径中没有连续红色结点)

4.对于每个结点,从该结点到其所有后代叶结点的简单路径上,均包含相同数目的黑色结点(每条路径的黑色结点数量相等)

5.每个叶子结点都是黑色的(此处的叶子结点指的是空结点)

以上四点,就能保证红黑树确保没有一条路径会比其他路径长出两倍(最短*2>=最长)第五点我们放在后面解释。

由于其底层也是二叉搜索树,结点的封装我们就不多说了(存放的还是pair类型,结点中包含其左右结点和父结点的指针)除此之外,我们还要用枚举记录颜色,基本就是如图:

颜色给什么我们一会再说。

二、红黑树的基本功能实现

1.插入数据

此时会面临一个选择, 是插入红色还是黑色,这要看插入后对其他结点的影响大不大,对于红色,我们只要保证路径无连续红色即可,即使插入后有连续红色也只是在这一条路径上更改,但黑色就不一样了,需要保证每条路径的黑结点数量相等,一旦一条路插入黑色,所有的其他路径都要修改,代价和红色比还是很大的。所以,我们先讨论插入红色结点的情况

以下面这棵树(或子树)为例

其中,p代表parent  g代表grandfather  u 代表uncle

前提条件:abcde均为空,cur为新增

我们一开始先不考虑用旋转来解决问题,毕竟旋转的操作影响比较大,且目的是实现完全平衡,但我们的红黑树的目的是实现近似平衡即可,因此尽量减少工作量。

其中,以上有几个结点的颜色已经是确定的:cur红色结点,parent一定也是红色结点(因为如果parent是黑色结点那么我们cur的插入操作就符合红黑树的规则,不需要再调整了,我们这里所有情况都是当cur插入后树不符合红黑树的规则下),grandfather一定是黑色(parent已经是红了,一条路不可能出现连续红色)。因此,唯一可变性就在这个uncle结点。

情况一:当uncle存在且是红结点,为了保证规则,首先需要把parent转变为黑,同时把uncle变红,而且要把grandfather变红(因为每个路径的黑结点数量一定是相同的,经过上面的操作后,两条路径均新增一个黑结点,为了保持和别的路径相等,需要把grandfather变红保持相等,但如果grandfather 本身是根就没必要)然后再向上调整,把grandfather当成cur调整。

在情况一的前提条件下,ab为红,cde为只有一个黑色结点的子树,那么其情况就有上百种,我们在后续也就不过多分析了。

情况二之一:当uncle不存在(abcde均为空,cur为新增且为parent的左) 如下图左边

此时如果我们像情况一的处理方式貌似无法解决问题,破坏了黑色数量的平衡,因此我们只能旋转处理(上图右为旋转后的结果)

情况二之二:当uncle不存在(abcde均为空,cur为新增且为parent的右) 

此时我们通过单旋就无法满足要求了,需要进行双旋,先以parent为中心进行一次做单旋,此时情况就变成了情况二之一,再加个以g为中心的右旋即可满足。

情况三:uncle存在且为黑色

处理方法:旋转(以g为中心的右单旋),让g的位置变成p,p的左不变,右变为g,g右不变,左变成c,然后p变黑,g变红

其实,无论uncle是空还是为黑色,其操作原理完全相同,因此我们当只需要单旋成为情况二,双旋为情况三

我们用代码分析一下以上的所有情况,还是和前面的类似,需要写在插入函数中,而且,其中左旋和右旋的函数在上节的AVL树已经讲解完原理,所以代码中对这部分就不讲解了(这边附上AVL树的链接https://blog.csdn.net/czt230610/article/details/135952308?fromshare=blogdetail&sharetype=blogdetail&sharerId=135952308&sharerefer=PC&sharesource=czt230610&sharefrom=from_link)

//....上面是插入函数while(parent&&parent->_col==RED)//必须为红色,否则插入后无需修改{Node*grandfather =parent->_parent;if(parent==grandfather->_left)  //大前提,研究的都是左边一边高{                              //当右边高的时候代码原理相同Node*uncle=grandfather->right;if(uncle&&uncle->_col==RED) //情况一{parent->_col=BLACK;uncle->_col=BlACK;grandfather->_col=RED;cur=grandfather;parent=cur->_parent;}else //uncle不存在或者为黑色   情况二{if(cur==parent->_left) //一边高,单旋即可{rotater(grandfather);//改色parent->_col=BLACK;grandfather->_col=RED;}else//不是一边高,双旋 情况三{rotatel(parent);rotater(grandfather);//改色cur->_col=BLACK;grandfather->_col=RED;}break;}} else//parent在右uncle在左{Node* uncle = grandfather->_left;// 叔叔存在且为红,-》变色即可if (uncle && uncle->_col == RED){parent->_col = uncle->_col = BLACK;grandfather->_col = RED;// 继续往上处理cur = grandfather;parent = cur->_parent;}else // 叔叔不存在,或者存在且为黑{// 情况二:叔叔不存在或者存在且为黑// 旋转+变色//      g//   u     p//            cif (cur == parent->_right){RotateL(grandfather);parent->_col = BLACK;grandfather->_col = RED;}else{//		g//   u     p//      cRotateR(parent);RotateL(grandfather);cur->_col = BLACK;grandfather->_col = RED;}break;}				}_root->_col = BLACK;//无论情况一之后是否需要向上调整都把根变黑//避免了多情况分析
}

正文结束 

麻烦留下你宝贵的点赞与收藏,这对我的动力真的很大!

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

通过比较list与vector在简单模拟实现时的不同进一步理解STL的底层

cplusplus.com/reference/list/list/?kwlist 当我们大致阅读完list的cplusplus网站的文档时,我们会发现它提供的接口大致上与我们的vector相同。当然的,在常用接口的简单实现上它们也大体相同,但是它们的构造函数与迭代器的实现却大有不同。…

计算机网络:数据链路层 —— 共享式以太网

文章目录 共享式以太网CSMA/CD 协议CSMA/CD 协议 的基本原理 共享式以太网的争用期共享式以太网的最小帧长共享式以太网的最大帧长共享式以太网的退避算法截断二进制指数退避算法 共享二进制以太网的信道利用率使用集线器的共享式以太网10BASE-T 共享式以太网 共享式以太网是当…

自监督学习:引领机器学习的新革命

引言 自监督学习(Self-Supervised Learning)近年来在机器学习领域取得了显著进展,成为人工智能研究的热门话题。不同于传统的监督学习和无监督学习,自监督学习通过利用未标注数据生成标签,从而大幅降低对人工标注数据…

Modbus TCP 西门子PLC指令以太口地址配置以及 Poll Slave调试软件地址配置

1前言 本篇文章讲了 Modbus TCP通讯中的一些以太网端口配置和遇到的一些问题, 都是肝货自己测试的QAQ。 2西门子 SERVER 指令 该指令是让外界设备主动连接此PLC被动连接, 所以这里应该填 外界设备的IP地址。 这边 我因为是电脑的Modbus Poll 主机来…

反弹shell检测的一些思路

前言 反弹shell是攻击者常用的手段之一,通过反弹Shell,攻击者可以绕过防火墙,获取目标系统的shell访问权限,进行后续的恶意操作。因此,及时检测并阻止反弹Shell行为对于安全防护来说非常重要。本文通过介绍反弹shell的…

Kafka原理剖析之「Purgatory(炼狱 | 时间轮)」

一、前言 本文介绍一下Kafka赫赫有名的组件Purgatory,相信做Kafka的朋友或多或少都对其有一定的了解,至少是听过它的名字。那它的作用是什么呢,用来解决什么问题呢?官网confluent早就有文章对其做了阐述 https://cwiki.apache.o…

Redis和Jedis的区别

目录 含义与用途 Jedis案例 总结 含义与用途 Redis: 概念:Redis是一个基于内存的键值存储数据库,支持丰富的数据结构。比如:字符串功能:除了基础的数据存储,Redis还提供了丰富的高级功能。如持久化&…

golang生成并分析cpu prof文件

1. 定义一个接口,请求接口时,生成cpu.prof文件 在主协程中新启一个协程,当请求接口时,生成一个60秒的cpu.prof文件 go func() {http.HandleFunc("/prof", startProfileHandler)http.ListenAndServe(":9092"…

MySQL中什么情况下类型转换会导致索引失效

文章目录 1. 问题引入2. 准备工作3. 案例分析3.1 正常情况3.2 发生了隐式类型转换的情况 4. MySQL隐式类型转换的规则4.1 案例引入4.2 MySQL 中隐式类型转换的规则4.3 验证 MySQL 隐式类型转换的规则 5. 总结 如果对 MySQL 索引不了解,可以看一下我的另一篇博文&…

markdown 笔记,语法,技巧

起因, 目的: markdown 有些语法,不常用,记不住。单独记录一下。 1. 插入数学公式 用 $$ 来包裹住多行数学公式。 $$ 多行数学公式 $$ 2. 2个星号 ** , 加粗, 3. 单行代码的 引用, 左右各一个顿号 8.…

HTML_文本标签

概念: 1、用于包裹:词汇、短语等。 2、通常写在排版标签里面。 3、排版标签更宏观(大段的文字),文本标签更微观(词汇、短语)。 4、文本标签通常都是行内元素。 常用的文本标签 标签名 全称 标签语义em Emphasized 加重(文本)。要着重阅…

数字图像处理:图像复原应用

数字图像处理:图像复原应用 1.1 什么是图像复原? 图像复原是图像处理中的一个重要领域,旨在从退化(例如噪声、模糊等)图像中恢复出尽可能接近原始图像的结果。图像复原与图像增强不同,复原更多地依赖于图…

3D一览通常见问题QA

感谢大家一直以来对大腾智能3D一览通的支持,我们致力于提供便捷高效的3D协同服务。这里小编整理了一些关于3D一览通的常见问题,以便大家更好地了解和使用3D一览通。 Q:3D一览通的功能是什么? 3D一览通是大腾智能打造的一款云端轻…

如何在 JSON 中编写“anyOf”语句?

在 JSON 中,anyOf 语句通常用于 JSON Schema(JSON 模式)中,来定义多个可能的模式,表示数据可以匹配多个子模式中的任意一个。这种功能常用于验证 JSON 数据是否符合某一组可能的条件之一。 1、问题背景 问题&#xff…

【计算机网络 - 基础问题】每日 3 题(三十六)

✍个人博客:https://blog.csdn.net/Newin2020?typeblog 📣专栏地址:http://t.csdnimg.cn/fYaBd 📚专栏简介:在这个专栏中,我将会分享 C 面试中常见的面试题给大家~ ❤️如果有收获的话,欢迎点赞…

MongoDB 的安装详情

在虚拟机里面opt下 新建一个mongodb文件夹 再新建一个opt/mongodb/data文件夹, 然后将挂载的mongodb数据放到data文件夹里: 【把mongodb的数据挂载出来,以后我们再次重启的时候 数据起码还会在】 冒号右边 挂载到左边的路径 docker run -…

Matlab终于能够实现Transformer预测了

声明:文章是从本人公众号中复制而来,因此,想最新最快了解各类智能优化算法及其改进的朋友,可关注我的公众号:强盛机器学习,不定期会有很多免费代码分享~ 目录 原理简介 数据介绍 结果展示 完整代码 今…

ubuntu24 修改ip地址 ubuntu虚拟机修改静态ip

1. ubuntu 修改地址在/etc/netplan # 进入路径 cd /etc/netplan # 修改文件夹下的配置文件,我的是50-cloud-init.yaml. ye可能你得是20-cloud-init.yaml 2. 修改为: dhcp4: 改为false 192.168.164.50 是我自己分配的ip地址, /24 为固定写法&#xff…

数据结构与算法:堆与优先队列的深入剖析

数据结构与算法:堆与优先队列的深入剖析 堆是一种特殊的树形数据结构,广泛应用于优先队列的实现以及各种高效的算法中,如排序和图算法。通过深入了解堆的结构、不同堆的实现方式,以及堆在实际系统中的应用,我们可以掌…

初级网络工程师之从入门到入狱(四)

本文是我在学习过程中记录学习的点点滴滴,目的是为了学完之后巩固一下顺便也和大家分享一下,日后忘记了也可以方便快速的复习。 网络工程师从入门到入狱 前言一、Wlan应用实战1.1、拓扑图详解1.2、LSW11.3、AC11.4、抓包1.5、Tunnel隧道模式解析1.6、AP、…