【数据结构】红黑树的删除(抽丝剥茧,带你理清每一种情况)

文章目录

  • 前言
  • 正文
    • 1.所删除的结点为红色
      • 1.1delnode的左右都为空
      • 1.2delnode的左为空,且右不为空
      • 1.3delnode的左不为空,右为空
      • 1.4delnode的左不为空,且右不为空
    • 2.所删除的结点为黑色
      • 2.1 调整后所在树每条路径黑色结点的个数不发生变化
        • 2.1 左结点不为空,右节点为空
        • 2.2 左结点为空,右节点不为空
        • 2.3 左右结点都为空
          • 2.3.1 uncle为黑色
            • 2.3.1.1uncle的左节点为红色(右不为红)
            • 2.3.1.2uncle的右节点为红色
            • 2.3.1.3uncle的左右结点都为黑色
          • 2.3.2 uncle红色
            • 2.3.2.1 uncle的左右结点都为黑
      • 2.2 调整后所在树每条路径黑色结点的个数发生变化
        • 2.2.1 uncle为黑色
          • 2.2.1.1 uncle的左右结点为黑色
  • 图解
  • 实现代码
  • 总结

前言

 红黑树的删除,较AVL树的删除比较抽象,同时也跟红黑树的插入的区别较大,但大体上的思路还是基于普通二叉搜索树的基础上进行讨论的。

浅浅的铺垫一下:

  1. 需要清楚普通二叉树的删除,可见AVL树的删除文章开头。
  2. 四种旋转的操作(只需操作)得熟记于心,可见AVL树的插入与验证
  3. 红黑树的插入的变色原理得清楚,可见红黑树的插入与验证

正文

1.所删除的结点为红色

  • 红色的删除最为简单,因为红色结点所连接的结点都是黑色!

为了便于描述,我们这里将所删除的结点称之为delnode

1.1delnode的左右都为空

在这里插入图片描述

不管delnode在左边还是在右边,我们只需要改变父节点的delnode指向为空即可。

1.2delnode的左为空,且右不为空

  • 如果delnode右不为空,则其右为黑色,但是每条路径的黑色结点数必然相同,则delnode的左结点必然也为黑色,与条件的左为空相悖,因此情况不存在

1.3delnode的左不为空,右为空

  • 如果delnode左不为空,则其左为黑色,但是每条路径的黑色结点数必然相同,则delnode的右结点必然也为黑色,与条件的右为空相悖,因此情况不存在

1.4delnode的左不为空,且右不为空

  • 根据普通二叉搜索树,这里要找左子树的最大结点,进行值交换,然后再删除找到的左子树的最大节点,其如果为红色,则转换为1.1情况。

  • 因此:delnode为红色只有一种处理方法。

2.所删除的结点为黑色

  • 重头戏来了!
    为了便于描述,我们这里将所删除的结点称之为delnode

 先对delnode进行分析,既然为黑色,其左节点或者右节点为红色,或者左右结点都为红色,或者左右都为空,当然分析到这里还不够,我们还要对其uncle进行分析。

2.1 调整后所在树每条路径黑色结点的个数不发生变化

2.1 左结点不为空,右节点为空

  • 左节点只能是红色。
    在这里插入图片描述

不管delnode为parent的左结点还是右节点,parent的指向delnode的节点改为指向delnode的左边,再将delnode的左边结点颜色改为黑色即可。

2.2 左结点为空,右节点不为空

在这里插入图片描述

不管delnode为parent的左结点还是右节点,parent的指向delnode的节点改为指向delnode的右节点,再将delnode的右边结点颜色改为黑色即可。

2.3 左右结点都为空

parentdelnode的父节点,父节点另一个链接的结点设为uncle
 如果下面分析delnode结点为左右有些太冗余了,我们只分析cur为parent的左结点这一种情况,最后cur为parent右结点这一种情况,最后以图解的方式呈现。

2.3.1 uncle为黑色
2.3.1.1uncle的左节点为红色(右不为红)
  1. 父节点为红色
  • uncle右节点为黑色
    在这里插入图片描述

  • uncle右节点为空

在这里插入图片描述

  1. 父节点为黑色
  • uncle右节点为黑色

