news 2026/6/10 9:48:42

C++进阶数据结构之红黑树

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
C++进阶数据结构之红黑树

1.红黑树的概念

红黑树是一颗二叉搜索树,他的每个节点增加一个存储位来表示节点的颜色,可以是红色或者黑色。通过对任何一条从根到叶子的路径上各个节点的颜色进行约束,红黑树确保没有一条路径会比其他路径长出两倍,因而是接近平衡的

1.1红黑树的规则

1.每个结点不是红色就是黑色

2.根结点是黑色的

3.如果一个结点是红色的,则它的两个孩子结点必定是黑色的,也就是说,任意一条路径不会有连续的红色结点

4.对于任意一个结点,从该结点到其所有的NULL结点的简单路径上,均包含相同数量的黑色结点

2.2.1红黑树插入过程

1.插入值按二叉搜索树规则进行插入,插入后我们观察是否符合红黑树四条规则

2.如果是空树插入,新增结点是黑色结点,如果是非空树插入,新增结点必定是红色结点,因为非空树插入,新增黑色结点就破坏了规则4,规则4难以维护

3.非空树插入后,新增结点必须是红色结点,如果父亲结点是黑色的,则没有违法任何规则,插入结束

4.非空树插入后,新增结点必须是红色结点,如果父亲结点是红色的,违反规则3,处理办法由下图分析

2.2.2情况一:变色

c为红(图有点问题),p为红,g为黑,u存在且为红,则将g变为红,p和u都变为黑色,此时会出现一个问题,g的父节点是什么颜色的?我们是不能确认的,所以把g当成新的c,继续往上更新

2.2.3情况二:单旋+变色

c为红,p为红,g为黑,u不存在或者u存在且为黑

u不存在时,c为新增结点

if (cur == parent->_left) { RotateR(grandf); parent->_col = BLACK; grandf->_col = RED; }

u存在且为黑色时,c不为新增结点,是grandfather转换来的,因为如果是新增结点,那么在新增之前构不成红黑树

2.2.4情况三:双旋+变色

同上,但是区别就是,c和p的相对位置不同,当为同侧时就是单旋+变色,当是异侧时,就是双旋+变色

同侧 异侧

g g g g

p u u p p u p u

c c c c

简单理解就是直线和折线形

全部代码实现

#pragma once #include<iostream> using namespace std; enum Colour { RED, BLACK }; template<class K,class V> struct RBTreeNode { pair<K,V> _kv; RBTreeNode<K, V>* _left; RBTreeNode<K, V>* _right; RBTreeNode<K, V>* _parent; Colour _col; RBTreeNode(const pair<K,V>& kv) :_kv(kv), _left(nullptr), _right(nullptr), _parent(nullptr) { } }; template<class K,class V> class RBTree { using Node= RBTreeNode<K, V>; public: bool Insert(const pair<K, V>& kv) { if (_root == nullptr) { _root = new Node(kv); _root->_col = BLACK; return true; } Node* parent = nullptr; Node* cur = _root; while (cur) { if (cur->_kv.first < kv.first) { parent = cur; cur = cur->_right; } else if (cur->_kv.first > kv.first) { parent = cur; cur = cur->_left; } else { return false; } } cur = new Node(kv); cur->_parent = parent; cur->_col = RED; if (parent->_kv.first < cur->_kv.first) { parent->_right = cur; } else { parent->_left = cur; } //父亲是红色,出现连续红色结点,需要处理 while(parent && parent->_col == RED) { Node* grandf = parent->_parent; if (grandf->_left == parent) { Node* uncle = grandf->_right; if (uncle && uncle->_col == RED) { parent->_col = uncle->_col = BLACK; grandf->_col = RED; //继续往上处理 cur = grandf; parent = parent->_parent; } else { //这个时候就要进行旋转+变色 if (cur == parent->_left) { // g // p u //c RotateR(grandf); parent->_col = BLACK; grandf->_col = RED; break; } else { // g // p u // c //cur在parent左边的时候 RotateL(parent); RotateR(grandf); cur->_col = BLACK; grandf->_col = RED; break; } } } else { Node* uncle = grandf->_left; if (uncle && uncle->_col == RED) { // g // u p // c parent->_col = uncle->_col = BLACK; grandf->_col = RED; cur = grandf; parent = cur->_parent; } else { if (cur == parent->_right) { RotateL(grandf); parent->_col = BLACK; grandf->_col = RED; } else { // g // u p // c RotateR(parent); RotateL(grandf); cur->_col = BLACK; grandf->_col = RED; } break; } } } _root->_col = BLACK; return true; } //右旋 void RotateR(Node* parent) { if (parent == nullptr || parent->_left == nullptr) { return; } Node* subL = parent->_left; Node* subLR = subL->_right; if (subLR) { subLR->_parent = parent; } parent->_left = subLR; subL->_right = parent; Node* pParent = parent->_parent; parent->_parent = subL; if (parent == _root) { _root = subL; _root->_parent = nullptr; } else { if (pParent->_left == parent) { pParent->_left = subL; } else { pParent->_right = subL; } subL->_parent = pParent; } } //左旋 void RotateL(Node* parent) { if (parent == nullptr || parent->_right == nullptr) { return; } Node* subR = parent->_right; Node* subRL = subR->_left; parent->_right = subRL; if (subRL) { subRL->_parent = parent; } Node* pParent = parent->_parent; subR->_left = parent; parent->_parent = subR; if (pParent == nullptr) { _root = subR; subR->_parent = nullptr; } else { if (parent == pParent->_left) { pParent->_left = subR; } else { pParent->_right = subR; } subR->_parent = pParent; } } //中序遍历 void InOrder() { _InOrder(_root); cout << endl; } Node* Find(const K& key) { Node* cur = _root; while (cur) { if (cur->_kv.first < key) { cur = cur->_right; } else if (cur->_kv.first > key) { cur = cur->_left; } else { return cur; } } return nullptr; } bool IsBalance() { if (_root == nullptr) { return true; } if (_root->_col == RED) { return false; } int refNum = 0; Node* cur = _root; while (cur) { if (cur->_col == BLACK) { refNum++; } cur = cur->_left; } return Check(_root, 0, refNum); } private: bool Check(Node* root, int blackNum, const int refNum) { if (root == nullptr) { if (refNum != blackNum) { cout << "存在黑色结点数量不相等的路径" << endl; return false; } return true; } if (root->_parent != nullptr && root->_col == RED && root->_parent->_col == RED) { cout << "存在连续的红色结点" << endl; return false; } if (root->_col == BLACK) { blackNum++; } return Check(root->_left, blackNum, refNUum) && Check(root->_right, blackNum, refNum); } void _InOrder(Node* root) { if (root == nullptr) { return; } _InOrder(root->_left); cout << root->_kv.first << ":" << root->_kv.second << endl; _InOrder(root->_right); } private: Node* _root = nullptr; };
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/10 9:46:29

