C++ --红黑树
红黑树的五大性质每个节点是红色或黑色根节点是黑色所有叶子NIL空节点都是黑色红色节点的两个子节点都是黑色即不能有连续的红节点从任一节点到其每个叶子的所有路径都包含相同数目的黑色节点黑色高度一致节点定义与辅助函数#include iostream using namespace std; enum Color { RED, BLACK }; templatetypename Key, typename Value struct RBNode { Key key; Value value; Color color; RBNode* left; RBNode* right; RBNode* parent; RBNode(Key k, Value v, Color c RED) : key(k), value(v), color(c), left(nullptr), right(nullptr), parent(nullptr) {} };辅助函数// 判断节点颜色空节点视为黑色 templatetypename Key, typename Value bool isRed(RBNodeKey, Value* node) { return node ! nullptr node-color RED; } // 左旋 templatetypename Key, typename Value void leftRotate(RBNodeKey, Value* root, RBNodeKey, Value* x) { RBNodeKey, Value* y x-right; x-right y-left; if (y-left) y-left-parent x; y-parent x-parent; if (!x-parent) root y; else if (x x-parent-left) x-parent-left y; else x-parent-right y; y-left x; x-parent y; } // 右旋对称 templatetypename Key, typename Value void rightRotate(RBNodeKey, Value* root, RBNodeKey, Value* y) { RBNodeKey, Value* x y-left; y-left x-right; if (x-right) x-right-parent y; x-parent y-parent; if (!y-parent) root x; else if (y y-parent-left) y-parent-left x; else y-parent-right x; x-right y; y-parent x; }旋转的具体步骤插入前的核心认知1为什么新节点必须是红色核心原因如果插入黑色节点会立即违反性质5黑色高度一致因为这条路径多了一个黑色节点修复起来需要调整整棵树。而插入红色节点只可能违反性质4不能有连续红节点这种冲突是局部的可以通过旋转和变色在有限范围内修复。插入操作的两阶段阶段操作复杂度阶段1标准BST插入找到位置挂载新红节点O(log n)阶段2修复红黑性质处理连续红冲突O(log n) 但旋转次数≤2阶段1标准BST插入templatetypename Key, typename Value void insert(RBNodeKey, Value* root, Key key, Value value) { // 步骤1创建新节点红色 RBNodeKey, Value* z new RBNodeKey, Value(key, value, RED); // 步骤2BST查找插入位置 RBNodeKey, Value* y nullptr; // y最终指向z的父节点 RBNodeKey, Value* x root; // x是游标指针 while (x ! nullptr) { y x; // 记录父节点 if (key x-key) x x-left; else if (key x-key) x x-right; else { // 键已存在更新值释放新节点 x-value value; delete z; return; } } // 步骤3挂载新节点 z-parent y; if (y nullptr) { root z; // 树为空新节点就是根 } else if (key y-key) { y-left z; } else { y-right z; } // 步骤4修复红黑性质 insertFixup(root, z); }细节解读y指针记录当前节点的父节点如果树为空新节点直接成为根但根必须是黑色修复阶段会处理。如果键已存在我们直接更新值并返回不进行任何颜色修复。阶段2插入修复修复的触发条件只有一种情况需要修复父节点是红色因为新节点也是红色形成连续红。如果父节点是黑色树已经满足所有红黑性质无需任何操作。修复的总体策略while (父节点是红色) { 判断父节点是祖父的左孩子还是右孩子对称处理 获取叔叔节点的颜色 if (叔叔是红色) { 处理情况1颜色翻转 } else { // 叔叔是黑色或null if (当前节点是父节点的内侧孩子) { 处理情况2旋转父节点转换为情况3 } 处理情况3旋转祖父节点 变色 } } 最后确保根是黑色三种情况详解假设父节点是祖父的左孩子情况1叔叔是红色G(黑) G(红) / \ ---- / \ P(红) U(红) P(黑) U(黑) / / z(红) z(红)操作将父节点P设为黑色将叔叔U设为黑色将祖父G设为红色为了保持黑色高度将z指针上移到G继续循环检查为什么这样做有效局部黑色高度不变原来路径G-P-z有1个黑G现在G-P有1个黑PG-U有1个黑U黑色高度保持。但祖父变红后可能与其父节点形成连续红所以需要继续向上检查。代码实现if (isRed(y)) { // y是叔叔节点 z-parent-color BLACK; y-color BLACK; z-parent-parent-color RED; z z-parent-parent; // 上移两层 }情况2叔叔是黑色叔叔节点为空也默认是黑色NIL且z是父节点的右孩子内侧情况G(黑) G(黑) / / P(红) z(红) \ / z(红) P(红)操作将z指向父节点P对z进行左旋为什么要旋转当前z是右孩子属于内侧插入直接右旋祖父会让z跑到左边但结构不对称。通过左旋父节点将情况转化为情况3z变成左孩子即外侧情况。注意旋转后颜色不变因为还没完成修复代码实现if (z z-parent-right) { z z-parent; leftRotate(root, z); }情况3叔叔是黑色且z是父节点的左孩子外侧情况G(黑) P(黑) / / \ P(红) z(红) G(红) / z(红)操作将父节点P设为黑色将祖父G设为红色对祖父G进行右旋为什么这样做有效旋转后P成为新的子树根G变成P的右孩子。P原来是红色现在变黑保证不会与上层形成连续红。G原来是黑色现在变红但它的左右子树黑色高度保持不变。黑色高度验证原路径z→P→G黑色节点数 1只有G新路径z→P→G黑色节点数 1只有P代码实现z-parent-color BLACK; z-parent-parent-color RED; rightRotate(root, z-parent-parent); // 旋转后循环可以结束因为z的父节点已变黑对称情况父节点是祖父的右孩子完全对称只需将左和右互换else { // 父节点是祖父的右孩子 RBNodeKey, Value* y z-parent-parent-left; // 叔叔在左 if (isRed(y)) { // 情况1对称 z-parent-color BLACK; y-color BLACK; z-parent-parent-color RED; z z-parent-parent; } else { if (z z-parent-left) { // 情况2对称z是左孩子 z z-parent; rightRotate(root, z); } // 情况3对称 z-parent-color BLACK; z-parent-parent-color RED; leftRotate(root, z-parent-parent); } }完整插入修复流程图开始插入新节点为红色 ↓ 父节点是红色 ↓ 是 祖父存在且叔叔是红色 ↓ 是 ↓ 否 情况1颜色翻转 叔叔是黑色 ↓ ↓ z上移到祖父 z是父节点的内侧孩子 继续循环 ↓ 是 ↓ 否 情况2旋转父节点 情况3旋转祖父变色 ↓ ↓ 转换为情况3 修复完成退出循环 ↓ 情况3旋转祖父变色 ↓ 修复完成退出循环 ↓ 确保根为黑色 ↓ 结束复杂度和性能分析指标值说明时间O(log n)BST查找O(log n) 修复最多O(log n)旋转次数≤2次情况3后退出情况2转情况3也算1次颜色翻转次数≤O(log n)可能一直上移到根空间O(1)只使用了几个指针变量为什么旋转最多2次情况1颜色翻转不会旋转但可能向上传播情况2旋转父节点后必然进入情况3情况3旋转祖父节点后必然退出循环所以最多2次旋转情况2情况3各一次完整的insertFixup代码templatetypename Key, typename Value void insertFixup(RBNodeKey, Value* root, RBNodeKey, Value* z) { // 只要父节点是红色就需要修复 while (z ! root isRed(z-parent)) { // 分支A父节点是祖父的左孩子 if (z-parent z-parent-parent-left) { RBNodeKey, Value* uncle z-parent-parent-right; // ★情况1叔叔是红色 → 颜色翻转 if (isRed(uncle)) { z-parent-color BLACK; uncle-color BLACK; z-parent-parent-color RED; z z-parent-parent; // 上移两层继续检查 } else { // ★情况2z是右孩子内侧→ 左旋父节点 if (z z-parent-right) { z z-parent; leftRotate(root, z); } // ★情况3z是左孩子外侧→ 右旋祖父 变色 z-parent-color BLACK; z-parent-parent-color RED; rightRotate(root, z-parent-parent); // 此时父节点已变黑循环必然结束 } } else { // 分支B父节点是祖父的右孩子完全对称 RBNodeKey, Value* uncle z-parent-parent-left; if (isRed(uncle)) { z-parent-color BLACK; uncle-color BLACK; z-parent-parent-color RED; z z-parent-parent; } else { if (z z-parent-left) { // 内侧右孩子的左孩子 z z-parent; rightRotate(root, z); } z-parent-color BLACK; z-parent-parent-color RED; leftRotate(root, z-parent-parent); } } } // 保证根永远是黑色处理情况1传播到根的情况 root-color BLACK; }总结插入操作的思维导图红黑树插入├── 阶段1BST插入│ ├── 查找位置y记录父节点│ ├── 挂载新节点红色│ └── 更新父指针│└── 阶段2修复while父为红├── 父是祖父左孩子│ ├── 叔红 → 翻转颜色上移│ └── 叔黑│ ├── z是右孩子 → 左旋父转情况3│ └── z是左孩子 → 右旋祖父变色结束│└── 父是祖父右孩子对称├── 叔红 → 翻转颜色上移└── 叔黑├── z是左孩子 → 右旋父转情况3└── z是右孩子 → 左旋祖父变色结束最后根变黑强制

