数据结构: 红黑树
目录
1.红黑树概念
2.红黑树性质
3.调整
1.如果p和u都是红色,将其都改为黑色即可,然后向上调整
2.如果p红(u黑/u不在),这时候左子树两红,于是给右子树一个红(旋转+变色)
2.1右单旋 + 变色- p变黑, g变红, 达到给右子树一个红节点的效果, 并保持每条路径上黑色节点的个数相同
2.2左右双旋转 + 变色
2.3左单旋 + 变色
2.4右左双选 + 变色
4.红黑树的简单实现
4.1红黑树的定义
4.2相关功能
插入
检查
获取最左/右侧的节点
检查树种是否存在data节点
4.3默认成员函数
测试用例:
1.插入
2.检查
3.获取最左/右侧节点
4.在树种查找节点
1.红黑树概念
红黑树,是一种二叉搜索树,但在每个结点上增加一个存储位表示结点的颜色,可以是Red或Black。 通过对任何一条从根到叶子的路径上各个结点着色方式的限制,红黑树确保没有一条路径会比其他路径长出俩倍,因而是接近平衡的
2.红黑树性质
- 每个结点不是红色就是黑色
- 根节点是黑色的
- 如果一个节点是红色的,则它的两个孩子结点是黑色的
- 对于每个结点,从该结点到其所有后代叶结点的简单路径上,均包含相同数目的黑色结点
- 每个叶子结点都是黑色的(此处的叶子结点指的是空结点)
最短路径: 全黑
最长路径: 一黑一红交替
红黑树就能保证:其最长路径中节点个数不会超过最短路径节点个数的两倍
红黑树优势: 旋转次数更少
新插入的节点默认是红色
--1.如果是黑色, 一定违反了规则4 会影响所有路径
--2.如果是红色, 当插入到红色节点后面,违反规则3 , 当插入到黑色节点的后面,不违反规则
3.调整
什么时候需要修改红黑树?--当插入到红色节点后面的时候
1.如果p和u都是红色,将其都改为黑色即可,然后向上调整
- -然后将g改为红(g原来为黑,我们已经把p,u改为黑了,会多一个黑节点,违反规则4,需要把g改为红)
- -当然改为红后,g的p可能也是红,继续往上调整即可(把cur = g),如果最后调到根,要将根变黑
2.如果p红(u黑/u不在),这时候左子树两红,于是给右子树一个红(旋转+变色)
-这种情况讨论cur的插入位置 ,来决定其需要怎么旋转(单旋,双旋)
--p是g的左 ,且插入的节点在左子树
2.1右单旋 + 变色
- p变黑, g变红, 达到给右子树一个红节点的效果, 并保持每条路径上黑色节点的个数相同
2.2左右双旋转 + 变色
--p是g的右, 且插入的节点在右子树
2.3左单旋 + 变色
2.4右左双选 + 变色
4.红黑树的简单实现
4.1红黑树的定义
节点

RBTree

