红黑树结构原理的图文讲解(非代码)

article/2025/10/1 6:13:07

1.引言

HashMap的基本结构是数组,链表和红黑树。以数组为基本形态,数组中的元素先以链表形式储存,当链表的长度超过8时(包含数组上的那个链表头)就会将链表转换为红黑树,以加快修改和查询效率。当然除了HashMap还有很多地方都会用到红黑树,理解红黑树的原理还是比较重要的。

2.概念与由来

红黑树的本质是二叉树,二叉树在插入元素的时候是根据关键字(可以理解为用来识别每个节点的id,一般是hash来判断)的大小来判断插入到哪一个分支的,如下图所示:

(备注:大写字母代表每个节点相当于每个节点的名字没有实际意义在本文中方便文字说明,数字代表每个节点的关键字的大小有实际意义

规律是父节点的关键字大于左子节点且小于右子节点,即B<A<C的关系。

举个插入的例子:当新插入一个元素是会判断其关键字大小如果大于A的,则插入到A的右子节点也就是C,但是此处已经有了节点存在了,然后继续判断是否大于C,如果小于C,则插入到C的左子节点,正好此处为空存在,插入后形成下图所示:

但是按照这个规则插入就遇到一个问题,如下图所示的情况:

这样的现状导致查询效率非常低,如果要找节点J,这样一串遍历下来就跟链表结构区别不大了,从而失去了树结构的优势。为了解决这个问题出现了平衡二叉树。而平衡二叉树在原始二叉树基础上加了平衡节点的机制,每插入一次元素后都会自动去判断是否失衡了,如果失衡了则会自动调整节点的布局结构使其从根节点(最顶端的节点)到每一个叶节点(最低端的节点)的距离不会相差太多。然而平衡二叉树的要求过于严格,几乎每一次插入都要调整节点的布局,使得插入操作效率变得很低,于是有了一个这种的办法那就是红黑树。

3.红黑树规则

一共如下四条规则:

  • 每个节点不是红色就是黑色的;

  • 根节点(顶端节点)总是黑色的;

  • 如果节点是红色的,则它的子节点必须是黑色的(反之不一定);

  • 从根节点到叶节点或空子节点的每条路径,必须包含相同数目的黑色节点(即相同的黑色高度)。

根据该规则,新插入的节点全都是红色,然后再根据具体情况做颜色变换甚至旋转。

原因:如果我们新插入的颜色是黑色的话,那么每插入一个节点都会违背第四条规则,这样就导致每次都做变色甚至旋转。当插入红色节点时,首先不会违反第四条规则,并且如果其父节点是黑色时也不会违反第三条,至于第二条规则大部分情况不会违背基本不予以考虑了。这样一来插入红色就不是每次都需要变色或者旋转了,这样就可以优化计算机的处理过程。

4.旋转机制

旋转分为向右旋转和向左旋转,下图所示是向右旋转,第一次看旋转的图可能会有些困难,但是看多了一眼就能看出来如何去旋转才能达到平衡了。外圈节点顺时针旋转一个节点的角度,中间红圈的连接点转移到C的位置(旋转完了C的位置就不是C了,这个箭头指示表示位置,而不是连接到哪一个节点)。

这样旋转完了就会变成下图所示的形状,这样就看上去平衡多了。整个旋转过程可以空间想象一下。

下图是向左旋转的示意图,这一个稍微复杂一点:

旋转完成后,如下图所示:

其实不管怎么旋转,宗旨就是两点,一是节点的高度(从顶点到低端的节点数量)差距不大,二是满足关键字大小的规则。

虽然刚开始看这种结构旋转有些不适应,看多了一看原始图就能想象出如何旋转可以达到平衡了。但是这只是从目的出发去使其平衡,光靠这些不能细化什么样的二叉树才能满足红黑树,并且这只是我们人类一看就能明白如何去旋转来达到平衡,但是计算机做不到,然后又加入了颜色这一指标(也便于指定规则来约束计算机)。

5.插入过程演化(该过程为的是更好的理解所有变化操作的情况和做法)

5-1.对在空的红黑树中插入第一个元素时,插入红色节点,由于违反第二条规定,做变色操作,变为黑色节点,如下图所示。

5-2.继续插入两个子节点,不需要任何变色操作,如下图所示。

5-3.给节点B插入左子节点D,插入后由于新节点的父节点B和叔叔C节点(祖父节点的另一个子节点)也都是红色,违反了第三条,最简单的办法就是将其父节点B和叔叔节点C变为黑色,如下图所示。

5-3.给节点D插入左子节点E,插入后首先插入节点E为红色,其父节点D为红色,且新插入的E是其父节点D的左子节点,解决办法是,首先将其父节点D变为黑色,祖父节点B变为红色,然后以祖父节点B为支点向右旋转,如下图所示。

5-4.给节点B插入右子节点F,其父节点B和叔叔节点E均为红色,将父节点B和叔叔节点E变为黑色并将其祖父节点D变成红色,如下图所示。

5-5.多插入几个节点便于后面观察,如下图所示。

5-6.给G插入左子节点K,其父节点和叔叔节点均为红色,所以将父节点和叔叔节点变为黑色且祖父节点变为红色,如下图从1变成2。这样B和D都是红色又会冲突,此时将B看作是新插入的节点,B的父节点为红色,叔叔节点为黑色,且B是其父节点的右子节点,以D为支点向左旋转,如下图3变成4(蓝色箭头代表转移的位置并不是代表连接到该节点上)。接下来D和B都是红色依然冲突,将D看着是新插入的节点,其父节点B为红色,叔叔节点C为黑色,且是其父节点B的左子节点,所以将其父节点B变为黑色,祖父节点A变为红色,并以A节点为支点向右旋转,如下图5变成6再变成7,这样整个红黑树就平衡了。

6.规则总结 

看完上面的插入过程,其实中间有很多操作是重复的,所以总结需要变化的情况有以下3种:

  • 1.插入节点的父节点和其叔叔节点均为红色的;

  • 2.插入节点的父节点是红色,叔叔节点是黑色(或为空),且插入节点是其父节点的右子节点;

  • 3.插入节点的父节点是红色,叔叔节点是黑色(或为空),且插入节点是其父节点的左子节点;

对应上面的3种情况,所需要进行的操作分别是:

  • 1.将其父节点和叔叔节点变为黑色,祖父节点变为红色(如果祖父节点是根节点则不需要改变);

  • 2.以其父节点为支点向左旋转;

  • 3.将其父节点变为黑色,祖父节点变为红色,以祖父节点为支点向右旋转;

 


http://chatgpt.dhexx.cn/article/Bklxb48u.shtml

相关文章

二叉树与红黑树见解

目录 一、红黑树简介二、 红黑树的特性三、红黑数的应用四、红黑树的原理实现4.1 识别红黑树4.2 红黑树节点的旋转4.3 插入节点4.3.1分情况讨论&#xff1a;4.3.2 代码示例 4.4删除节点相关引用 一、红黑树简介 红黑树是一种自平衡的二叉查找树&#xff0c;是一种高效的查找树…

什么是红黑树(内存最优的二叉树)

一.红黑树定义 红黑树(Red Black Tree) 是一种自平衡二叉查找树&#xff0c;是在计算机科学中用到的一种数据结构&#xff0c;典型的用途是实现关联数组。 它是在1972年由Rudolf Bayer发明的&#xff0c;当时被称为平衡二叉B树(symmetric binary B-trees)。后来&#xff0c;在1…

【二叉树进阶】红黑树(Red Black Tree) - 平衡二叉搜索树

文章目录 一、红黑树的概念二、红黑树的性质2.1 红黑树和AVL树效率对比 三、红黑树的结构&#xff08;KV模型&#xff09;四、红黑树的插入4.1 插入节点4.2 平衡化操作&#xff08;难点&#xff09;4.2.1 情况一4.2.2 情况二4.2.3 情况三 4.3 总结 五、红黑树的验证六、红黑树的…

MySQL 慢查询日志导入 Elasticsearch 可视化查询分析

当应用程序后台 SQL 查询慢的时候我们一般第一时间会查看数据库慢查询记录&#xff0c;但是慢查询记录是原始文本&#xff0c;直接查询搜索分析比较费时费力&#xff0c;虽然业界有针对 MySQL 慢查询分析的命令行工具&#xff08;比如&#xff1a;pt-query-digest&#xff09;&…

MySQL 慢查询日志如何查看及配置

简介 MySQL 慢查询日志是排查问题 SQL 语句&#xff0c;以及检查当前 MySQL 性能的一个重要功能。 查看是否开启慢查询功能&#xff1a; 说明&#xff1a; slow_query_log 慢查询开启状态 slow_query_log_file 慢查询日志存放的位置&#xff08;这个目录需要MySQL的运行帐号的…

MySQL高级篇——聊聊MySQL的慢查询日志

文章目录&#xff1a; 1.数据库服务器的优化步骤 2.查看系统性能参数 3.定位执行慢的 SQL&#xff1a;慢查询日志 4.查看 SQL 执行成本&#xff1a;SHOW PROFILE 1.数据库服务器的优化步骤 当我们遇到数据库调优问题的时候&#xff0c;该如何思考呢&#xff1f;这里把思考…

清理mysql慢查询日志_MySQL清理慢查询日志slow_log的方法

一、清除原因 因为之前打开了慢查询,导致此表越来越大达到47G,导致磁盘快被占满,使用xtrabackup进行备份的时候文件也超大。 mysql> show variables like log_output%; Connection id: 1694401091 Current database: mysql +---------------+-------+ | Variable_name | …

mysql 慢查询日志的设置与优化

目录 1 引言 2 慢查询日志配置 3 分析工具 1 引言 MySQL数据中有记录慢查询的一种手段。并且是MySQL自带的。可用来排查那些查询sql语句执行得慢。从而给开发者提供一个调优得依据。 MySQL 慢查询的相关参数解释&#xff1a; slow_query_log &#xff1a;是否开启慢查…

如何开启mysql慢查询日志?

1、查看mysql的慢查询日志是否开启 show variables like %query%; 可以看到slow_query_log的值是OFF&#xff0c;也就是mysql默认是不启用慢查询日志的。 这里还有个long_query_time&#xff0c;默认是10秒&#xff0c;也就是超过了10秒即为慢查询。 log_queries_not_using_…

MySQL慢查询日志详解

本次代码执行环境的mysql版本是 &#xff1a;5.6.37-log 1.慢查询日志概念(也叫慢日志):在 MySQL 中执行时间超过指定时间的 SQL 语句 2.常见的几个相关的变量 (可以直接去mysql下的配置文件my.cnf文件中去改,我下面是直接在SQLyog中进行操作) 默认情况下慢查询日志是关闭的…

MySQL 慢查询日志 使用方法浅析 日志定位与优化技巧

目录 前言 1、如何开启使用慢查询日志&#xff1f; 1.1 开启慢查询日志 1.2 设置慢查询阈值 1.3 确定慢查询日志的文件名和路径 1.3.1 查询MySQL数据目录 1.3.2 查询慢查询日志文件名 1.3.3 查询全局设置变量 1.3.4 查询单个变量命令 1.3.5 其他注意事项 2、如何定位并优…

mysql慢查询日志在哪里

如何查找MySQL中查询慢的SQL语句 你是指慢查询日志吗&#xff1f; 在my.ini中加上下面两句话 log-slow-queriese:\mysql5.5\mysql_slow_query.log long_query_time10 前面一句是设置慢查询日志存放路径&#xff0c;第二句是指多少秒以上算慢查询&#xff0c;上面的语句&#xf…

MySQL慢查询日志分析

&#xff08;1&#xff09;慢查询日志 MySQL提供了慢SQL的日志记录功能&#xff0c;我们可以通过设置一些属性来记录系统使用过程中慢查询的执行日志。使用MySQL慢查询日志对有效率问题的SQL进行监控。 查看属性 【1】查看MySQL是否开启慢查询日志记录功能 show variables l…

MySQL优化之慢日志查询

目录 一、慢查询日志(slow_query_log)概念二、慢查询日志实践1. 打开慢查询日志开关2. 设置合理的、业务可以接受的慢查询时间上限long_query_time3. 压测执行各种业务4. 查看慢查询日志5. 用explain分析这些耗时的sql语句&#xff0c;从而针对性优化 三、show profiles查看sql…

MySQL日志(一)—— 慢查询日志slow log

一、慢查询日志&#xff08;slow log&#xff09; 慢查询日志&#xff0c;就是查询超过一定的时间没有返回结果的时候&#xff0c;MySQL会将执行的SQL记录到日志中&#xff0c;这个日志&#xff0c;就称为慢查询日志。通过分析慢查询日志&#xff0c;可以快速找出执行慢的SQL语…

【OpenCv3】 VS C++ (五):SLIC超像素分割算法

下一节地址&#xff1a;https://blog.csdn.net/qq_40515692/article/details/102788157 OpenCv专栏&#xff1a;https://blog.csdn.net/qq_40515692/article/details/102885061 超像素&#xff08;SuperPixel&#xff09;&#xff0c;就是把原本多个像素点&#xff0c;组合成一…

superpixels(超像素)

superpixels(超像素&#xff09; 1.理解&#xff1a; 超像素不是在普通的像素基础上继续微观细分&#xff0c;超像素是一系列像素的集合&#xff0c;这些像素具有类似的颜色、纹理等特征&#xff0c;距离也比较近。其中超像素比较常用的一种方法是SLIC Semantic Segmentatio…

Seeds超像素分割

#%% SEED超像素分割 import cv2 import numpy as np import imageio # print(dir(cv2.ximgproc))img imageio.imread(rE:\Vaihingen\data\orginalimages\top_mosaic_09cm_area31.tif)[:,:,::-1] converted_img cv2.cvtColor(img, cv2.COLOR_BGR2HSV)# print(type(img_feature…

Python实现超像素分割

目录 一、什么是超像素&#xff1f;二、超像素具有哪些特点&#xff1f;三、Simple Linear Iterative Clustering (SLIC)算法实现步骤四、SLIC算法代码实现五、效果展示和分析六、基于超像素的边缘检测代码七、基于超像素的边缘检测效果展示与分析八、思维扩展参考资料注意事项…

基于Matlab的SLIC超像素分割算法分析

SLIC超像素分割算法分析 1&#xff1a;导入原始照片&#xff0c;初始化聚类中心&#xff0c;按照设定的超像素个数&#xff0c;在图像内均匀的分配聚类中心。假设图片总共有 N 个像素点&#xff0c;预分割为 s 个相同尺寸的超像素&#xff0c;那么每个超像素的大小为N/ s &…