红黑树的原理+实现
文章目录
- 红黑树
- 定义
- 性质
- 红黑树的插入
- 动态效果演示
- 代码
- 测试红黑树
红黑树
定义

红黑树是一个近似平衡的搜索树,关于近似平衡主要体现在最长路径小于最短路径的两倍(我认为这是红黑树核心原则),为了达到这个原则,红黑树所有节点都增加了一个存储位表示节点的颜色(红或黑),并规定了一些性质来达到“近似平衡”
性质
- 每个节点不是红色就是黑色
- 根节点时黑色
- 如果一个节点是红色,则它的两个孩子节点是黑色
- 对于每个节点,从该节点到其所有后代叶节点的简单路径上,均包含相同数目的黑色节点
- 每个叶子节点都是黑色的(空节点也算为叶子节点)
对于这些性质有一些推论:
- 红色节点的父节点一定是黑色节点
- 何时红黑树的路径最短?——该树所有节点都是黑色
- 何时红黑树的路径最长?——该树红色节点和黑色节点交替
红黑树的插入
插入之前我们首先要搞明白一个问题,插入的节点默认应该应该是什么颜色(然后根据插入后调整)?
插入的节点如果都设置为黑色,一定会违反性质4,。如果插入的是红色节点,分为两种情况:如果插入节点的父节点为黑色,则不需要调整,如果插入节点的父节点为红色,则需要进一步调整。
从上可知,如果默认插入的是黑色100%需要调整,而默认插入的是红色,则有50%需要调整,所以我们这里选择默认插入红色节点
红黑树的插入需要记住三种需要调整的特殊情况:下面所有情况中 cur 为当前插入后违反红黑树规则的节点,
- 情况一:
cur和parent为红,grandparent为黑,uncle存在且为红

这种情况不需要旋转只需要调整节点的颜色即可,将parent和uncle变成黑色,grandparent变成红色(这里有特殊情况,如果grandparent为根节点时)

ok到这里我们观察一下,grandparent为红色,如果grandparent的父节点为红色(因为grandparent原本为黑色,所以其父节点有可能为红色)则又会出现两个连续的红色,所以情况一结束后还要继续向上检查,这时我们将cur=grandparent继续向上遍历,继续分析下一层的情况

- 情况二:
cur和parent为红,grandparent为黑,uncle为黑/不存在

这里有两种小情况我们先逐一分析,但是这两种小情况最后的操作都是一样的- uncle不存在:cur一定为新插入的节点而不是整个向上调整循环中的一次,因为如果cur不是新插入的节点,则
cur或parent一定有一个是黑色,分别是从上一层的情况一和情况三变过来的,但是这就不满足红黑树的定义了。所以cur一定是新插入的节点 - uncle存在且为黑:那么cur一定是黑色的,现在是红色是因为上一层结束后改成了红色,继续向上遍历的结果
如何处理情况二?——右单旋+调整颜色

ok到这里情况二调整完毕了。是否需要继续向上调整了?答案是不用!因为整个局部的子树调整完的根节点变成黑色了,并不会和其父节点的颜色发生冲突,所以在 整个三个情况中只要调整完之后的根节点变成了黑色,就不用向上遍历了
- uncle不存在:cur一定为新插入的节点而不是整个向上调整循环中的一次,因为如果cur不是新插入的节点,则
- 情况三:
cur和parent为红,grandparent为黑,uncle为黑/不存在,但是cur为parent的右节点

如何处理情况三?——局部旋转!+ 转换情况二

这时旋转完之后的树是不是很眼熟?就是情况二,只需要交换一下cur和parent指针的执行进入下一次的循环即可。
这里还有另外一个思路就是:局部旋转之后直接执行情况二的右单旋,最后直接break跳出循环。两者思路其实是一模一样的
动态效果演示
以升序插入

以降序插入

随机插入