4.2相关功能
插入
1.找到节点的位置
2.链接节点
3.判断此时p是不是红色, 且存在 (默认插入的节点是红色), 是的话就需要调整
--p,u存在且都为红 ===> 直接将p,u变为黑色,g变红色, 然后向上调整,
如果调到根(要将其变黑)
--p红, u红/u不在 ===> 对插入节点位置进行讨论
1.p是g的左, cur是 p的左 ===> g右单旋
2.p是g的左, cur是p的右 ===> p左旋, g右旋
3.p是g的右, cur是p的右 ===> g左单旋
4.p是g的右, cur是p的左 ===> p右旋,g左旋
代码:
1.找到节点的位置 2.链接节点
3.判断此时p是不是红色, 且存在 (默认插入的节点是红色), 是的话就需要调整
效果:
检查
- 判断根节点是黑色的(规则2)
- 判断有无连续的红色节点(规则3)
- 判断每条路径上的黑色节点个数是否相等(规则4) --这里随便选取一条路径的黑色节点数作为基准值, 用来和对比其它路径黑节点的个数
代码:
//红黑树的检查bool Is_RBTree() {return _Is_RBTree(_root);}//红黑树的检查bool _Is_RBTree(Node* root){//规则2:根节点是黑色的if (root == nullptr) return true; if (root->_color != BLACK) return false;//规则3:不能有连续的红色节点//规则4:每条路径上的黑色节点个数相等Node* cur = root; int base_nums = 0;while (cur) {if (cur->_color == BLACK) base_nums++;cur = cur->_left;}Check(root,base_nums,0);}bool Check(Node* root,int base_nums,int block_nums) {if (root == nullptr) {if (base_nums != block_nums) return false;return true;}//检查有没有连续的红色节点if (root->_parent && root->_color == RED && root->_parent->_color == RED)return false;//遇到一个黑色节点就++if (root->_color == BLACK) block_nums++;return Check(root->_left,base_nums,block_nums) && Check(root->_right,base_nums,block_nums);}
获取最左/右侧的节点
//获取红黑树最左侧节点Node* LeftMost(){Node* cur = _root;//空树if (cur == nullptr) return nullptr;while (cur->_left){cur = cur->_left;}return cur;}//获取红黑树最右侧节点Node* RightMost(){Node* cur = _root;//空树if (cur == nullptr) return nullptr;while (cur->_right){cur = cur->_right;}return cur;}
检查树种是否存在data节点
//检测红黑树中是否存在值为data的节点Node* Find(const T& data){Node* cur = _root;while (cur){if (cur->_data > data)cur = cur->_left;else if (cur->_data < data)cur = cur->_right;else return cur;}return nullptr;}
4.3默认成员函数
--构造函数
这里传了缺省值(可不写)
--拷贝构造
思路:使用前序遍历, 构造红黑树
--赋值运算符
思路: 交换_root
--析构函数
后序遍历,删除节点
测试用例:
1.插入

2.检查
正常情况:

异常:
屏蔽掉颜色的调整

修改默认生成黑色节点

3.获取最左/右侧节点

4.在树种查找节点

