【数据结构与算法】【16】红黑树

什么是红黑树

红黑树是在AVL树的基础上改进的一种二叉查找树,英文名R-B Tree

上一篇我们已经讲过,AVL树是一种高度平衡的二叉查找树

它的查找效率最高,但是由于要维护平衡性,插入和删除效率便降低了

红黑树则是降低了一点平衡性的要求,从而来提升插入和删除效率

由于在实际场景中,很难有数据只查询不修改的,因此红黑树的适用场景更广,综合效率更高

红黑树的特性

红黑树的节点必须满足以下五个特性

  1. 每个节点带有颜色,要么红色,要么黑色
  2. 根节点必须为黑色
  3. 叶节点必须为黑色(红黑树所有的叶节点,都是虚构出来的NIL节点,这是为了方便调整红黑树的平衡性)
  4. 每个红节点的孩子必定为黑色(不存在两个连续的红色节点)
  5. 任意节点,到其所有的叶节点,中间经过的黑色节点数量是相同的

以上规定,最终决定了红黑树的平衡性:

根节点到任意叶节点的最长路径,不多于最短路径的两倍(路径全黑时最短,红黑相间时最长)

可见,红黑树中的节点平衡因子,是可以大于1的

在这里插入图片描述

红黑树插入时的平衡性修复

红黑树的平衡修复,主要是通过染色、左旋、右旋三种方式来实现的

在向红黑树插入新节点时,我们一般都将节点染成红色

因为插入红色节点时,只需要处理两个节点连续红色的问题,比较容易修复

如果插入黑色节点,则会出现根节点到叶节点黑色点数量异常的问题,这个比较难修复

红黑树的插入大致可以分为七大类情形,在讲述这七大类情形时,我们先了解一下术语定义

在这里插入图片描述

  • N:Now,刚插入的待平衡的新节点
  • P:Parent,新节点的父节点
  • GP:GrandParent:祖父节点,即父节点的父节点
  • U:Uncle,叔父节点,即父节点的兄弟节点

情形一:N为根节点

N染成黑色,直接作为红黑树根节点即可,修复完成

情形二:P为黑色

黑色点数量不变,不影响平衡性,无需任何处理,修复完成

情形三:P为红色,U为红色

在这里插入图片描述
P和U染黑,GP染红。再以GP作为新的N节点,递归修复平衡性

情形四:P为红色,U为黑色,P左N左

在这里插入图片描述
GP右旋,P染黑,GP染红,修复完成

情形五:P为红色,U为黑色,P右N右

在这里插入图片描述
GP左旋,P染黑,GP染红,修复完成

情形六:P为红色,U为黑色,P左N右

在这里插入图片描述
N右旋。再以P作为新的N节点,递归修复平衡性

情形七:P为红色,U为黑色,P右N左

在这里插入图片描述
N左旋。再以P作为新的N节点,递归修复平衡性

红黑树删除时的平衡性修复

红黑树的删除比较繁琐,分为很多种情况,每种情况又有很多子类型

整体上,根据节点位置,可以分为四大类情况

  1. 删除节点为叶节点
  2. 删除节点只有左孩子,没有右孩子
  3. 删除节点只有右孩子,没有左孩子
  4. 删除节点既有左孩子,又有右孩子

下面我们逐个情况来讲解如何进行删除和再平衡

在此之前,我们先要搞清楚,怎么样才算平衡性修复成功

这个判断标准就是:根节点到所有NIL节点的黑色出现次数,和平衡之前相等

我们统一将被删除节点称为D节点,D节点兄弟为B节点,D节点父亲为P节点,B节点孩子分为LN和RN节点

1 D为叶节点

这种情况又分为D为红色,D为黑色两大类情况

1-1 D为红色

直接删除D节点即可

在这里插入图片描述
1-2 D为黑色

这又分为D在P左侧,以及D在P右侧的情况,我们只讲解D在左侧的情况,另一种情况处理方式是一样的

对于红黑树的任意叶节点,其最下面两层的结构,只可能是以下五种情况

在这里插入图片描述

由于D为黑色,且为叶节点,要保持平衡性,则P右侧必有一个黑色节点,且最多两层,只可能是以下五种情况

在这里插入图片描述
由于这个情况下包含太多子情景了,我们先讲234的情况

