红黑树!!

文章目录

  • 1.红黑树的概念
  • 2.红黑树的几种情况
    • 2.1 情况一:cur为红,p为红,g为黑,u存在且为红(p为parent,g为grandfather,u为uncle)
    • 2.2 情况二:cur为红,p为红,g为黑,u不存在/u存在且为黑(p为parent,g为grandfather,u为uncle)
    • 2.3 情况三:cur为红,p为红,g为黑,u不存在/u存在且为黑(p为parent,g为grandfather,u为uncle)双旋情况
  • 3.红黑树的底层


1.红黑树的概念

红黑树,是一种二叉搜索树,但在每个结点上增加一个存储位表示结点的颜色,可以Red或Black。 通过对任何一条从根到叶子的路径上各个结点着色方式的限制,红黑树确保没有一条路径会比其他路径长出俩倍,因而是接近平衡的。

最长路径≤最短路径×2
在这里插入图片描述
在这里插入图片描述

  1. 每个结点不是红色就是黑色
  2. 根节点是黑色的
  3. 如果一个节点是红色的,则它的两个孩子结点是黑色的 (不存在连续的红色节点)
  4. 对于每个结点,从该结点到其所有后代叶结点的简单路径上,均包含相同数目的黑色结点 (每条路径都存在相同数量的黑色节点)
  5. 每个叶子结点都是黑色的(此处的叶子结点指的是空结点,不是传统的叶子节点)

2.红黑树的几种情况

在这里插入图片描述

2.1 情况一:cur为红,p为红,g为黑,u存在且为红(p为parent,g为grandfather,u为uncle)

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
太过复杂

2.2 情况二:cur为红,p为红,g为黑,u不存在/u存在且为黑(p为parent,g为grandfather,u为uncle)

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

2.3 情况三:cur为红,p为红,g为黑,u不存在/u存在且为黑(p为parent,g为grandfather,u为uncle)双旋情况

在这里插入图片描述
在这里插入图片描述

3.红黑树的底层

#pragma once
#include<iostream>
#include<vector>using namespace std;
enum Colour
{RED,BLACK
};template<class K, class V>
struct RBTreeNode
{RBTreeNode<K, V>* _left;RBTreeNode<K, V>* _right;RBTreeNode<K, V>* _parent;pair<K, V> _kv;Colour _col;RBTreeNode(const pair<K, V>& kv):_left(nullptr), _right(nullptr), _parent(nullptr), _kv(kv), _col(RED){}
};template<class K, class V>
class RBTree
{typedef RBTreeNode<K, V> Node;
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->_col = RED; // 新增节点给红色if (parent->_kv.first < kv.first){parent->_right = cur;}else{parent->_left = cur;}cur->_parent = parent;// parent的颜色是黑色也结束while (parent && parent->_col == RED){// 关键看叔叔Node* grandfather = parent->_parent;if (parent == grandfather->_left){Node* uncle = grandfather->_right;// 叔叔存在且为红,-》变色即可if (uncle && uncle->_col == RED){parent->_col = uncle->_col = BLACK;grandfather->_col = RED;// 继续往上处理cur = grandfather;parent = cur->_parent;}else // 叔叔不存在,或者存在且为黑{if (cur == parent->_left){//     g  //   p   u// c //单旋RotateR(grandfather);parent->_col = BLACK;grandfather->_col = RED;}else{//      g  //   p     u//      c //双旋RotateL(parent);RotateR(grandfather);cur->_col = BLACK;grandfather->_col = RED;}break;}}else{Node* uncle = grandfather->_left;// 叔叔存在且为红,-》变色即可if (uncle && uncle->_col == RED){parent->_col = uncle->_col = BLACK;grandfather->_col = RED;// 继续往上处理cur = grandfather;parent = cur->_parent;}else // 叔叔不存在,或者存在且为黑{// 情况二:叔叔不存在或者存在且为黑// 旋转+变色//      g//   u     p//            c//单旋if (cur == parent->_right){RotateL(grandfather);parent->_col = BLACK;grandfather->_col = RED;}else{//		g//   u     p//      c//双旋RotateR(parent);RotateL(grandfather);cur->_col = BLACK;grandfather->_col = RED;}break;}}}_root->_col = BLACK;return true;}void RotateR(Node* parent){Node* subL = parent->_left;Node* subLR = subL->_right;parent->_left = subLR;if (subLR)subLR->_parent = parent;subL->_right = parent;Node* ppNode = parent->_parent;parent->_parent = subL;if (parent == _root){_root = subL;_root->_parent = nullptr;}else{if (ppNode->_left == parent){ppNode->_left = subL;}else{ppNode->_right = subL;}subL->_parent = ppNode;}}void RotateL(Node* parent){Node* subR = parent->_right;Node* subRL = subR->_left;parent->_right = subRL;if (subRL)subRL->_parent = parent;subR->_left = parent;Node* ppNode = parent->_parent;parent->_parent = subR;if (parent == _root){_root = subR;_root->_parent = nullptr;}else{if (ppNode->_right == parent){ppNode->_right = subR;}else{ppNode->_left = subR;}subR->_parent = ppNode;}}void InOrder(){_InOrder(_root);cout << endl;}bool IsBalance(){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){//cout << blackNum << endl;if (refNum != blackNum){cout << "存在黑色节点的数量不相等的路径" << endl;return false;}return true;}if (root->_col == RED && root->_parent->_col == RED){cout << root->_kv.first << "存在连续的红色节点" << endl;return false;}if (root->_col == BLACK){blackNum++;}return Check(root->_left, blackNum, refNum)&& Check(root->_right, blackNum, refNum);}void _InOrder(Node* root){if (root == nullptr){return;}_InOrder(root->_left);cout << root->_kv.first << ":" << root->_kv.second << ":" << (root->_col == RED ? "RED" : "BLACK") << endl;_InOrder(root->_right);}private:Node* _root = nullptr;//size_t _size = 0;
};void TestRBTree1()
{//int a[] = { 8, 3, 1, 10, 6, 4, 7, 14, 13 };int a[] = { 4, 2, 6, 1, 3, 5, 15, 7, 16, 14,8, 3, 1, 10, 6, 4, 7, 14, 13 };RBTree<int, int> t1;for (auto e : a){// 1、先看是插入谁导致出现的问题// 2、打条件断点,画出插入前的树// 3、单步跟踪,对比图一一分析细节原因t1.Insert({ e,e });cout << "Insert:" << e << "->" << t1.IsBalance() << endl;}t1.InOrder();cout << t1.IsBalance() << endl;
}

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/11937.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

