C++——【红黑树】原理详解:定义、性质、插入变色与旋转实现

发布时间:2026/10/24 6:33:39

C++——【红黑树】原理详解:定义、性质、插入变色与旋转实现 个人主页ꪔ小林Y✨个人专栏《C小白闯关日记》《C语言小白闯关日记》《数据结构入门——从原理到实战》,《拾光Linux》《网络安全》代码信条每一行代码都是成长的脚印每一次调试成功都是对坚持的回应目录红黑树1.红黑树定义及规则2.红黑树的实现1红黑树的基本结构2红黑树的插入红黑树插入代码实现红黑树1.红黑树定义及规则定义红黑树是一颗二叉搜索树他的每个结点增加一个存储位来表示结点的颜色红/黑。通过对任何一条从根到叶子的路径上各个节点的颜色进行约束红黑树确保没有一条路径会比其他路径长出2倍因而接近平衡。规则1每个节点不是红色就是黑色2根节点是黑色注意红黑树可以是空树3如果一个节点是红色则他的两个孩子节点必须是黑色也就是说任意一条路径不会有连续的红色节点4对于任意一个节点从该节点到其所有NULL节点的简单路径上均包含相同数量的黑色节点红黑树增删查改时间复杂度O(logN)2.红黑树的实现1红黑树的基本结构//枚举表示颜色enumColour{RED,BLACK};//key/value实现templateclassK,classVstructRETreeNode{pairK,V_kv;RETreeNodeK,V*_left;RETreeNodeK,V*_right;RETreeNodeK,V*_parent;Colour _col;RETreeNode(constpatrK,vkv):_kv(kv),_left(nullptr),_right(nullptr),_parent(nullptr){}};templateclassK,classVclassRBTree{typedefRBTreeNodeK,VNode;public:private:Node*_rootnulptr;};2红黑树的插入插入一个值按照二叉搜索树的规则进行插入须符合以下规则空树插入新增节点为黑色非空树插入新增节点必须为红色。否则破坏规则4。非空树插入后新增为红如果父亲节点是黑色没有违反任何规则插入结束。非空树插入后新增为红如果父亲节点是红色违反规则3进一步分析 (假设新增节点c(cur),父亲节点p爷爷节点g叔叔节点u)3.1情况一变色叔叔存在且为红即c为红p为红u存在且为红则将p和u变黑g变红。把g当做新的c继续向上处理。若g就是根则再变为黑3.2情况二单旋变色叔叔不存在或者存在且为黑c为红p为红g为黑u不存在或者存在且为黑。u不存在则c一定是新增节点u存在且为黑则c一定不是新增c之前是黑色的是在c的子树中插入符合情况一变色将c从黑色变成红色更新上来的。这里单纯的变色无法解决问题需要变色旋转如果p是g的左c是p的左那么先以g为旋转点进行右单旋再把p变黑g变红即可。p变成课这颗树新的根这样子树黑色结点的数量不变没有连续的红色结点了且不需要往上更新因为c的父亲是黑色还是红色或者空都不违反规则。如果p是g的右c是p的右那么先以g为旋转点进行左单旋再把p变黑g变红即可。p变成课这颗树新的根。例3.3情况三双旋变色如果p是g的左c是p的右那么先以p为旋转点进行左单旋再以g为旋转点进行右单旋再把c变黑g变红即可。c变成课这颗树新的根。如果p是g的右c是p的左那么先以p为旋转点进行右单旋再以g为旋转点进行左单旋再把c变黑g变红即可。c变成课这颗树新的根。例红黑树插入代码实现boolInsert(constpairK,Vkv){//空树插入黑色节点if(_rootnullptr){_rootnewNode(kv);_root-_colBLACK;returntrue;}Node*parentnullptr;Node*cur_root;while(cur){if(cur-_kv.firstkv.first){parentcur;curcur-_right;}elseif(cur-_kv.firstkv.first){parentcur;curcur-_left;}else{returnfalse;}}//新增红色curnewNode(kv);cur-_colRED;if(parent-_kv.firstkv.first){parent-_rightcur;}else{parent-_leftcur;}cur-_parentparent;//父亲存在且为红while(parentparent-_colRED){Node*grandfatherparent-_parent;if(grandfather-_leftparent){// g// p u//cNode*unclegrandfather-_right;//情况一叔叔存在且为红,变色即可if(uncleuncle-_colRED){//变色继续往上处理parent-_coluncle-_colBLACK;grandfather-_colRED;curgrandfather;parentcur-_parent;}else// 叔叔不存在或者叔叔存在且为黑{// g// p u//c// 情况二单旋变色if(curparent-_left){RotateR(geandfather);parent-_colBLACK;grandfather-_colRED;}else{// g// p u// c//情况三双旋变色RotateL(parent);RotateR(grandfather);cur-_colBLACK;grandfather-_colRED;}break;}}else{// g// u pNode*unclegrandfather-_left;//情况一叔叔存在且为红,变色即可if(uncleuncle-_colRED){//变色继续往上处理parent-_coluncle-_colBLACK;grandfather-_colRED;curgrandfather;parentcur-_parent;}else// 叔叔不存在或者叔叔存在且为黑{// g// u p// c// 情况二单旋变色if(curparent-_right){RotateL(geandfather);parent-_colBLACK;grandfather-_colRED;}else{// g// u p// c//情况三双旋变色RotateR(parent);RotateL(grandfather);cur-_colBLACK;grandfather-_colRED;}break;}}}//不存在父亲_root-_colBLACK;returntrue;}到这儿本期C——【红黑树】定义及其实现的内容就结束了。如果文中有表述不准的地方或是你有更清晰的理解思路强烈欢迎在评论区留言交流——技术路上多碰撞才能更快进步觉得内容对你有帮助的话别忘了点赞❤️➕收藏方便后续回顾复习想跟着一起系统学习数据结构的朋友也可以点击关注下一期我们会聚焦更进一步的学习。不见不散✌️
延伸阅读