2 D有左孩子,没有右孩子

LC的值赋给D,删除LC

在这里插入图片描述
3 D有右孩子,没有左孩子

RC的值赋给D,删除RC

在这里插入图片描述
4 D有左孩子,也有右孩子

LC的值赋给D,问题转换为递归删除LC

在这里插入图片描述
下面我们回到前面的问题,再来讲解D为叶节点,且D为黑色的五种情况

1-2-1

在这里插入图片描述
1-2-2
在这里插入图片描述

1-2-3
在这里插入图片描述

1-2-4
在这里插入图片描述

1-2-5
在这里插入图片描述

红黑树代码实现

红黑树实现代码的核心是插入和删除后的再平衡

由于红黑树的情景实在是太多了,这里不再逐个实现,一般面试也不会让大家手动去实现红黑树

但是当大家拿到一张红黑树的图时,自己应当知道如何去删除某个节点并进行平衡修复

查看全文

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

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章:

【数据结构与算法】【16】红黑树

什么是红黑树
红黑树是在AVL树的基础上改进的一种二叉查找树,英文名R-B Tree
上一篇我们已经讲过,AVL树是一种高度平衡的二叉查找树
它的查找效率最高,但是由于要维护平衡性,插入和删除效率便降低了
红黑树则是降低了一点平衡……

【RStudio中文乱码】【两个方法】

文章目录方法一方法二Reference方法一
File→\rightarrow→Reopen with Encoding→\rightarrow→"UTF-8"→\rightarrow→"OK"
方法二
Tools→\rightarrow→Global Options→\rightarrow→Code→\rightarrow→Setting→\rightarrow→Default text enco……

云原生之容器编排实践-SpringBoot应用以Deployment方式部署到minikube以及弹性伸缩

背景
在实际生产环境下,我们更多的是使用 yaml 描述文件来启动一个 Pod ,并设置 kind 属性值为 Deployment 类型。
Deployment
使用 Deployment 来部署应用,重点关注其可以实现应用服务的动态扩缩容。
需要注意的是:应用本身需……

fastJson序列化与反序列化

本人刚入坑Java岗小菜鸟一枚。 昨天写需求时出现一个复杂的json数据需要转换成Java对象。json就那么回事嘛,有什么了不起的,一顿操作猛如虎啊。结果一排排红色的日志格外的刺眼的映入了眼帘。抱歉啊我不该对你不存在敬畏之心。 fastjson:
我&#xff1……

回流焊机T962维修

我有一台上图中的回流焊机 排烟风扇坏不工作了,体现在温控曲线下降过程总是超温;在超温的时候我观察到风扇状态灯是亮的,但是风扇不转。这样焊接出来的板子会导致有点偏黄,但是也能使用,于是这个故障就搁置了差不多2年……

[C++11 多线程同步] — 条件变量

1 std::condition_variable 类介绍
当 std::condition_variable 对象的某个 wait 函数被调用的时候,它使用 std::unique_lock(通过 std::mutex) 来锁住当前线程。当前线程会一直被阻塞,直到另外一个线程在相同的 std::condition_variable 对象上调用了 ……

【Shell编程】Shell中Bash变量-位置参数变量

目录系列文章位置参数变量实例-理解参数实例-剩余参数实例-区别整体对待和单独对待系列文章
【Shell编程】Shell基本概述与脚本执行方式
【Shell编程】Shell中Bash基本功能
【Shell编程】Bash变量-用户自定义变量 位置参数变量
位置参数变量作用$nn为数字,$0代表……

时间序列分析ARMA模型原理及Python statsmodels实践(上)

目录1. 时间序列及相关基本概念1.1. 时间序列分解1.2. 时间平稳序列1.3. 自相关与自相关函数(ACF)1.4. 白噪声及Ljung-Box检验1.4.1. 白噪声1.4.2. Ljung-Box检验1.5. 时间序列分析的平稳性1.5.1. 时间序列的平稳性检验1.5.2. 纯随机性检验1.6. 差分法2.……

ThinkAutomation下载文件的通配符