代码
代码仓库
测试红黑树
为了测试我们写出来的红黑树是否符合要求,我们可以写一个isbalance函数,主要判断:
- 不能出现连续的红色节点
- 每条路径的黑色节点是否相同
两个条件分别使用不同的函数判断
具体代码实现如下:
bool parent_isRed(Node *root) // 判断红色节点的父节点是不是黑色节点{if (root == nullptr){return true;}if (root->_col == RED && root->_parent->_col == RED){return false;}return parent_isRed(root->_left) && parent_isRed(root->_right);}void black_num_is_same(Node *root, std::vector<int> &num, int k = 0) // num存储了每条路径黑色节点的数量{if (root == nullptr){num.push_back(k);return;}if (root->_col == BLACK){k++;}black_num_is_same(root->_left, num, k);black_num_is_same(root->_right, num, k);}
void IsBalnace() // 检查红黑树是否平衡{bool is = parent_isRed(_root);std::vector<int> num;black_num_is_same(_root, num);bool it = true;int first = num[0];for (const auto &e : num){if (e != first){it = false;break;}}if (it && is){std::cout << "it is a redblackTree" << std::endl;}else{std::cout << "it is not a redblackTree" << std::endl;}}
检测函数写完我们取1000个随机数向红黑树插入,并用isblance 检查是否平衡:
测试代码
输出结果:

