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:28 阅读更多 →
Python分支结构实战:从if-else到编程决策思维

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

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

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

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

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

2026/7/30 3:45:28 阅读更多 →

最新新闻

C++面向对象编程核心:类与对象的封装、构造与内存管理详解

C++面向对象编程核心:类与对象的封装、构造与内存管理详解

1. 项目概述:为什么C的类和对象是基石? 如果你刚开始接触C,或者从C语言转过来,可能会觉得“类”和“对象”这两个词既熟悉又陌生。熟悉是因为到处都在提“面向对象编程”,陌生是因为它和之前写C语言时那种“函数结构体…

2026/7/30 3:55:32 阅读更多 →
Spring Boot用户状态检测系统:睡眠状态识别与智能提醒实战

Spring Boot用户状态检测系统:睡眠状态识别与智能提醒实战

最近在开发一个智能提醒系统时,遇到了一个有趣的技术需求:如何准确识别用户状态并触发相应的提醒逻辑。特别是在睡眠状态检测这个场景下,传统的方案往往依赖硬件传感器或复杂的生物特征分析,但在某些轻量级应用中,我们…

2026/7/30 3:55:32 阅读更多 →
Java中文乱码全解析:从字符编码原理到实战解决方案

Java中文乱码全解析:从字符编码原理到实战解决方案

1. 从“锟斤拷”说起:为什么中文乱码是Java开发者的必修课如果你在Java开发中没见过“锟斤拷”或者“烫烫烫”,那你的职业生涯可能还不够完整。这当然是个玩笑,但背后反映的是一个严肃且普遍的问题:中文乱码。它就像一个幽灵&…

2026/7/30 3:55:32 阅读更多 →
Python数据分析实战:从数据清洗到可视化呈现的完整行业盈利分析流程

Python数据分析实战:从数据清洗到可视化呈现的完整行业盈利分析流程

1. 项目缘起:为什么我们需要一个“闯关式”的行业盈利分析实验?最近在带团队做数据分析培训,发现一个挺普遍的问题:很多朋友学了Python、Pandas、Matplotlib,看教程时感觉都懂了,一到自己动手分析真实的行业…

2026/7/30 3:55:32 阅读更多 →
verilog HDLBits刷题[Finite State Machines]“Lemmings2”---Lemmings2

verilog HDLBits刷题[Finite State Machines]“Lemmings2”---Lemmings2

1、题目 See also: Lemmings1. In addition to walking left and right, Lemmings will fall (and presumably go "aaah!") if the ground disappears underneath them. In addition to walking left and right and changing direction when bumped, when ground0…

2026/7/30 3:55:31 阅读更多 →
C/C++项目配置管理:深入解析INI文件操作库的设计与工程实践

C/C++项目配置管理:深入解析INI文件操作库的设计与工程实践

1. 项目概述:为什么IniFile源码值得深挖?在C/C开发领域,配置文件处理是每个项目几乎都会遇到的“基础设施”问题。无论是桌面应用、嵌入式系统还是后台服务,总需要一种简单、直观的方式来存储和读取程序设置。而INI文件&#xff0…

2026/7/30 3:54:31 阅读更多 →

日新闻

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

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

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

2026/7/30 0:00:13 阅读更多 →
如何3步掌握Video Download Helper:网页视频下载的完整实战指南

如何3步掌握Video Download Helper:网页视频下载的完整实战指南

如何3步掌握Video Download Helper:网页视频下载的完整实战指南 【免费下载链接】VideoDownloadHelper Chrome Extension to Help Download Video for Some Video Sites. 项目地址: https://gitcode.com/gh_mirrors/vi/VideoDownloadHelper 你是否曾经在浏览…

2026/7/30 0:00:13 阅读更多 →
“双减”后首个AI备课压力测试报告:覆盖32所中小学的176节AI辅助课,暴露4大隐性增负节点

“双减”后首个AI备课压力测试报告:覆盖32所中小学的176节AI辅助课,暴露4大隐性增负节点

更多请点击: https://intelliparadigm.com 第一章:AI 教师备课辅助 AI 教师备课辅助系统正逐步成为教育数字化转型的核心支撑工具,它并非替代教师,而是通过语义理解、知识图谱与多模态生成能力,将教师从重复性劳动中解…

2026/7/30 0:00:13 阅读更多 →

周新闻

深度学习道路桥梁裂缝检测系统 道路桥梁裂缝检测数据集 道路桥梁病害识别检测数据集

深度学习道路桥梁裂缝检测系统 道路桥梁裂缝检测数据集 道路桥梁病害识别检测数据集

深度学习道路桥梁裂缝检测系统 数据集6000张 完整源码已标注数据集训练好的模型环境配置教程程序运行说明文档,可以直接使用!系统支持图片、视频、摄像头等多种方式检测裂缝,功能强大实用。 1数据集6000张 8各类别

2026/7/29 22:18:20 阅读更多 →
深度学习YOLO模型如何训练 PUBG 绝地求生目标检测数据集

深度学习YOLO模型如何训练 PUBG 绝地求生目标检测数据集

pubg数据集 精选原图1.42万数据 1.49万标签 无任何重复、算法增强或冗余图像! pubg绝地求生目标检测数据集 1分类:e_body,14905个标签,txt格式 共计14244张图,99%为640*640尺寸图像 适合yolo目标检测、AI训练关键词&am…

2026/7/29 14:34:28 阅读更多 →
Apex英雄目标检测数据集 深度学习框架YOLO如何训练APEX数据集

Apex英雄目标检测数据集 深度学习框架YOLO如何训练APEX数据集

Apex检测数据集数据集详情检测类别: allies enemy tag图片总量:7247张训练集:5139张验证集:1425张测试集:683张标注状态:全部已标注,即拿即用数据格式:支持YOLO格式及其他格式&#…

2026/7/29 15:00:03 阅读更多 →

月新闻