MATLAB支持向量机:函数或变量 ‘svmtrain‘ 无法识别解决方法

我的MATLAB版本是2020a&#xff0c;在运行程序时出现了一下报错 若在运行程序时出现了以下报错&#xff1a; 支持向量机程序在MATLAB执行代码的时候发现有错误。 试一下help&#xff0c;如下图所示&#xff0c;SVM_L和svmtrain均找不到。 打开matlab帮助文档&#xff1a; 可…

C# XPTable in .net6(XPTable控件使用说明八)

经过作者schoetbi、armin-pfaeffle的努力&#xff0c;XPTable已经可以在 winform .net6 .net8的环境下使用&#xff0c;版本升级到了2.0&#xff0c;这样就可以在winform下同时使用XPTABLE和EFcore, 这样就可以解决大部分的场景了。

【HMGD】GD32/STM32 DMA接收不定长串口数据

单片机型号&#xff1a;GD32F303系列 CubeMX配置 配置串口参数 开启DMA 开启中断 示例代码 使用到的变量 uint8_t RX_Buff_FLAG 0; uint8_t RX_Buff[300] {0}; uint8_t TX_Buff[300] {0};串口接收空闲函数 // 串口接收空闲函数 void HAL_UARTEx_RxEventCallback(UART_H…

邮件地址采集软件有哪些-邮箱地址采集软件

邮件地址采集软件是帮助用户收集、管理和使用邮件地址的工具&#xff0c;它们在商业营销、市场调研、网络爬虫等领域有着广泛的应用。以下是一些常见的邮件地址采集软件&#xff1a; 易邮件地址搜索大师&#xff1a;易邮件地址搜索大师是一款搜索邮件地址和手机号码的软件&…

数据库开发记录

一.MySQL相关 1.Spatial Data相关

OpenAI发布最强大模型GPT-4o:对所有用户免费

OpenAI 最新推出的 GPT-4o 模型在实现更自然的人机交互方面迈出了重要一步。GPT-4o的“o” 源自拉丁语“全方位”&#xff0c;意思是“一切”。活动期间 OpenAI, 米拉穆拉蒂该公司技术总监上台展示了新的语言模型。她强调&#xff0c;拥有 OpenAI 帐户的每个人都可以免费使用新…

安装adobe系列,提示错误代码146解决办法

安装Adobe系列产品如PS、PR、Lrc等产品时&#xff0c;会因为各种各样的错误导致安装失败&#xff01;今天小编为大家带来的是安装adobe系列&#xff0c;提示错误代码146解决办法&#xff0c;收藏起来吧&#xff01; 方法一&#xff1a;就是传说中的万能大法&#xff0c;关机重启…

【MySQL】sql表设计的注意事项

程序员的实用神器 文章目录 程序员的实用神器强烈推荐引言注意事项强烈推荐专栏集锦写在最后 强烈推荐 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到网站:人工智能 推荐一个个人工作&#x…

五、Linux二进制安装MariaDB 六、MariaDB主从复制