相关文章:
红黑树的原理+实现
文章目录红黑树定义性质红黑树的插入动态效果演示代码测试红黑树红黑树 定义 红黑树是一个近似平衡的搜索树,关于近似平衡主要体现在最长路径小于最短路径的两倍(我认为这是红黑树核心原则),为了达到这个原则,红黑树所…...
用于非线性时间序列预测的稀疏局部线性和邻域嵌入(Matlab代码实现)
💥💥💞💞欢迎来到本博客❤️❤️💥💥 🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。 ⛳️座右铭&a…...
使用 Vue3 重构 Vue2 项目
目录前言:一、项目整体效果展示二、项目下载使用方法三、为什么要重构项目四、重构的流程五、步骤中的 bug 以及解决方式六、未解决的问题总结:前言: 2020年9月18日,vue3正式版发布了,前几天学习完成后,我决…...
Hive学习——单机版Hive的安装
目录 一、基本概念 (一)什么是Hive (二)优势和特点 (三)Hive元数据管理 二、Hive环境搭建 1.自动安装脚本 2./opt/soft/hive312/conf目录下创建hive配置文件hive-site.xml 3.拷贝一个jar包到hive下面的lib目录下 4.删除hive的guava,拷贝hadoop下的guava 5…...
uprobe 实战
观测数据源 目前按照我的理解,和trace相关的常用数据源–探针 大致分为四类。 内核 Trace point kprobe 用户程序 USDT uprobe 在用户程序中,USDT是所谓的静态Tracepoint。和内核代码中的Trace point类似。实现方式是在代码开发时,使用USDT…...
华为OD机试 - 求最大数字(Python)| 真题+思路+考点+代码+岗位
求最大数字 题目 给定一个由纯数字组成以字符串表示的数值,现要求字符串中的每个数字最多只能出现2次,超过的需要进行删除;删除某个重复的数字后,其它数字相对位置保持不变。 如34533,数字3重复超过2次,需要删除其中一个3,删除第一个3后获得最大数值4533 请返回经过删…...
雨水情测报与大坝安全监测系统
压电式雨量传感器产品概述传感器由上盖、外壳和下盖组成,壳体内部有压电片和电路板,可以固定在外径50mm立柱上和气象站横杆上。传感器采用冲击测量原理对单个雨滴重量进行测算,进而计算降雨量。雨滴在降落过程中受到雨滴重量和空气阻力的作用…...
抖音广告投放形式有哪些?新品牌进入抖音怎么建立口碑
坐拥5亿用户的抖音平台,已经成为各大品牌的兵家必争之地。想要在这块宣传的“高地”,做出声量,就必须了解抖音广告投放形式有哪些。这里整理的这份抖音广告投放指南,你一定不能错过。一、抖音为何如此牛想要弄清楚抖音广告的投放形…...
Beefxss使用教程图文教程(超详细)
「作者主页」:士别三日wyx 「作者简介」:CSDN top100、阿里云博客专家、华为云享专家、网络安全领域优质创作者 Beefxss一、首次使用二、修改账号密码三、自带练习页面四、简单使用五、工具界面介绍六、功能演示1、网页重定向2、社工弹窗3、功能颜色标识…...
【Python学习笔记】35.Python3 CGI编程(2)
前言 本章继续介绍Python的CGI编程。 通过CGI程序传递checkbox数据 checkbox用于提交一个或者多个选项数据,HTML代码如下: 实例 <!DOCTYPE html> <html> <head> <meta charset"utf-8"> <title>csdn教程(csd…...
博客等级说明
CSDN 博客等级是按照用户的博客积分数量进行的设定,为 Lv1 至 Lv10 共 10 个等级,不同的等级创作者可以享受到不同的权益待遇。例如,皮肤奖励、自定义域名、客服优先处理、自定义文章标签等特权。您需要提高博客积分进一步提升等级࿰…...
STL——容器适配器、deque
一、容器适配器 1.适配器 适配器是一种设计模式(设计模式是一套被反复使用的、多数人所知晓的、经过分类编目的、代码设计经验的总结),该种模式是将一个类的接口转换成客户希望的另外一个接口。 2.STL标准库中stack和queue的底层结构 stack…...
VBA数组和Excel工作表数据传递
本文介绍如何利用 VBA 的数组(Array) 来提高 Excel 单元格和外部数据传输的性能。如果数量比较大,通过 Array 来传输数据比直接操作单元格要快若干倍。 将 Range 的数据写入 VBA Array 将 Range 数据写入 VBA 的数组非常简单。下面的例子演示了用法&am…...
PyQt5保姆级入门教程——从安装到使用
目录 Part1:安装PyQt5 Part 2:PyCharm配置PyQt5 Part 3:PyQt5设计界面介绍 Part 4:PyQt5设计UI 今天看了多个大佬的教程,总算是把PyQt5开发弄好了,每个部分都要看几个人的十分不方便,我十分…...
1.6 epoll实战使用
文章目录1、连接池2、epoll两种工作模式2.1、LT模式2.2、ET模式3、后端开发面试题4、epoll验证1、连接池 将每一个套接字和一块内存进行绑定,连接池就是一个结构体数组,通过链表来维护一个空闲连接。 1、ngx_get_connection(int fd)从空闲链表取一个空闲…...
JDK定时、Spring定时、时间轮定时小结
Timer使用一个线程,一个小根堆。线程执行根上的任务,小根堆会根据执行时间戳重新调整,根上的任务是下一个执行的任务。 DelayedQueue维护一个优先级队列,本质也是一个数组方式的堆。任务生成时也有时间戳,只提供存储。…...
关于cFosSpeed如何配置
cFosSpeed配置一、检查Calibration Done情况二、优化Ping时间和线路校准三、测网速四、cFosSpeed控制台五、配置参数一、检查Calibration Done情况 安装完毕,激活成功后。 右键------>选项------>设置, 打开适配器信息,查看Calibra…...
YOLOV5输出的txt里面有什么猫腻(用于图像分类竞赛中提升图像信息密度)
背景概括: kaggle最近举办了一场医学乳腺癌检测的比赛(图像分类) 比赛官网地址 给的数据是dcm的专业的医学格式,自己通过DICOM库转为png后,发现该图像胸部不同的患者乳腺大小不一,简言之乳腺的CT有效图在…...
vue+axios常用操作
vueaxios常用操作vue2axios请求拦截依赖项http.jsvue2axios设置请求头依赖项http.js获取并设置请求头api.jsa.vuevue2axios请求拦截 依赖项 “vue”: “^2.6.11” “axios”: “^0.21.0” “element-ui”: “^2.13.2”(做弹窗提示,可以不用) http.js // 引入axi…...
Xshell连接阿里云服务器搭建网站
一、建设一个网站的基本要求 申请一个独立的域名申请一台云服务器ECS在服务器上安装网站环境,如:Apache发布网站内容至云服务器将第一步注册的域解析至云服务器的外网IP地址进行ICP备案 二、用户访问网站的过程 在浏览器上输入域名浏览器自动调用DNS&…...
Spring Boot面试题精选汇总
🤟致敬读者 🟩感谢阅读🟦笑口常开🟪生日快乐⬛早点睡觉 📘博主相关 🟧博主信息🟨博客首页🟫专栏推荐🟥活动信息 文章目录 Spring Boot面试题精选汇总⚙️ **一、核心概…...
微信小程序云开发平台MySQL的连接方式
注:微信小程序云开发平台指的是腾讯云开发 先给结论:微信小程序云开发平台的MySQL,无法通过获取数据库连接信息的方式进行连接,连接只能通过云开发的SDK连接,具体要参考官方文档: 为什么? 因为…...
图表类系列各种样式PPT模版分享
图标图表系列PPT模版,柱状图PPT模版,线状图PPT模版,折线图PPT模版,饼状图PPT模版,雷达图PPT模版,树状图PPT模版 图表类系列各种样式PPT模版分享:图表系列PPT模板https://pan.quark.cn/s/20d40aa…...
如何理解 IP 数据报中的 TTL?
目录 前言理解 前言 面试灵魂一问:说说对 IP 数据报中 TTL 的理解?我们都知道,IP 数据报由首部和数据两部分组成,首部又分为两部分:固定部分和可变部分,共占 20 字节,而即将讨论的 TTL 就位于首…...
智能分布式爬虫的数据处理流水线优化:基于深度强化学习的数据质量控制
在数字化浪潮席卷全球的今天,数据已成为企业和研究机构的核心资产。智能分布式爬虫作为高效的数据采集工具,在大规模数据获取中发挥着关键作用。然而,传统的数据处理流水线在面对复杂多变的网络环境和海量异构数据时,常出现数据质…...
关键领域软件测试的突围之路:如何破解安全与效率的平衡难题
在数字化浪潮席卷全球的今天,软件系统已成为国家关键领域的核心战斗力。不同于普通商业软件,这些承载着国家安全使命的软件系统面临着前所未有的质量挑战——如何在确保绝对安全的前提下,实现高效测试与快速迭代?这一命题正考验着…...
并发编程 - go版
1.并发编程基础概念 进程和线程 A. 进程是程序在操作系统中的一次执行过程,系统进行资源分配和调度的一个独立单位。B. 线程是进程的一个执行实体,是CPU调度和分派的基本单位,它是比进程更小的能独立运行的基本单位。C.一个进程可以创建和撤销多个线程;同一个进程中…...
LCTF液晶可调谐滤波器在多光谱相机捕捉无人机目标检测中的作用
中达瑞和自2005年成立以来,一直在光谱成像领域深度钻研和发展,始终致力于研发高性能、高可靠性的光谱成像相机,为科研院校提供更优的产品和服务。在《低空背景下无人机目标的光谱特征研究及目标检测应用》这篇论文中提到中达瑞和 LCTF 作为多…...
React从基础入门到高级实战:React 实战项目 - 项目五:微前端与模块化架构
React 实战项目:微前端与模块化架构 欢迎来到 React 开发教程专栏 的第 30 篇!在前 29 篇文章中,我们从 React 的基础概念逐步深入到高级技巧,涵盖了组件设计、状态管理、路由配置、性能优化和企业级应用等核心内容。这一次&…...
聚六亚甲基单胍盐酸盐市场深度解析:现状、挑战与机遇
根据 QYResearch 发布的市场报告显示,全球市场规模预计在 2031 年达到 9848 万美元,2025 - 2031 年期间年复合增长率(CAGR)为 3.7%。在竞争格局上,市场集中度较高,2024 年全球前十强厂商占据约 74.0% 的市场…...