ThinkAutomation下载文件的通配符 对于数据库操作类型,现在可以从同一解决方案中的其他操作中选择现有连接字符串,而不是在每个操作上构建/输入连接字符串。 “云存储”操作现在支持用于下载文件的通配符(例如:/myfiles/docs/*.pdf)。 Gmail消……

有序顺序表的插入

下面看问题场景 如图是一个有序表,有序表是用数组承载的,然后我想把 元素 8插入到有序表 , 怎么实现呢? 下面开始用人脑模拟?
要把 8 插入到有序表 ,先从有序表的第一个元素和8进行比较 ,依次看到了7 ,下一个元素9大于8,停止遍历,
我们就把 8 插入到7和 9 之间,但是没有空位……

获取文件MD5小案例(未拆分文件)

文章目录前端获取MD5后端获取MD5前端获取MD5
1、引入js
<script src"js/spark-md5.min.js" type"text/javascript"></script>注:spark-md5库GitHub链接 2、这里是一个按钮和被隐藏调的<input/>标签 <body><button……

Java 进阶(15)线程安全集合

CopyOnWriteArrayList
线程安全的ArrayList,加强版读写分离。
写有锁,读⽆锁,读写之间不阻塞,优于读写锁。
写⼊时,先copy⼀个容器副本、再添加新元素,最后替换引⽤。
使⽤⽅式与ArrayList⽆异。
示例……

HR:面试官最爱问的linux问题,看看你能答对多少

文章目录摘要Linux的文件系统是什么样子的?如何访问和管理文件和目录?如何在Linux中查看和管理进程?如何使用Linux命令行工具来查看系统资源使用情况?如何配置Linux系统的网络设置?如何使用Linux的cron任务调度器来执行……

vscode开发常用的工具栏选项,查看源码技巧以及【vscode常用的快捷键】

一、开发常用的工具栏选项
1、当前打开的文件快速在左侧资源树中定位: 其实打开了当前的文件已经有在左侧资源树木定位了,只是颜色比较浅 2、打开太多文件的时候,可以关闭 3、设置查看当前类或文件的结构 OUTLINE
相当于idea 查看当前类或接……

数据要素化条件之一:原始性

随着技术的发展,计算机不仅成为人类处理信息的工具,而且逐渐地具有自主处理数据的能力,出现了替代人工的数据智能技术。数据智能的大规模使用需要关于同一分析对象或同一问题的、来源于不同数据源的海量数据。这种数据必须是针对特定对象的记……

【面试题 高逼格利用 类实现加法】编写代码, 实现多线程数组求和.

编写代码, 实现多线程数组求和.关键1. 数组的初始化关键2. 奇偶的相加import java.util.Random;public class Thread_2533 {public static void main(String[] args) throws InterruptedException {// 记录开始时间long start System.currentTimeMillis();// 1. 给定一个很长的……

一个python训练

美国:28:麻省理工学院,斯坦福大学,哈佛大学,加州理工学院,芝加哥大学,普林斯顿大学,宾夕法尼亚大学,耶鲁大学,康奈尔大学,哥伦比亚大学,密歇根大学安娜堡分校,约翰霍普金斯大学,西北大学,加州大学伯克利分校,纽约大学,加州大学洛杉矶分校,杜克大学,卡内基梅隆大学,加州大学圣地……

Mybatis03学习笔记

目录 使用注解开发
设置事务自动提交
mybatis运行原理
注解CRUD
lombok使用(偷懒神器,大神都不建议使用)
复杂查询环境(多对一)
复杂查询环境(一对多)
动态sql环境搭建
动态sql常用标签……

设置或取得c# NumericUpDown 编辑框值的方法,(注意:不是Value值)

本人在C#开发中使用到了NumericUpDown控件,但是发现该控件不能直接控制显示值,经研究得到下面的解决办法
NumericUpDown由于是由多个控件组合而来的控件,其中包含一个类似TextBox的控件,若想取得或改变其中的值要使用如下方法
N……

使用NPOI 技术 的SetColumnWidth 精确控制列宽不能成功的解决办法(C#)

在使用NPOI技术开发自动操作EXCEL软件时遇到不能精确设置列宽的问题。

ISheet sheet1 hssfworkbook.CreateSheet("Sheet1");
sheet1.SetColumnWidth(0, 50 * 256); // 在EXCEL文档中实际列宽为49.29
sheet1.SetColumnWidth(1, 100 * 256); // 在EXCEL文……

Published by

风君子

独自遨游何稽首 揭天掀地慰生平

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注