相关新闻

【AI需求预测分析黄金法则】:20年实战总结的5大避坑指南与实时优化框架

【AI需求预测分析黄金法则】:20年实战总结的5大避坑指南与实时优化框架

更多请点击: https://intelliparadigm.com 第一章:AI需求预测分析黄金法则的底层逻辑 AI需求预测并非单纯依赖历史数据拟合,其本质是构建“业务动因—数据表征—模型响应”的闭环因果链。脱离业务语义的数据驱动建模,极易陷入过拟…

2026/7/30 3:45:31阅读更多 →
Python分支结构实战:从if-else到编程决策思维

Python分支结构实战:从if-else到编程决策思维

1. 项目概述:从“头哥”平台看Python分支结构的实战价值最近在“头哥”这个编程实践平台上,看到不少朋友在攻克实验二——分支结构程序设计。这让我想起了自己刚学Python那会儿,面对if-elif-else时那种既熟悉又有点无从下手的感觉。熟悉是因为…

2026/7/30 3:45:31阅读更多 →
AI制度文档编写进入“强监管倒计时”:2024Q3起未通过AI治理文档合规性审查=项目自动终止

AI制度文档编写进入“强监管倒计时”:2024Q3起未通过AI治理文档合规性审查=项目自动终止

更多请点击: https://kaifayun.com 第一章:AI制度文档编写的时代背景与强监管逻辑 人工智能技术正以前所未有的速度渗透至金融、医疗、政务、教育等关键领域,其自主决策能力与规模化部署能力在提升效率的同时,也显著放大了算法偏…

