【红黑树变色+旋转】

文章目录

  • 一. 红黑树规则
  • 二. 情况一叔叔存在且为红
  • 情况二.变色+旋旋

一. 红黑树规则

对于红黑树,进行变色+旋转处理,终究都是为了维持颜色+以下几条规则,只有颜色和规则维持住了,红黑树就维持住了最长路径的长度不超过最短路径的两倍。

规则:

  1. 根是黑的。
  2. 没有连续的红节点。
  3. 每条路径的黑色数量相等。

二. 情况一叔叔存在且为红

注意点:红黑树插入的节点都是红色的,因为在红黑树中动黑色节点是非常忌讳的,因为要维持每条路径黑色数量相等非常困难,所以插入的节点默认都是红色的。

当插入红色节点后:1.如果父亲为黑或者父亲不存在,结束,不需要任何处理。
2. 如果父亲存在且为红,由于插入节点为红,存在连续红节点,需要处理,可以肯定的是爷爷一定是黑,因为插入节点前就是一棵红黑树了,既然父亲和爷爷颜色确定,主要看叔叔。

1.叔叔存在且为红
在这里插入图片描述
在这里插入图片描述

情况二.变色+旋旋

叔叔存在且为黑或者叔叔不存在都需变色+旋转,关键分析是左单旋,右单旋,还是左右双旋,还是右左双旋只要旋转后,就平衡了,直接结束,不需要向上更新

1. 变色+单旋
在这里插入图片描述
对于叔叔存在且为黑或不存在这种情况,不可能是因为直接插入红色节点导致连续红这种情况直接发生的,因为这发生了,原本就不是红黑树,一定是由上述图一第一种情况处理更新上来导致的。
解决办法:curp->left, pg->left 左左右单旋g点+
p变黑,g变红。
同理:如果上述情况curp->right, pg->right,右右左单旋g点+p变黑,g变红

2.变色+双旋
在这里插入图片描述
对于这种情况:curp->right, pg->left,左右双旋,
将p左旋,g右旋,+ cur变黑+g变红。

同理:curp->left, pg->right, 右左双旋,将p右旋,g左旋,+cur变黑+g变红