在这里插入图片描述

  • uncle右节点为空
    在这里插入图片描述

 总结分析方式是一样的,只是最后实际的变色是不一样的,我们可以从中发现一个变色规律:

  1. 右左双旋
  2. parent的颜色赋值给uncle_left
  3. parent的颜色与uncle的颜色赋值为黑色
2.3.1.2uncle的右节点为红色
  1. 父节点为黑色
  • uncle的左节点为黑色
    在这里插入图片描述

  • uncle的左节点为红色

在这里插入图片描述

  1. 父节点为红色
  • uncle的左节点为黑色

在这里插入图片描述

  • uncle的左节点为红色

在这里插入图片描述

 总结分析方式是一样的,只是最后实际的变色是不一样的,我们可以从中发现一个变色规律:

  1. 左旋
  2. parent的颜色赋值给uncle
  3. parent的颜色与uncle_right的颜色赋值为黑色
2.3.1.3uncle的左右结点都为黑色
  • parent为黑色

在这里插入图片描述

2.3.2 uncle红色
  • uncle为红色,其连接的结点必然为黑色,又因为delnode为黑,所以uncle的左右结点必然存在。
2.3.2.1 uncle的左右结点都为黑

在这里插入图片描述

整棵树每条路径的黑色结点数不变,但是此时cur的uncle更新为un_left为黑色,继续对uncle的情况进行判断即可,更新后parent为红且uncle为黑,一定是高度不变化的一种情况之一,再判断一次即可。

2.2 调整后所在树每条路径黑色结点的个数发生变化

parentdelnode的父节点,父节点另一个链接的结点设为uncle

2.2.1 uncle为黑色

  • 上面uncle为黑色且高度不变化的情况已经考虑过了,这里只剩下一种情况。
2.2.1.1 uncle的左右结点为黑色
  • parent为黑色
    在这里插入图片描述

整棵树每条路径的黑色结点数少一个,继续向上调整,cur等于parent,parent更新为cur的parent,最坏情况到根节点结束。

图解

在这里插入图片描述

实现代码