2026/7/30 3:45:31阅读更多 →
PX4无人机Offboard模式实战:从MAVROS通信到真机部署全解析

PX4无人机Offboard模式实战:从MAVROS通信到真机部署全解析

1. 项目概述与核心价值如果你已经跟着前两篇内容,成功搭建了PX4的仿真环境,并且让无人机在Gazebo里飞了起来,那么恭喜你,你已经迈出了坚实的第一步。但很多朋友可能会发现,自己手里的无人机好像不太“听话”——它要么…

2026/7/30 4:57:47阅读更多 →
555定时器工作原理与三种工作模式详解:从基础电路到实战应用

555定时器工作原理与三种工作模式详解:从基础电路到实战应用

在电子电路设计领域,555定时器芯片是当之无愧的经典。这款诞生于1970年代的集成电路,因其简单可靠、成本低廉、应用广泛而经久不衰。无论是学生进行电子实验,还是工程师设计实际产品,掌握555定时器都是必备的基础技能。555定时器的…

2026/7/30 4:57:47阅读更多 →
DOB灯板技术解析:从集成驱动原理到应用选型指南

DOB灯板技术解析:从集成驱动原理到应用选型指南

1. 从“灯珠驱动”到“一块板”:DOB灯板的本质是什么?如果你最近在逛灯具市场,或者自己动手改造家里的照明,可能会听到一个词:DOB灯板。商家可能会告诉你,这个灯板“更简单”、“更便宜”、“更稳定”。听起…

2026/7/30 4:57:47阅读更多 →
GPT-5.6 来了,Codex 没了,我想用它做个旧手机监控 App

GPT-5.6 来了,Codex 没了,我想用它做个旧手机监控 App

大家可能听说了,7 月 10 日OpenAI 搞了一场发布会,发布了GPT-5.6,包含三个新模型。查了一下GPT-5.6 系列的三个型号:Sol(旗舰)、Terra(均衡)、Luna(性价比)名…

2026/7/30 4:57:47阅读更多 →
多智能体系统实战:从AutoGen到ChatDev的架构解析

多智能体系统实战:从AutoGen到ChatDev的架构解析

1. 多智能体系统概述:从单兵作战到团队协作的进化在大型语言模型(LLM)应用领域,我们正经历着从单一智能体到多智能体协作的范式转变。就像软件开发从单体架构演进到微服务架构一样,多智能体系统通过任务分解和角色分工…

2026/7/30 4:57:47阅读更多 →
C++枚举深度解析:从传统enum到enum class的类型安全实践

C++枚举深度解析:从传统enum到enum class的类型安全实践

1. 项目概述:为什么C程序员绕不开enum? 干了这么多年C,从学生时代的课程设计到后来参与的大型商业引擎开发, enum (枚举)这个看似简单的工具,几乎在每个项目里都会出现。新手用它来定义几个状…

2026/7/30 4:55:47阅读更多 →
覆盖国产 + 海外 + 开源模型,OpenClaw 2.7.9 Windows/Mac 双端部署详解