总结单纯变色处理,需要不停向上更新至父亲不存在或者父亲为黑结束,旋转+变色处理完就平衡了直接结束。
一下是代码实现

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);if (parent->_kv.first < kv.first){parent->_right = cur;}else{parent->_left = cur;}cur->_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{//需要判别单旋还是左旋,确定cur的位置//旋转+变色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{if (cur == parent->_right){//		g//	u		p//				cRotateL(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 RotateL(Node* parent){++rotateSize;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 (_root == parent){_root = subR;subR->_parent = nullptr;}else{if (parent == ppnode->_left){ppnode->_left = subR;}else{ppnode->_right = subR;}subR->_parent = ppnode;}}void RotateR(Node* parent){++rotateSize;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;subL->_parent = nullptr;}else{if (parent == ppnode->_left){ppnode->_left = subL;}else{ppnode->_right = subL;}subL->_parent = ppnode;}}

无论怎么方式处理完都需要保证根是黑的,最后加上

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

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

相关文章

环 境 变 量

如果希望某一个文件在 CMD 窗口的任意路径下都可以打开&#xff0c;则需要将该文件的路径存放在环境变量中。 在 CMD 中运行该文件时&#xff0c;优先查看当前路径下的文件&#xff0c;如果没有找到&#xff0c;则进入环境变量中记录的路径下寻找该文件&#xff0c;如果能找到…

Docker高级篇之Docker搭建mysql主从复制架构

文章目录 1. 安装mysql主从复制2. 主从复制测试 1. 安装mysql主从复制 首先创建主节点 docker run -d -p 3308:3306 \ --privilegedtrue \ -v /Users/jackchai/Desktop/lottory_docker/learndocker/mymysql/master/log:/var/log/mysql \ -v /Users/jackchai/Desktop/lottory_…

端午假期来临,来使用闪侠惠递便宜寄快递吧!

相信很多人和我一样&#xff0c;每当需要寄快递时&#xff0c;总是感到十分头疼。不同的快递公司有不同的价格、时效和服务质量等等&#xff0c;选择起来真的很不容易。但是现在有了闪侠惠递来帮大家寄快递吧&#xff0c;这个问题就可以迎刃而解了&#xff01;小编奉劝大家快来…

【HarmonyOS4学习笔记】《HarmonyOS4+NEXT星河版入门到企业级实战教程》课程学习笔记(十三)

课程地址&#xff1a; 黑马程序员HarmonyOS4NEXT星河版入门到企业级实战教程&#xff0c;一套精通鸿蒙应用开发 &#xff08;本篇笔记对应课程第 20 - 21节&#xff09; P20《19.ArkUI-属性动画和显式动画》 本节先来学习属性动画和显式动画&#xff1a; 在代码中定义动画&am…

在keil5中打开keil4工程的方法

文章目录 1. 打开文件 2. 安装旧版本包 3. 在keil4中打开keil5工程 1. 打开文件 在keil5 MDK的环境下&#xff0c;打开keil4的工程文件&#xff0c;会弹出下图所示的窗口&#xff1a; 参考官网的解释这两个方法分别为&#xff1a; 1. 使用MDK 版本 4 Legacy Pack时&#x…

Android 高德地图API(新版)

新版高德地图 前言正文一、创建应用① 获取PackageName② 获取调试版安全码SHA1③ 获取发布版安全码SHA1 二、配置项目① 导入SDK② 配置AndroidManifest.xml 三、获取当前定位信息① ViewBinding使用和导包② 隐私合规设置③ 权限请求④ 初始化定位⑤ 获取定位信息 四、显示地…

electron打包时资源下载失败cannot resolve xxx/30.0.9/electron-v30.0.9-win32-ia32.zip

同学们可以私信我加入学习群&#xff01; 正文开始 问题描述解决方案总结 问题描述 最近electron更新频繁&#xff0c;而我在用electron做个人项目&#xff0c;对稳定性没有太高要求&#xff0c;希望保持着electron的最新版本&#xff0c;所以就没有固定版本。 单位网络不太好…

Docker镜像加载原理(Union文件系统)

联合文件系统 Union文件系统&#xff0c;是一种轻量级的分层高性能服务系统&#xff0c;支持对文件系统的修改来进行一层一层的叠加&#xff0c;同时将不同目录挂载到同一个虚拟文件系统中&#xff0c;Union文件系统是Docker镜像的基础&#xff0c;通过分层来进行集成&am…

[第五空间 2021]WebFTP、[HCTF 2018]Warmup

目录 [第五空间 2021]WebFTP ​[SWPUCTF 2021 新生赛]Do_you_know_http [NCTF 2018]签到题 [HNCTF 2022 Week1]What is Web [HNCTF 2022 Week1]Interesting_http [HCTF 2018]Warmup [第五空间 2021]WebFTP 使用dirsearch扫描&#xff0c;发现有git泄露 使用GitHack克隆目…

Docker安装、使用,容器化部署springboot项目

目录 一、使用官方安装脚本自动安装 二、Docker离线安装 1. 下载安装包 2. 解压 3.创建docker.service文件 4. 启动docker 三、docker常用命令 1. docker常用命令 2. docker镜像命令 3. docker镜像下载 4.docker镜像push到仓库 5. docker操作容器 6.docker …

轻松实现文件随机提取:从众多文件夹中智能筛选指定数量文件,一键移至目标文件夹!

在信息爆炸的时代&#xff0c;电脑中的文件越来越多&#xff0c;整理起来却越来越头疼。你是否也曾在海量的文件夹中迷失&#xff0c;苦苦寻找那个特定的文件&#xff1f;你是否也曾为了将文件从一个文件夹移动到另一个文件夹而耗费大量时间&#xff1f;现在&#xff0c;我们为…

开发一个Dapp需要多少?

区块链开发一个Dapp要多少钱&#xff1f; 开发一个去中心化应用&#xff08;Dapp&#xff09;的成本取决于多个因素&#xff0c;包括Dapp的复杂性、功能需求、区块链平台以及开发团队的经验水平。以下是一些主要的影响因素&#xff1a; 1. 区块链平台&#xff1a;不同区块链…

《十八岁出门远行》世界很小,案牍劳形;世界很大,日短心长

《十八岁出门远行》世界很小&#xff0c;案牍劳形&#xff1b;世界很大&#xff0c;日短心长 余华&#xff0c;作家&#xff0c;著有《在细雨中呼喊》《活着》《文城》《兄弟》等。 文章目录 《十八岁出门远行》世界很小&#xff0c;案牍劳形&#xff1b;世界很大&#xff0c;日…

2048小游戏的菜鸡实现方法

# 2048小游戏的实现与分析 2048是一款非常受欢迎的数字滑块游戏&#xff0c;其目标是通过滑动和合并相同数字的方块来创建一个值为2048的方块。下面&#xff0c;我们将通过分析一个C语言实现的2048小游戏的源代码&#xff0c;来探索如何用编程实现这款游戏。 ## 游戏概述 20…

C++学习/复习13--list概述

一、list概念 1.带头双向链表 2.构造函数 3.迭代器&#xff08;其迭代器需尤其注意&#xff09; 4、size 5.front/back 6.插入删除 删除时的迭代器失效 由于list的节点特殊&#xff0c;既有数据又有指针&#xff0c;其实现需要节点/迭代器/list各成一类再组合

Linux网络编程——概念及实现双方聊天

网络编程的场景&#xff1a; 假设你面前有五座房子&#xff08;服务器&#xff09;&#xff0c;你要走到其中一座房子的某一间&#xff0c;此时你站在五座房子面前很迷茫&#xff0c;突然&#xff0c;第二座房子上面有人在叫&#xff0c;并且用汉语&#xff08;TCP/UDP&#xf…

【Framework系列】Excel转Json,配置表、导表工具介绍

今天来介绍一下Framework系列的配置部分&#xff0c;这一部分归属于Framework-Design之中。读过《Framework系列介绍》的小伙伴应该了解整个Framework框架是由多个工程项目组成&#xff0c;没看过的小伙伴可以点击链接了解一下。 Framework-Design设计的初衷是给策划同学用的&a…

上市公司绿色并购数据+do文件(1996-2024.4)

数据简介&#xff1a;手工搜集重污染上市公司的并购公告&#xff0c;采用内容分析法&#xff0c;对每次并购的背景和目的&#xff0c;主并企业和标的企业经营范围以及该次并购对主并企业带来的影响进行综合分析&#xff0c;逐一判断该项并购事件是否为绿色并购 时间跨度&#…

汽车尾气排放污染的解决方案

根据公安部截至2023年底的机动车市场保有量统计&#xff0c;燃油车市场仍有不少消费者拥趸&#xff1a;目前全国新能源汽车保有量仅占汽车总量的6.07%&#xff0c;而其中的纯电动汽车保有量占比仅为76.05%。 汽车尾气排放污染已成为城市主要污染源之一。据统计显示&#xff0c…

嵌入式Linux系统编程 — 2.1 标准I/O库简介

目录 1 标准I/O库简介 1.1 标准I/O库简介 1.2 标准 I/O 和文件 I/O 的区别 2 FILE 指针 3 标准I/O库的主要函数简介 4 标准输入、标准输出和标准错误 4.1 标准输入、标准输出和标准错误概念 4.2 示例程序 5 打开文件fopen() 5.1 fopen()函数简介 5.2 新建文件的权限…