更多相关文章

2026/10/24 6:33:39

HDLHorse重磅发布|大幅提升设计仿真的效率

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/24 6:33:39

全网首发拆解JEV决策大模型为什么爆火???

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/24 6:33:39

Uni-Dock 实战测评:源码编译、四体系基准与批量吞吐验证

本文收录于专栏 gnina系列 —— 专栏系统覆盖分子对接引擎选型、GPU 加速虚拟筛选与打分函数评估,点击订阅可跟踪后续更新。 你看过 Uni-Dock 论文里"超千倍加速、100 块 V100 十二小时筛完 3820 万分子"的说法,想知道拿到自己这张消费级 GPU …

2026/10/24 7:33:42

科莱特 SAP FICO 学员真实经历:一个普通财务人的成长复盘

前面四篇,我写了为什么转 SAP、怎么学、怎么面、怎么进项目活下来。这一篇,是这个系列的收尾。不聊操作、不聊面试技巧。我想聊聊这整件事给我的认知冲击,走到今天,脑子里真正变了什么。如果你也在犹豫要不要转、转了之后值不值、…

2026/10/24 7:33:42

Swift 常量详解:let 与 const 的正确使用方式

1. 引言在 Swift 编程语言中,常量是构建安全、可预测代码的基础。与变量不同,常量一旦赋值便不可更改,这不仅能防止意外修改,还能让代码的意图更加清晰。本文将深入讲解 Swift 常量的定义、使用场景以及最佳实践,并通过…

2026/10/24 7:33:42

坚果云收件箱的10个神用法:从收集周报到客户合同文件自动归档

文章目录一、文件收集的「三大灾难」二、收件箱的核心机制2.1 收件箱 vs 传统收集方式2.2 收件箱的创建步骤三、10个神用法逐一拆解用法一:团队周报收集用法二:学生作业提交用法三:客户合同签约用法四:供应商报价收集用法五&#…

2026/10/24 7:33:42

SSD1322 OLED驱动芯片底层机制拆解:从接口时序到灰度表

简介:SSD1322数据手册是Solomon Systech公司发布的高性能有机发光二极管驱动控制器官方技术文档,面向显示驱动开发工程师、嵌入式硬件设计人员和屏体调试工程师,用于解决芯片选型、引脚连接、寄存器配置以及显示时序匹配等问题。资源以单个PD…

2026/10/24 7:33:42

响应式数据流实战:从零构建实时数据处理内核

1. 从“rea”这个标题说起:一个被低估的缩写背后藏着什么第一次看到“rea”这个标题,我承认自己愣了几秒。它太短了,短到像是一个被截断的单词,又像是一个随手敲下的代号。但恰恰是这种极简的标题,往往藏着最值得深挖的…

2026/10/24 7:28:42

多智能体协作框架agency-agents:架构设计与工程实践

1. 从"agency-agents"这个标题说起:一个多智能体协作框架的完整拆解第一次看到"agency-agents"这个命名的时候,我的直觉是:这大概率是一个围绕"代理"和"代理机构"概念构建的多智能体协作系统。拆开来…

2026/10/23 22:56:35

金融AI落地指南:从调研报告到技术选型与工程实践

简介:这份PDF报告聚焦2025年金融服务业中国AI现状与趋势,面向金融科技从业者、AI战略规划人员及关注行业数字化转型的研究者,帮助读者把握生成式AI在银行、支付、交易等场景中的落地路径与投资方向。资源包内含1个PDF文件,大小约1…

2026/10/24 0:02:40

MATLAB缩进快捷键与批量格式化实战指南

1. 被自动缩进折磨的那些年如果你写过MATLAB代码,大概率经历过这种场景:从某个文档、网页或者聊天记录里复制了一段代码,粘贴进编辑器之后,每一行前面都带着莫名其妙的空格,有的行首是四个空格,有的是一个T…

2026/10/24 0:02:40

用Poco实现Qt风格信号与槽的跨平台C++方案

简介:本资源是一份面向C中级开发者的技术实践工程,聚焦于在非Qt框架环境下模拟实现Qt核心通信机制——信号与槽,借助Poco网络库的事件系统完成解耦式对象通信。适用于需在跨平台C项目中引入松耦合回调机制、但受限于无法集成Qt依赖的开发场景…

2026/10/24 0:02:40

ESXi裸机虚拟化安装指南:从硬件兼容到虚拟机部署

1. 为什么还要折腾ESXi:从一台闲置机器说起手里攒了几台淘汰下来的迷你主机,配置不算差,i5加16G内存,扔了可惜,装个桌面系统又觉得浪费。这种场景下,ESXi就成了一个绕不开的选择。它是一套裸机虚拟化平台&a…

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
☎咨询二维码 ☎ ↑