当前位置: 首页 > news >正文

【红黑树变色+旋转】

文章目录

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

一. 红黑树规则

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

规则:

  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;}}

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

相关文章:

【红黑树变色+旋转】

文章目录 一. 红黑树规则二. 情况一叔叔存在且为红情况二.变色旋旋 一. 红黑树规则 对于红黑树&#xff0c;进行变色旋转处理&#xff0c;终究都是为了维持颜色以下几条规则&#xff0c;只有颜色和规则维持住了&#xff0c;红黑树就维持住了最长路径的长度不超过最短路径的两倍…...

pytorch 使用tensor混合:进行index操作

(Pdb) tmp torch.randn(3,5) (Pdb) indx torch.tensor([1,0]).long() (Pdb) temp(indx) *** NameError: name ‘temp’ is not defined (Pdb) tmp(indx) *** TypeError: ‘Tensor’ object is not callable (Pdb) tmp[indx] tensor([[ 0.1633, 0.9389, 1.2806, -0.2525, 0.28…...

Threejs(WebGL)绘制线段优化:Shader修改gl.LINES模式为gl.LINE_STRIP

目录 背景 思路 Threejs实现 记录每条线的点数 封装原始裁剪索引数据 封装合并几何体的缓冲数据&#xff1a;由裁剪索引组成的 IntArray 守住该有的线段&#xff01; 修改顶点着色器 修改片元着色器 完整代码 WebGL实现类似功能&#xff08;简易版&#xff0c;便于测…...

继承-进阶

父子类成员共享 普通成员对象/父子间不共享&#xff0c; 成员独立 函数成员共享&#xff08;函数不存储在对象中&#xff09; 子类由两部分构成&#xff1a;父类中继承的成员和子类中新定义成员 继承方式 子类中存在父类private成员但不可直接访问&#xff08;及时在类中&am…...

探索k8s集群的配置资源(secret和configmap)

目录 ConfigMap ConfigMap&#xff08;主要是将配置目录或者文件挂载到k8s里面使用&#xff09; 与Secret类似&#xff0c;区别在于ConfigMap保存的是不需要加密配置的信息。&#xff08;例如&#xff1a;配置文件&#xff09; ConfigMap 功能在 Kubernetes1.2 版本中引入&…...

如何设置vue3项目中默认的背景为白色

方法1&#xff1a;通过CSS全局样式 在全局CSS文件中设置&#xff1a; 如果你的项目中有全局的CSS文件&#xff08;如App.vue或专门的CSS文件&#xff09;&#xff0c;你可以直接设置body或html标签的背景颜色。 在src/assets文件夹中&#xff08;或者任何你存放CSS文件的地方&a…...

MS1112驱动开发

作者简介&#xff1a; 一个平凡而乐于分享的小比特&#xff0c;中南民族大学通信工程专业研究生在读&#xff0c;研究方向无线联邦学习 擅长领域&#xff1a;驱动开发&#xff0c;嵌入式软件开发&#xff0c;BSP开发 作者主页&#xff1a;一个平凡而乐于分享的小比特的个人主页…...

K8s存储对象的使用

背景和概念 容器中的文件在磁盘上是临时存放的&#xff0c;这给在容器中运行较重要的应用带来一些问题&#xff1a; 当容器崩溃或停止时&#xff0c;此时容器状态未保存&#xff0c; 因此在容器生命周期内创建或修改的所有文件都将丢失。另外 在崩溃期间&#xff0c;kubelet 会…...

构建自动化API数据抓取系统

构建一个自动化API数据抓取系统是一个涉及多个技术领域的复杂任务。这样的系统不仅要求高效的数据获取能力&#xff0c;还需要有稳定的数据处理、存储和错误处理机制。 1. 需求分析 在开始构建之前&#xff0c;明确你的需求至关重要。你需要确定要抓取的API、数据的频率、数据的…...

【Qt知识】部分QWidget属性表格

QWidget是Qt库中所有图形用户界面组件的基类&#xff0c;它提供了大量属性以供自定义和配置控件的行为和外观。下面列出了一些主要的QWidget属性及其作用。 属性 作用 accessibleName 控件的辅助技术名称&#xff0c;用于无障碍访问。 accessibleDescription 控件的辅助技…...

【ARM64 常见汇编指令学习 19.1 -- ARM64 跳转指令 b.pl 详细介绍】

文章目录 ARM64 跳转指令 b.pl使用场景语法示例总结 ARM64 跳转指令 b.pl 在 ARMv8 架构中&#xff0c;b.pl 是一条条件分支&#xff08;Branch&#xff09;指令&#xff0c;它根据当前的状态寄存器中的条件标志执行跳转。b.pl 的全称是 Branch if Plus&#xff0c;即如果条件…...

WWDC24即将到来,ios18放大招

苹果公司即将在下周开全球开发者大会(WWDC)&#xff0c;大会上将展示其人工智能技术整合到设备和软件中的重大进展,包括与OpenAI的历史性合作。随着大会的临近,有关iOS 18及其据称采用AI技术支持的应用程序和功能的各种泄露信息已经浮出水面。 据报道,苹果将利用其自主研发的大…...

C#中的空合并运算符与空合并赋值运算符:简化空值处理

在C#编程中&#xff0c;处理可能为null的值是一项常见的任务&#xff0c;尤其是在涉及数据库查询、Web服务调用或任何可能返回缺失数据的场景中。为了简化这类操作并提高代码的可读性&#xff0c;C# 8 引入了两个非常实用的运算符&#xff1a;空合并运算符 (??) 和 空合并赋值…...

数据结构:哈夫曼树及其哈夫曼编码

目录 1.哈夫曼树是什么&#xff1f; 2.哈夫曼编码是什么&#xff1f; 3.哈夫曼编码的应用 4.包含头文件 5.结点设计 6.接口函数定义 7.接口函数实现 8.哈夫曼编码测试案列 哈夫曼树是什么&#xff1f; 哈夫曼树&#xff08;Huffman Tree&#xff09;是一种特殊的二叉树&#xf…...

微信如何防止被对方拉黑删除?一招教你解决!文末附软件!

你一定不知道&#xff0c;微信可以防止被对方拉黑删除&#xff0c;秒变无敌。只需一招就能解决&#xff01;赶快来学&#xff01;文末有惊喜&#xff01; 惹到某些重要人物&#xff08;比如女朋友&#xff09;&#xff0c;被删除拉黑一条龙&#xff0c;那真的是太令人沮丧了&a…...

jar增量打包

jar增量打包 Linux环境下&#xff1a; 1.解压缩 jar -xvf jarname.jar&#xff08;解压&#xff09;2.打包 这时可以把要替换的lib包的内容粘帖进去&#xff0c;然后重新打jar包 jar -cvf0M jarname.jar .&#xff08;重新压缩,-0是主要的&#xff09;jar命令&#xff1a; …...

智慧医院物联网建设-统一管理物联网终端及应用

近年来&#xff0c;国家卫健委相继出台的政策和评估标准体系中&#xff0c;都涵盖了强化物联网建设的内容。物联网建设已成为智慧医院建设的核心议题之一。 作为医院高质量发展的关键驱动力&#xff0c;物联网的顶层设计与网络架构设计规划&#xff0c;既需要结合现代信息技术的…...

Debian的常用命令

Debian作为一个稳定、安全且高效的Linux发行版,被广泛应用于服务器和桌面操作系统中。对于系统管理员和开发者来说,熟练掌握Debian的常用命令能够大大提升工作的效率和系统的管理水平。本文将详细介绍一些常见且实用的Debian命令,帮助新手更好地管理和操作Debian系统。 系统…...

矩阵1-范数与二重求和的求和可交换

矩阵1-范数与二重求和的求和可交换 1、矩阵1-范数 A [ a 11 a 12 ⋯ a 1 n a 21 a 22 ⋯ a 2 n ⋮ ⋮ ⋱ ⋮ a n 1 a n 2 ⋯ a n n ] A \begin{bmatrix} a_{11} &a_{12} &\cdots &a_{1n} \\ a_{21} &a_{22} &\cdots &a_{2n} \\ \vdots &\vdots …...

Python笔记 - *args和**kwargs

探索Python的*args和**kwargs 在Python中&#xff0c;函数可以接受任意数量的参数&#xff0c;而这要归功于*args和**kwargs的强大功能。这两个特性使得函数在处理不同数量的输入时变得更加灵活和高效。在这篇博客中&#xff0c;我们将详细介绍*args和**kwargs&#xff0c;并展…...

接口测试中缓存处理策略

在接口测试中&#xff0c;缓存处理策略是一个关键环节&#xff0c;直接影响测试结果的准确性和可靠性。合理的缓存处理策略能够确保测试环境的一致性&#xff0c;避免因缓存数据导致的测试偏差。以下是接口测试中常见的缓存处理策略及其详细说明&#xff1a; 一、缓存处理的核…...

JavaScript 中的 ES|QL:利用 Apache Arrow 工具

作者&#xff1a;来自 Elastic Jeffrey Rengifo 学习如何将 ES|QL 与 JavaScript 的 Apache Arrow 客户端工具一起使用。 想获得 Elastic 认证吗&#xff1f;了解下一期 Elasticsearch Engineer 培训的时间吧&#xff01; Elasticsearch 拥有众多新功能&#xff0c;助你为自己…...

【第二十一章 SDIO接口(SDIO)】

第二十一章 SDIO接口 目录 第二十一章 SDIO接口(SDIO) 1 SDIO 主要功能 2 SDIO 总线拓扑 3 SDIO 功能描述 3.1 SDIO 适配器 3.2 SDIOAHB 接口 4 卡功能描述 4.1 卡识别模式 4.2 卡复位 4.3 操作电压范围确认 4.4 卡识别过程 4.5 写数据块 4.6 读数据块 4.7 数据流…...

微信小程序 - 手机震动

一、界面 <button type"primary" bindtap"shortVibrate">短震动</button> <button type"primary" bindtap"longVibrate">长震动</button> 二、js逻辑代码 注&#xff1a;文档 https://developers.weixin.qq…...

高等数学(下)题型笔记(八)空间解析几何与向量代数

目录 0 前言 1 向量的点乘 1.1 基本公式 1.2 例题 2 向量的叉乘 2.1 基础知识 2.2 例题 3 空间平面方程 3.1 基础知识 3.2 例题 4 空间直线方程 4.1 基础知识 4.2 例题 5 旋转曲面及其方程 5.1 基础知识 5.2 例题 6 空间曲面的法线与切平面 6.1 基础知识 6.2…...

新能源汽车智慧充电桩管理方案:新能源充电桩散热问题及消防安全监管方案

随着新能源汽车的快速普及&#xff0c;充电桩作为核心配套设施&#xff0c;其安全性与可靠性备受关注。然而&#xff0c;在高温、高负荷运行环境下&#xff0c;充电桩的散热问题与消防安全隐患日益凸显&#xff0c;成为制约行业发展的关键瓶颈。 如何通过智慧化管理手段优化散…...

C# 类和继承(抽象类)

抽象类 抽象类是指设计为被继承的类。抽象类只能被用作其他类的基类。 不能创建抽象类的实例。抽象类使用abstract修饰符声明。 抽象类可以包含抽象成员或普通的非抽象成员。抽象类的成员可以是抽象成员和普通带 实现的成员的任意组合。抽象类自己可以派生自另一个抽象类。例…...

【git】把本地更改提交远程新分支feature_g

创建并切换新分支 git checkout -b feature_g 添加并提交更改 git add . git commit -m “实现图片上传功能” 推送到远程 git push -u origin feature_g...

从零实现STL哈希容器:unordered_map/unordered_set封装详解

本篇文章是对C学习的STL哈希容器自主实现部分的学习分享 希望也能为你带来些帮助~ 那咱们废话不多说&#xff0c;直接开始吧&#xff01; 一、源码结构分析 1. SGISTL30实现剖析 // hash_set核心结构 template <class Value, class HashFcn, ...> class hash_set {ty…...

GitHub 趋势日报 (2025年06月08日)

&#x1f4ca; 由 TrendForge 系统生成 | &#x1f310; https://trendforge.devlive.org/ &#x1f310; 本日报中的项目描述已自动翻译为中文 &#x1f4c8; 今日获星趋势图 今日获星趋势图 884 cognee 566 dify 414 HumanSystemOptimization 414 omni-tools 321 note-gen …...