依托 AI 导出鸭落地高效方案,解决 Claude 生成的文本到 word 中格式混乱痛点

巧用AI导出鸭解决Claude生成的文本到word中格式混乱问题全解析 摘要&#xff1a;本文深入解析了Claude生成文本迁移至Word时普遍存在的格式混乱问题&#xff0c;介绍了AI导出鸭作为专业解决方案的技术架构与核心能力。通过五类导出方案横向对比、数据实证、专家点评和真实用户案…

作者头像 李华
网站建设 2026/6/10 9:46:28

靠谱的团建拓展公司

在快节奏的现代生活中&#xff0c;企业团建拓展活动已成为提升团队凝聚力、激发员工潜能的重要手段。佛山作为大湾区内的热门选择之一&#xff0c;不仅能够帮助企业实现团队建设的目标&#xff0c;还能通过丰富的活动形式和专业的服务为企业带来全新的体验。然而&#xff0c;在…

作者头像 李华
网站建设 2026/6/10 9:45:45

28-源码-栈帧管理

栈帧管理前言在第 26 篇和第 27 篇中&#xff0c;我们看到了解释器的整体架构和指令分发机制。现在&#xff0c;我们将注意力转向解释器的另一个核心子系统——栈帧管理&#xff08;Stack Frame Management&#xff09;。栈帧&#xff08;Stack Frame&#xff09;是方法执行时的…

作者头像 李华
网站建设 2026/6/10 9:45:19

第76篇 | HarmonyOS 保险箱详情页:私密照片如何浏览、恢复和导出

第76篇 | HarmonyOS 保险箱详情页&#xff1a;私密照片如何浏览、恢复和导出第 76 篇讲保险箱详情页。私密照片解锁后不能只显示一个列表&#xff0c;用户还需要像普通相册一样查看前后镜头、滑动浏览、恢复公开相册、导出到系统相册或再次锁定。区别在于这些动作都必须在保险箱…

作者头像 李华
网站建设 2026/6/10 9:42:55

10+ 开源项目,让 AI 帮你做出设计师级别的 PPT 和网页

AI 生成内容的能力已经很强了&#xff0c;但「能看」和「好看」之间隔着一整个设计师。 你有没有这种感觉&#xff1a;AI 写出来的页面&#xff0c;功能都有&#xff0c;排版就是差点意思——间距要么挤要么空、配色像系统默认、PPT 更是一页白底黑字从头杵到尾。不是你 promp…

作者头像 李华