代码:RB-Tree/RB-Tree · 朱垚/数据结构练习 - 码云 - 开源中国 (gitee.com)
相关文章:
数据结构: 红黑树
目录 1.红黑树概念 2.红黑树性质 3.调整 1.如果p和u都是红色,将其都改为黑色即可,然后向上调整 2.如果p红(u黑/u不在),这时候左子树两红,于是给右子树一个红(旋转变色) 2.1右单旋 变色- …...
如何搭建开源ERP平台Odoo并实现公网远程访问?——“cpolar内网穿透”
文章目录 前言1. 下载安装Odoo:2. 实现公网访问Odoo本地系统:3. 固定域名访问Odoo本地系统 前言 Odoo是全球流行的开源企业管理套件,是一个一站式全功能ERP及电商平台。 开源性质:Odoo是一个开源的ERP软件,这意味着企…...
什么是马尔科夫随机场?
马尔科夫随机场,也称为马尔可夫网(Markov Network),是一种概率图模型,用于表示随机变量之间的依赖关系。它是由若干个随机变量组成的无向图,其中节点代表随机变量,边代表它们之间的相互作用或依…...
自然语言处理---huggingface平台使用指南
1 huggingface介绍 Huggingface总部位于纽约,是一家专注于自然语言处理、人工智能和分布式系统的创业公司。他们所提供的聊天机器人技术一直颇受欢迎,但更出名的是他们在NLP开源社区上的贡献。Huggingface一直致力于自然语言处理NLP技术的平民化(democr…...
修炼k8s+flink+hdfs+dlink(六:学习k8s-pod)
一:增(创建)。 直接进行创建。 kubectl run nginx --imagenginx使用yaml清单方式进行创建。 直接创建方式,并建立pod。 kubectl create deployment my-nginx-deployment --imagenginx:latest 先创建employment,不…...
ARM映像文件组成
引言 ARM编译器将各种源文件(汇编文件、C语言程序文件、C语言程序文件)编译生成ELF格式的目标文件(后缀为.o文件,以下将目标文件简称为.o文件),.o文件经过连接器,和C/C运行时库一起编译生成ELF格…...
redis怎么设计一个高性能hash表
问题 redis 怎么解决的hash冲突问题 ?redis 对于扩容rehash有什么优秀的设计? hash 目标是解决hash冲突,那什么是hash冲突呢? 实际上,一个最简单的 Hash 表就是一个数组,数组里的每个元素是一个哈希桶&…...
《软件方法》强化自测题-总纲(6)
DDD领域驱动设计批评文集 做强化自测题获得“软件方法建模师”称号 《软件方法》各章合集 按照业务建模、需求、分析、设计工作流考察,答案不直接给出,可访问自测链接或扫二维码自测,做到全对才能知道答案。 知识点见《软件方法》&#x…...
vue2中,下拉框多选和全选的实现
vue2中,下拉框多选和全选的实现 代码布局在methods: 中添加功能函数较为完整的一个整体代码: 如图所示点击全选即可完成下拉框中全部子项的全部的选中,同时取消全选即可全部取消选择。 代码布局 <div class"chos-box2"><…...
Android-Framework 默认音乐音量最大
代码位置:frameworks/base/services/core/java/com/android/server/audio/AudioService.java -712,6 712,9 public class AudioService extends IAudioService.Stub}} // force music max volume AudioSystem.DEFAULT_STREAM_VOLUME[AudioSystem.STREAM_MUSIC] MA…...
formData对象打印不出来
用el-upload上传图片 以流的形式传给后台 所以用formData对象带数据 let formData new FormData() formData.append(name,monkey7) console.log(formData) 明明已经把数据append进去了 console.log在控制台却打印不出 后来发现他得用formData.get("xxx"…...
【Web安全】SQL注入攻击几种常见防御手法总结
文章目录 前言一、使用参数化查询二、输入验证和过滤三、使用存储过程四、最小权限原则五、使用ORM框架六、使用准备语句七、使用安全的数据库连接八、避免动态拼接SQL语句九、使用防火墙和入侵检测系统(一)防火墙(二)入侵检测系统(Intrusion Detection System,简称IDS)十、定期…...
Linux网络编程杂谈(聊聊网络编程背后的故事)
数据是如何传输到物理网络上的? 以TCP为例,当 TCP 决定发送数据时,这些数据需要经过多个处理阶段才能真正被传输到物理网络。其中一个关键步骤是将数据移动到网络接口卡 (NIC)。以下是这个过程的详细描述: 数据序列化: TCP 会为要…...
执行Maven项目时,无法解析项目的依赖关系
报错[ERROR] Failed to execute goal on project pdms-services: Could not resolve dependencies for project ..... 在IDEA ----> setting ---->Remote Jar Repositories ----> Maven jar repositories中添加远程仓库的http地址。 再次进行maven的clean和install就好…...
索引有哪些缺点以及具体有哪些索引类型
索引的优缺点 优点: 合理的增加索引,可以提高数据查询的效率,减少查询时间 有一些特殊的索引,可以保证数据的完整性,比如唯一索引 缺点: 创建索引和维护索引需要消耗时间 索引需要额外占用物理空间 对创建…...
前端学成在线项目详细解析二
12-banner区域-课程表布局 HTML布局 <div class"right"><h3>我的课程表</h3><div class"content">1</div> </div> CSS样式 /* 课程表 */ .banner .right {margin-top: 60px;width: 218px;height: 305px;background-…...
Linux 网卡性能优化设置
在高速网络传输中,每秒传输的数据量非常大。网络设备设置有一种缓存机制,即“缓存区”,在 Linux 系统中,网卡缓冲分为两种类型:软件缓冲区和硬件缓冲区。 要提高网络吞吐率,首先当然是升级linux kernel。其…...
华为OD 最大嵌套括号深度(100分)【java】B卷
华为OD统一考试A卷+B卷 新题库说明 你收到的链接上面会标注A卷还是B卷。目前大部分收到的都是B卷。 B卷对应20022部分考题以及新出的题目,A卷对应的是新出的题目。 我将持续更新最新题目 获取更多免费题目可前往夸克网盘下载,请点击以下链接进入: 我用夸克网盘分享了「华为O…...
“微信小程序登录与用户信息获取详解“
目录 引言微信小程序微信登录介绍1. 微信登录的基本概念2. 微信小程序中的微信登录 微信小程序登录的wxLogin与getUserProfile的区别1. wx.login()2. wx.getUserProfile()3.两者区别 微信小程序登录的理论概念1. 微信登录流程2. 用户授权与登录态维护 微信小程序登录的代码演示…...
软考-防火墙技术与原理
本文为作者学习文章,按作者习惯写成,如有错误或需要追加内容请留言(不喜勿喷) 本文为追加文章,后期慢慢追加 by 2023年10月 防火墙概念 根据网络的安全信任程度和需要保护的对象,人为地划分若干安全区域…...
网络编程(Modbus进阶)
思维导图 Modbus RTU(先学一点理论) 概念 Modbus RTU 是工业自动化领域 最广泛应用的串行通信协议,由 Modicon 公司(现施耐德电气)于 1979 年推出。它以 高效率、强健性、易实现的特点成为工业控制系统的通信标准。 包…...
【OSG学习笔记】Day 18: 碰撞检测与物理交互
物理引擎(Physics Engine) 物理引擎 是一种通过计算机模拟物理规律(如力学、碰撞、重力、流体动力学等)的软件工具或库。 它的核心目标是在虚拟环境中逼真地模拟物体的运动和交互,广泛应用于 游戏开发、动画制作、虚…...
《从零掌握MIPI CSI-2: 协议精解与FPGA摄像头开发实战》-- CSI-2 协议详细解析 (一)
CSI-2 协议详细解析 (一) 1. CSI-2层定义(CSI-2 Layer Definitions) 分层结构 :CSI-2协议分为6层: 物理层(PHY Layer) : 定义电气特性、时钟机制和传输介质(导线&#…...
React19源码系列之 事件插件系统
事件类别 事件类型 定义 文档 Event Event 接口表示在 EventTarget 上出现的事件。 Event - Web API | MDN UIEvent UIEvent 接口表示简单的用户界面事件。 UIEvent - Web API | MDN KeyboardEvent KeyboardEvent 对象描述了用户与键盘的交互。 KeyboardEvent - Web…...
Spring AI 入门:Java 开发者的生成式 AI 实践之路
一、Spring AI 简介 在人工智能技术快速迭代的今天,Spring AI 作为 Spring 生态系统的新生力量,正在成为 Java 开发者拥抱生成式 AI 的最佳选择。该框架通过模块化设计实现了与主流 AI 服务(如 OpenAI、Anthropic)的无缝对接&…...
06 Deep learning神经网络编程基础 激活函数 --吴恩达
深度学习激活函数详解 一、核心作用 引入非线性:使神经网络可学习复杂模式控制输出范围:如Sigmoid将输出限制在(0,1)梯度传递:影响反向传播的稳定性二、常见类型及数学表达 Sigmoid σ ( x ) = 1 1 +...
小木的算法日记-多叉树的递归/层序遍历
🌲 从二叉树到森林:一文彻底搞懂多叉树遍历的艺术 🚀 引言 你好,未来的算法大神! 在数据结构的世界里,“树”无疑是最核心、最迷人的概念之一。我们中的大多数人都是从 二叉树 开始入门的,它…...
Axure 下拉框联动
实现选省、选完省之后选对应省份下的市区...
WEB3全栈开发——面试专业技能点P7前端与链上集成
一、Next.js技术栈 ✅ 概念介绍 Next.js 是一个基于 React 的 服务端渲染(SSR)与静态网站生成(SSG) 框架,由 Vercel 开发。它简化了构建生产级 React 应用的过程,并内置了很多特性: ✅ 文件系…...
快速排序算法改进:随机快排-荷兰国旗划分详解
随机快速排序-荷兰国旗划分算法详解 一、基础知识回顾1.1 快速排序简介1.2 荷兰国旗问题 二、随机快排 - 荷兰国旗划分原理2.1 随机化枢轴选择2.2 荷兰国旗划分过程2.3 结合随机快排与荷兰国旗划分 三、代码实现3.1 Python实现3.2 Java实现3.3 C实现 四、性能分析4.1 时间复杂度…...