目录 五、Linux二进制安装MariaDB1 卸载mariadb1.1 卸载相关的服务(mysql和mariadb都查询一下)1.2 查找MySQL和mariadb相关的文件目录 2 安装mariadb2.1 mariadb下载地址2.2 将安装包放入到服务器中并解压 (我放到opt下)2.3 将解压后的目录移动到安装目录下2.4 创建数据目录(根…

高效且安全的传输工具:FileLink跨网文件传输

在数字化时代&#xff0c;文件传输已成为我们日常工作和生活不可或缺的一部分。无论是企业内部的资料共享&#xff0c;还是企业对外的文件交换&#xff0c;都需要一个高效、稳定且安全的传输工具。而FileLink跨网文件传输正是满足这些需求的理想选择。 FileLink跨网文件传输 首…

雇佣 K 位工人的总代价

题目链接 雇佣 K 位工人的总代价 题目描述 注意点 costs[i]是雇佣第 i 位工人的代价每一轮雇佣后&#xff0c;剩余工人的下标可能会发生变化一位工人只能被选择一次如果剩余员工数目不足 candidates 人&#xff0c;那么下一轮雇佣他们中代价最小的一人如果有多位代价相同且最…

IOS 苹果IAP(内购)之创建沙盒账号

IOS 苹果IAP&#xff08;内购&#xff09;之创建沙盒账号 沙盒账号是什么&#xff1f;沙盒账号创建的前提条件沙盒账号创建沙盒账号使用流程沙盒账号注意事项 沙盒账号是什么&#xff1f; 如果IOS应用里面用到了苹果应用内付费&#xff08;IAP&#xff09;功能&#xff0c;那么…

上位机图像处理和嵌入式模块部署(树莓派4b的替代品)

【 声明&#xff1a;版权所有&#xff0c;欢迎转载&#xff0c;请勿用于商业用途。 联系信箱&#xff1a;feixiaoxing 163.com】 实话实说&#xff0c;树莓派4b的产品力还是比较优秀的&#xff0c;价格还算适中。但是和国产卡片电脑比起来&#xff0c;则逊色不少。功能差不多的…

第四篇 Asciidoc - MindMap 思维导图 不是事

MindMap 是一种对思维的简单抽象,说到底,就是一个树状结构。 以下是一个样例: Figure 1. MindMap示例 我们的目录结构、模块结构、分类结构等等,都是树型结构,它非常普遍,因此 MindMap 是笔记软件中,获得最多支持的一种图。 精确地说,这类图,是对思维结构的一种映射…

BES 平台 SDK之 美格信Dongle 连接

前言: 最近项目到了试产阶段,需要用到美格信的Dongel 来测试ANC 相关功能。在此简单介绍下如何连接Dongel 的操作步骤。 一:硬件材料清单 1.美格信dongle 一台 2.待测机器 二:软件工具 1.BES_Designer_Tool_v1.0.782 2.美格信驱动安装包 :libusb-win32-devel-filter-1.2…

C语言易错提醒选择题精选

Ⅰ 易错题 1.设有double p;&#xff0c;为变量p声明一个引用名称rp,则定义语句为 double& rpp; 2.已知‘A’一‘Z’的ASCII码为65—90&#xff0c;当执行“char ch14*52&#xff1b;cout<<ch<<endl;”语句序列后得到的输出结H &#xff0c;72对应ASCII码中…

免费分享一套SpringBoot+Vue教务管理(课程管理)系统,帅呆了~~

大家好&#xff0c;我是java1234_小锋老师&#xff0c;看到一个不错的SpringBootVue教务管理(课程管理)系统&#xff0c;分享下哈。 项目视频演示 【免费】SpringBootVue教务管理(课程管理)系统 Java毕业设计_哔哩哔哩_bilibili【免费】SpringBootVue教务管理(课程管理)系统 …

品鉴中的盲品挑战:如何凭借感官判断红酒的类型与品质

盲品挑战是一种品鉴方式&#xff0c;通过蒙住品鉴者的眼睛&#xff0c;仅凭感官来判断红酒的类型和品质。这种方式考验品鉴者的感官敏锐度和经验&#xff0c;也是提升品鉴能力的一种有趣方式。那么&#xff0c;如何在盲品挑战中凭借感官判断雷盛红酒的类型与品质呢&#xff1f;…

Web APIs(获取元素+操作元素+节点操作)

目录 1.API 和 Web API 2.DOM导读 DOM树 3.获取元素 getElementById获取元素 getElementsByTagName获取元素 H5新增方法获取 获取特殊元素 4.事件基础 执行事件 操作元素 修改表单属性 修改样式属性 使用className修改样式属性 获取属性的值 设置属性的值 移除…

Git系列:git show 使用技巧

&#x1f49d;&#x1f49d;&#x1f49d;欢迎莅临我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:「stormsha的主页」…