覆盖国产 + 海外 + 开源模型,OpenClaw 2.7.9 Windows/Mac 双端部署详解

🔹 工具基础介绍 OpenClaw 是开源生态中一款实用性较强的本地智能工具,凭借本地离线运行、可视化图形操作和任务自动化三大核心特性,赢得了众多用户的青睐。与普通在线对话AI工具不同,它属于能够直接操控本机软硬件的智能数字员工…

2026/7/29 9:47:45阅读更多 →
伺服阀焊完微漏毁整机?精密激光焊接三关锁住高压

伺服阀焊完微漏毁整机?精密激光焊接三关锁住高压

所谓液压伺服阀体的精密激光焊接,是用激光束对阀座壳体(通常为不锈钢或铝合金)进行密封焊接,使阀体在21-35MPa的高压液压油或压缩气体中长期运行而不发生介质泄漏。液压伺服阀是高端液压系统的"大脑"。从航空航天飞行控…

2026/7/29 7:00:19阅读更多 →
D2DX:三步实现《暗黑破坏神2》高清宽屏体验的终极指南

D2DX:三步实现《暗黑破坏神2》高清宽屏体验的终极指南

D2DX:三步实现《暗黑破坏神2》高清宽屏体验的终极指南 【免费下载链接】d2dx D2DX is a complete solution to make Diablo II run well on modern PCs, with high fps and better resolutions. 项目地址: https://gitcode.com/gh_mirrors/d2/d2dx 你是否还在…

2026/7/29 7:58:51阅读更多 →
3分钟解锁iOS应用自由:TrollInstallerX让你的iPhone摆脱安装限制 [特殊字符]

3分钟解锁iOS应用自由:TrollInstallerX让你的iPhone摆脱安装限制 [特殊字符]

3分钟解锁iOS应用自由:TrollInstallerX让你的iPhone摆脱安装限制 🚀 【免费下载链接】TrollInstallerX A TrollStore installer for iOS 14.0 - 16.6.1 项目地址: https://gitcode.com/gh_mirrors/tr/TrollInstallerX 你是否曾经因为iOS系统的严格…

2026/7/30 0:00:58阅读更多 →
[GESP202606 四级] 扫雷

[GESP202606 四级] 扫雷

B4557 [GESP202606 四级] 扫雷 https://www.luogu.com.cn/problem/B4557 中国计算机学会(CCF)2026年6月C四级讲解——扫雷 https://www.bilibili.com/video/BV1MCMg6AEXR/ B4557 [GESP202606 四级] 扫雷 https://www.bilibili.com/video/BV1ZKTj6ZEVh/ 2…

2026/7/30 0:00:58阅读更多 →
Windows驱动存储终极清理工具:DriverStoreExplorer完全指南

Windows驱动存储终极清理工具:DriverStoreExplorer完全指南

Windows驱动存储终极清理工具:DriverStoreExplorer完全指南 【免费下载链接】DriverStoreExplorer Driver Store Explorer 项目地址: https://gitcode.com/gh_mirrors/dr/DriverStoreExplorer 您是否曾因Windows系统盘空间不足而烦恼?是否遇到过设…

2026/7/30 0:00:58阅读更多 →
YOLOv8推理性能优化:从1.2FPS到35FPS的全链路加速实践

YOLOv8推理性能优化:从1.2FPS到35FPS的全链路加速实践

如果你在部署 YOLOv8 时,发现推理速度只有可怜的 1-2 FPS,而别人的演示视频却能跑到 30 FPS 以上,那么问题很可能不在模型本身,而在于你的整个处理链路。很多开发者拿到一个训练好的 YOLOv8 模型后,会直接使用官方示例…

2026/7/30 0:27:26阅读更多 →
Coze与Dify对比指南:低代码AI应用开发从入门到实战

Coze与Dify对比指南:低代码AI应用开发从入门到实战

1. 从零到一:为什么你需要了解 Coze 和 Dify?如果你对 AI 应用开发感兴趣,但一看到“大模型”、“智能体”、“工作流”这些词就头疼,觉得门槛太高,那这篇文章就是为你准备的。很多开发者,包括我自己&#…

2026/7/30 4:47:18阅读更多 →
AI生图工具怎么选?2026年6月版实测对比

AI生图工具怎么选?2026年6月版实测对比

做自媒体的朋友应该都有体会:配图一直是个让人头疼的问题。2026年,AI生图工具已经非常成熟了,但工具太多反而不知道怎么选。以下是截至2026年6月我对主流AI生图工具的实测对比。Midjourney V8.1:速度之王2026年6月11日&#xff0c…

2026/7/29 14:26:42阅读更多 →