void ChangeColor(Node* cur,Node* parent)
{while (parent){if (parent->_left == cur){Node* uncle = parent->_right;//既然cur为黑结点,那么uncle就必然不可能为空。if (uncle->_col == RED){//父节点必然为黑结点,uncle的左右孩子必然为黑色结点。//进行左旋RotateL(parent);uncle->_col = BLACK;parent->_col = RED;//无需更新。}else{//再次强调uncle是不可能为空的,因为cur为黑色结点。//需要对uncle的左右孩子进行判断Node* un_right = uncle->_right;Node* un_left = uncle->_left;//un_right 与 un_left可能为空。// //uncle的左结点为红色,右节点为黑色或者为空if (un_left && un_left->_col == RED && (un_right == nullptr || un_right->_col == BLACK)){//先变色uncle->_col = RED;un_left->_col = BLACK;//进行右旋RotateR(uncle);}//uncle的右节点为红色,uncle的左节点为黑色或者红色或者为空else if (un_right && un_right->_col == RED){//先变色uncle->_col = parent->_col;parent->_col = un_right->_col = BLACK;//进行左旋RotateL(parent);//到此处达到平衡break;}//uncle的左节点为黑色且右节点也为黑色。else{//直接进行变色uncle->_col = RED;if (parent->_col == BLACK){//更新cur结点与parent结点,继续向上更新。cur = parent;parent = cur->_parent;}else//父节点为红色{//变父节点为黑色,跳出循环。parent->_col = BLACK;break;}}}}else{Node* uncle = parent->_left;//uncle结点为红色if (uncle->_col == RED){//变色保证路径的黑色结点的个数不变。//此时新更新的uncle的颜色变为黑色。uncle->_col = BLACK;parent->_col = RED;//父节点,un_left与un_right皆为黑色。RotateR(parent);}else{//uncle结点为黑色Node* un_right = uncle->_right;Node* un_left = uncle->_left;//uncle的右节点为红色,且左节点为黑色或者空if (un_right && un_right->_col == RED &&\(un_left == nullptr || un_left->_col == BLACK)){//变色保证路径的黑色结点数不发生变化uncle->_col = RED;un_right->_col = BLACK;//以uncle结点进行进行左旋,此时un_right成uncleRotateL(uncle);}//uncle的左节点为红色,且右节点为黑/红/空。else if (un_left && un_left->_col == RED){//先变色保证路径的黑色结点数不发生变化uncle->_col = parent->_col;parent->_col = un_left->_col = BLACK;//进行右旋RotateR(parent);break;}//uncle的左右结点都为黑色else{uncle->_col = RED;if (parent->_col == BLACK){cur = parent;parent = cur->_parent;}else{parent->_col = BLACK;break;}}}}}
}

总结

  • 理解的难点
  1. 分类讨论,逐步分析,拆解与转换问题
  2. 旋转与变色的底层逻辑是增加待删除路径的黑色结点数,同时保证另一棵树的每一条路径的黑色结点数不发生变化
  3. 时间与耐心

 博主认为这三点缺一不可。

 红黑树的删除比插入是难了不少的,不像AVL树的删除,可以复用之前的轮子,这里还得重新分析,每一种情况,博主看网上的大多数的讲解是比较抽象的,所以这里特意举了很多实际的例子进行分析,希望能降低一些红黑树插入的难度。

最后如果本篇文章对您有所帮助的话,不妨点个赞鼓励一下吧!

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

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

相关文章

【问题处理】GIT合并解决冲突后,导致其他人代码遗失的排查

GIT合并解决冲突后,导致其他人代码遗失的排查 项目场景问题描述分析与处理:1. 警告分析2. 文件分析3. 问题关键4. 验证 解决策略总结 📕作者简介:战斧,从事金融IT行业,有着多年一线开发、架构经验&#xff…

ChatGPT追祖寻宗:GPT-2论文要点解读

论文地址:Language Models are Unsupervised Multitask Learners 上篇:GPT-1论文要点解读 在上篇:GPT-1论文要点解读中我们介绍了GPT1论文中的相关要点内容,其实自GPT模型诞生以来,其核心模型架构基本没有太大的改变&a…

华为云云服务器云耀L实例评测 | 在华为云耀L实例上搭建电商店铺管理系统:一次场景体验

🌷🍁 博主猫头虎(🐅🐾)带您 Go to New World✨🍁 🦄 博客首页——🐅🐾猫头虎的博客🎐 🐳 《面试题大全专栏》 🦕 文章图文…

java写一个用于生成雪花id的工具类

我们创建一个类 叫 SnowflakeIdGenerator 作为生成雪花id的工具类 然后 编写代码如下 public class SnowflakeIdGenerator {private static final long START_TIMESTAMP 1609459200000L; // 设置起始时间戳,可以根据需要进行调整private static final long WORKER…

HBase 记录

HBase 管理命令 hbase hbck -details TABLE_NAME hbase hbck -repair TABLE_NAMEHBase概览 Master、RegionServer作用 RegionServer与Region关系 数据定位原理 https://blogs.apache.org/hbase/entry/hbase_who_needs_a_master RegionServer HBase Essentials.pdf (P25)…

四种常用的自动化测试框架

一直想仔细研究框架,写个流水账似的测试程序不难,写个低维护成本的测试框架就很难了,所以研究多种测试框架还是很有必要的,知道孰优孰劣,才能在开始编写框架的时候打好基础,今天读到了KiKi Zhao的翻译文章&…

中标麒麟--国产操作系统-九五小庞

那么,我国国产操作系统现状到底如何呢? 自 1999 年徐冠华部长一语点破我们的产业软肋之后,国产操作系统起步于国家“七五”计划期间,目前国产操作系统均是基于Linux内核进行的二次开发,中国国产操作系统进入Linux元年…

【网络】计算机网络基础

Linux网络 对网络的理解 在网络传输中存在的问题: 找到我们所需要传输的主机解决远距离数据传输丢失的问题怎么进行数据转发,路径选择的问题 有问题,就有解决方案; 我们把相同性质的问题放在一起,做出解决方案 解…

【Markdown】图片缩放

▚ 01 原图表示 语法为: ![替代文本](图片链接地址)其中,替代文本是在无法显示图片时显示的替代文本,而图片链接是指向图片的URL或相对路径。 例如,插入Panda图片: ![panda](https://img-blog.csdnimg.cn/e5f3…

(高频面试1)Redis缓存穿透、缓存击穿、缓存雪崩

目录 一:缓存数据 1.1 应用场景 1.2:缓存数据出现的问题 1.2.1 缓存穿透 1.2.2 解决办法 1.2.3 缓存击穿 1.2.4 解决办法 1.2.5 缓存雪崩 1.2.6 解决办法 一:缓存数据 1.1 应用场景 数据库查询结果缓存是一种常见的缓存应用场景&a…

MybatisPlus(5)

前言🍭 ❤️❤️❤️SSM专栏更新中,各位大佬觉得写得不错,支持一下,感谢了!❤️❤️❤️ Spring Spring MVC MyBatis_冷兮雪的博客-CSDN博客 上篇讲了增删的操作,这篇讲修改操作中的一个问题以及它对应的…

DataX实现Mysql与ElasticSearch(ES)数据同步

文章目录 一、Linux环境要求二、准备工作2.1 Linux安装jdk2.2 linux安装python2.3 下载DataX: 三、DataX压缩包导入,解压缩四、编写同步Job五、执行Job六、定时更新6.1 创建定时任务6.2 提交定时任务6.3 查看定时任务 七、增量更新思路 一、Linux环境要求…

加密算法发展简介

1:对称加密算法 客户端加密数据和服务端解密数据,使用的相同的秘钥: 固定秘钥:双方约定好一个固定秘钥; 随机秘钥:双方约定每次建立连接的时候,某固定BYTE为秘钥; 缺点&#xff1a…

JK405R-SOP16录音芯片ic方案的功能简介,可以内置录音30秒-高采样率

一、简介 JK405R是一颗SOP16封装的录音芯片,专用于录音的应用,芯片内置了30秒的录音空间,同时还支持外扩 spiflash方便不同录音时长的应用需求。芯片内置MIC的放大器,并且增益可调 同时芯片还具备超低功耗,待机2uA。…

2023/9/17周报

摘要 本周阅读了两篇论文,其一为一种基于空气质量时频域特征提取的hybrid预测方法,另一篇为基于烛台与视觉几何群模型的 PM2.5 变化趋势特征提取与分类预测方法。在第一篇文章中,通过小波变化,对数据进行分频,并设计了…

Linux界的老古董

Slackware 是由 Patrick Volkerding 制作的 Linux 发行版,从 1993 年发布至今也一直在 Patrick 带领下进行维护。7 月 17 日,Slackware 才刚刚过完它 24 岁的生日,看似年纪轻轻的它,已然是 Linux 最古老的发行版。 Slackware 的发…

[vue问题]开发中问题集合

“TypeError: Cannot read property ‘Request’ of undefined” 这是测试文件的报错,最后发现是因为项目启动的时候就报错了,是其它错误导致的,所以测试文件才会提示这种错误,当启动报错修复后,该问题没有了 热加载…

[计组03]进程详解2

目录 应用程序 系统调用 驱动 软件 再看进程 进程管理 如何管理 ? 创建一个进程 注意 PCB 文件描述表 进程相关重点 为什么有进程调度 虚拟空间地址 这次我们从更加详细全面的角度看一下进程在计算机中体系中的展现 应用程序 应用程序 调动 系…

VR古迹复原——数字化复原圆明园,开创文化遗产保护新方式

圆明园是中国历史上一处重要的文化遗产,曾经被誉为“万园之园”,但在1860年的英法联军侵华战争中被毁。近年来,虚拟现实技术不断发展,广州华锐互动利用VR全景技术复原了圆明园,通过VR设备,人们可以在家中就…

CRM与chatGPT结合的效果

2023年ChatGPT是当之无愧的行业热词,从诞生到爆红短短5天,注册用户数就超过100万,截止到2023年1月底已经有超过1亿用户。在这样的背景下,Zoho CRM系统在业内较早推出集成ChatGPT的相关功能,接下来我们就来分享CRM接入C…