集合系列(十三) -红黑树实现分析详解

一、故事的起因

JDK1.8最重要的就是引入了红黑树的设计(当冲突的链表长度超过8个的时候),为什么要这样设计呢?好处就是避免在最极端的情况下冲突链表变得很长很长,在查询的时候,效率会非常慢。

  • 红黑树查询:其访问性能近似于折半查找,时间复杂度O(logn);
  • 链表查询:这种情况下,需要遍历全部元素才行,时间复杂度O(n);

本文主要是讲解红黑树的实现,只有充分理解了红黑树,对于后面的分析才会更加顺利。

简单的说,红黑树是一种近似平衡的二叉查找树,其主要的优点就是“平衡“,即左右子树高度几乎一致,以此来防止树退化为链表,通过这种方式来保障查找的时间复杂度为log(n)。


关于红黑树的内容,网上给出的内容非常多,主要有以下几个特性:

  • 1、每个节点要么是红色,要么是黑色,但根节点永远是黑色的;
  • 2、每个红色节点的两个子节点一定都是黑色;
  • 3、红色节点不能连续(也即是,红色节点的孩子和父亲都不能是红色);
  • 4、从任一节点到其子树中每个叶子节点的路径都包含相同数量的黑色节点;
  • 5、所有的叶节点都是是黑色的(注意这里说叶子节点其实是上图中的 NIL 节点);

在树的结构发生改变时(插入或者删除操作),往往会破坏上述条件3或条件4,需要通过调整使得查找树重新满足红黑树的条件。

二、调整方式

上面已经说到当树的结构发生改变时,红黑树的条件可能被破坏,需要通过调整使得查找树重新满足红黑树的条件。

调整可以分为两类:**一类是颜色调整,即改变某个节点的颜色,这种比较简单,直接将节点颜色进行转换即可;另一类是结构调整,改变检索树的结构关系。**结构调整主要包含两个基本操作:左旋(Rotate Left)右旋(RotateRight)

2.1、左旋

左旋的过程是将p的右子树绕p逆时针旋转,使得p的右子树成为p的父亲,同时修改相关节点的引用,使左子树的深度加1,右子树的深度减1,通过这种做法来调整树的稳定性。过程如下:

以jdk1.8为例,打开HashMap的源码部分,红黑树内部类TreeNode属性分析:

static final class TreeNode<K,V> extends LinkedHashMap.Entry<K,V> {//指向父节点的指针TreeNode<K,V> parent;//指向左孩子的指针TreeNode<K,V> left;//指向右孩子的指针TreeNode<K,V> right;//前驱指针,跟next属性相反的指向TreeNode<K,V> prev;//是否为红色节点boolean red;......
}

左旋方法rotateLeft如下:

/** 左旋逻辑*/
static <K,V> TreeNode<K,V> rotateLeft(TreeNode<K,V> root,TreeNode<K,V> p) {//root:表示根节点//p:表示要调整的节点//r:表示p的右节点//pp:表示p的parent节点//rl:表示p的右孩子的左孩子节点TreeNode<K,V> r, pp, rl;//r判断,如果r为空则旋转没有意义if (p != null && (r = p.right) != null) {//多个等号的连接操作从右往左看,设置rl的父亲为pif ((rl = p.right = r.left) != null)rl.parent = p;//判断p的父亲,为空,为根节点,根节点的话就设置为黑色if ((pp = r.parent = p.parent) == null)(root = r).red = false;//判断p节点是左儿子还是右儿子else if (pp.left == p)pp.left = r;elsepp.right = r;r.left = p;p.parent = r;}return root;
}
2.2、右旋

了解了左旋转之后,相应的就会有右旋,逻辑基本也是一样,只是方向变了。右旋的过程是将p的左子树绕p顺时针旋转,使得p的左子树成为p的父亲,同时修改相关节点的引用,使右子树的深度加1,左子树的深度减1,通过这种做法来调整树的稳定性。实现过程如下:

同样的,右旋方法rotateRight如下:

/** 右旋逻辑*/
static <K,V> TreeNode<K,V> rotateRight(TreeNode<K,V> root,TreeNode<K,V> p) {//root:表示根节点//p:表示要调整的节点//l:表示p的左节点//pp:表示p的parent节点//lr:表示p的左孩子的右孩子节点TreeNode<K,V> l, pp, lr;//l判断,如果l为空则旋转没有意义if (p != null && (l = p.left) != null) {//多个等号的连接操作从右往左看,设置lr的父亲为pif ((lr = p.left = l.right) != null)lr.parent = p;//判断p的父亲,为空,为根节点,根节点的话就设置为黑色if ((pp = l.parent = p.parent) == null)(root = l).red = false;//判断p节点是右儿子还是左儿子else if (pp.right == p)pp.right = l;elsepp.left = l;l.right = p;p.parent = l;}return root;
}

三、操作示例介绍

3.1、插入调整过程图解

3.2、删除调整过程图解

3.3、查询过程图解

四、总结

至此,红黑树的实现就基本完成了,关于红黑树的结构,有很多种情况,情况也比较复杂,但是整体调整流程,基本都是先调整结构然后调整颜色,直到最后满足红黑树特性要求为止。整篇文章,如果有理解不当之处,欢迎指正!

五、参考

1、简书 - JDK1.8红黑树实现分析

2、知乎 - 史上最清晰的红黑树讲解

六、写到最后

最近无意间获得一份阿里大佬写的技术笔记,内容涵盖 Spring、Spring Boot/Cloud、Dubbo、JVM、集合、多线程、JPA、MyBatis、MySQL 等技术知识。需要的小伙伴可以点击如下链接获取,资源地址:技术资料笔记。

不会有人刷到这里还想白嫖吧?点赞对我真的非常重要!在线求赞。加个关注我会非常感激!

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

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

相关文章

uniapp自定义导航栏左中右内容和图标,以及点击事件

uniapp自定义导航栏左中右内容和图标&#xff0c;以及点击事件 效果&#xff1a; 页面&#xff1a; <view class"navigation-bar"><view class"navigation-bar-left" click"navigateBack"><u-icon name"arrow-left"…

数学建模(灰色关联度 python代码 案例)

目录 介绍&#xff1a; 模板&#xff1a; 案例&#xff1a;哪些原因影响结婚率 数据标准化&#xff1a; 灰色关联度系数&#xff1a; 完整代码&#xff1a; 结果&#xff1a; 介绍&#xff1a; 灰色关联度是一种多指标综合评价方法&#xff0c;用于分析和评价不同指标之…

【DP】01背包问题与完全背包问题

一、01背包问题 有 N件物品和一个容量是 V 的背包。每件物品只能使用一次。 第 i 件物品的体积是 vi&#xff0c;价值是 wi。 求解将哪些物品装入背包&#xff0c;可使这些物品的总体积不超过背包容量&#xff0c;且总价值最大。 输出最大价值。 输入格式 第一行两个整数&…

Email API有哪些主要功能?如何用API发信?

Email API的安全性如何保障&#xff1f;如何选择API进行集成&#xff1f; Email API简化了电子邮件交互的复杂性&#xff0c;让开发者能够轻松地将邮件功能集成到他们的应用中。那么&#xff0c;Email API究竟有哪些主要功能呢&#xff1f;接下来&#xff0c;AokSend将一一探讨…

在Linux搭建Emlog博客结合内网穿透实现公网访问本地个人网站

文章目录 前言1. 网站搭建1.1 Emolog网页下载和安装1.2 网页测试1.3 cpolar的安装和注册 2. 本地网页发布2.1 Cpolar临时数据隧道2.2.Cpolar稳定隧道&#xff08;云端设置&#xff09;2.3.Cpolar稳定隧道&#xff08;本地设置&#xff09; 3. 公网访问测试总结 前言 博客作为使…

小迪安全46WEB 攻防-通用漏洞PHP 反序列化原生类漏洞绕过公私有属性

#知识点&#xff1a; 1、反序列化魔术方法全解 2、反序列化变量属性全解 3、反序列化魔术方法原生类 4、反序列化语言特性漏洞绕过 -其他魔术方法 -共有&私有&保护 -语言模式方法漏洞 -原生类获取利用配合 #反序列化利用大概分类三类 -魔术方法的调用…

Backend - Echarts(柱状条形图)

一、下载并安装 &#xff08;一&#xff09;官网 https://echarts.apache.org/zh/index.html &#xff08;二&#xff09;下载依赖 1. 官网里选择下载方式 https://echarts.apache.org/handbook/zh/basics/download/ 2. 官网github方式下载 https://github.com/apache/echa…

如何利用AI助力你的工作,学会这些AI操作秘密,让AI给你打工赚钱

随着科技的进步,AI已逐渐融入我们日常生活的方方面面,成为提升工作效率、拓展个人能力的得力助手。在这个时代,不是AI替代我们,而是那些懂得利用AI的同事将更具竞争力。学会让AI为你“打工”,不仅能够节省时间、提升效率,还能帮助我们发现新机会,实现创新。 AI的优势…

数据结构——认识二叉树

这是一篇回顾二叉树概念的文章 前言&#xff1a;一、了解树形结构1.2 树的定义2.2 树的相关概念2.2 树的表示形式 二、了解二叉树结构和性质2.1 什么是二叉树&#xff1f;2.2 二叉树的性质2.3 二叉树的遍历2.3 二叉树的应用范围2.5 二叉树的优缺点 三、掌握二叉树的存储结构3.1…

关闭 Microsoft Word 2010 配置窗口

关闭 Microsoft Word 2010 配置窗口 References 出现这种问题&#xff0c;主要是安装时所用账户和目前登陆的账户不为同一个账户造成的。或者你进行过覆盖安装或是重新安装过系统&#xff0c;但是 office 的安装目录没有更改。先激活 Microsoft Office&#xff0c;然后执行下列…

springcloud第4季 负载均衡的介绍3

一 loadbalance 1.1 负载均衡的介绍 使用注解loadbalance&#xff0c;是一个客户端的负载均衡器&#xff1b;通过之前已经从注册中心拉取缓存到本地的服务列表中&#xff0c;获取服务进行轮询负载请求服务列表中的数据。 轮询原理 1.2 loadbalance工作流程 loadBalance工作…

-bash: ./1.sh: /bin/bash^M: bad interpreter: No such file or directory解决方法

1、执行脚本 ./1.sh时报如下错误 -bash: ./1.sh: /bin/bash^M: bad interpreter: No such file or directory 2、在Windows编辑的脚本导入Linux系统中&#xff0c;执行报错问题 yum install -y dos2unix 3、或者本地安装 rpm -ivh /mnt/Packages/dos...... 4、然…

opencv各个模块介绍(1)

Core 模块&#xff1a;核心模块&#xff0c;提供了基本的数据结构和功能。 常用的核心函数&#xff1a; cv::Mat&#xff1a;表示多维数组的数据结构&#xff0c;是OpenCV中最常用的类之一&#xff0c;用于存储图像数据和进行矩阵运算。 cv::Scalar&#xff1a;用于表示多通道…

Python综合实战案例-数据清洗分析

写在前面&#xff1a; 本次是根据前文讲解的爬虫、数据清洗、分析进行的一个纵隔讲解案例&#xff0c;也是对自己这段时间python爬虫、数据分析方向的一个总结。 本例设计一个豆瓣读书数据⽂件&#xff0c;book.xlsx⽂件保存的是爬取豆瓣⽹站得到的图书数据&#xff0c;共 6067…

瑞芯微RK3576|触觉智能:开启科技新篇章

更多产品详情可关注深圳触觉智能官网&#xff01; “瑞芯微&#xff0c;创新不止步&#xff01;”——全新芯片RK3576即将震撼登场。指引科技风潮&#xff0c;创造未来无限可能&#xff01;这款芯片在瑞芯微不断创新和突破的道路上&#xff0c;不仅是对过往成就的完美延续&…

填补市场空白,Apache TsFile 如何重新定义时序数据管理

欢迎全球开发者参与到 Apache TsFile 项目中。 刚刚过去的 2023 年&#xff0c;国产开源技术再次获得国际认可。 2023 年 11 月 15 日&#xff0c;经全球最大的开源软件基金会 ASF 董事会投票决议&#xff0c;时序数据文件格式 TsFile 正式通过&#xff0c;直接晋升为 Apache T…

基于傅里叶描述子的手势动作识别,Matlab实现

博主简介&#xff1a; 专注、专一于Matlab图像处理学习、交流&#xff0c;matlab图像代码代做/项目合作可以联系&#xff08;QQ:3249726188&#xff09; 个人主页&#xff1a;Matlab_ImagePro-CSDN博客 原则&#xff1a;代码均由本人编写完成&#xff0c;非中介&#xff0c;提供…

AI之Suno:Suno V3的简介、安装和使用方法、案例应用之详细攻略

AI之Suno&#xff1a;Suno V3的简介、安装和使用方法、案例应用之详细攻略 目录 Suno AI的简介 1、特点与改进&#xff1a; Suno AI的安装和使用方法 1、第一步&#xff0c;让国产大模型—ChatGLM4帮我写一个提示词 2、第二步&#xff0c;将提示词交给Suno v3&#xff0c;…

阿里云倚天服务器是什么?倚天服务器c8y、g8y和r8y详细介绍

阿里云倚天云服务器CPU采用倚天710处理器&#xff0c;租用倚天服务器c8y、g8y和r8y可以享受优惠价格&#xff0c;阿里云服务器网aliyunfuwuqi.com整理倚天云服务器详细介绍、倚天710处理器性能测评、CIPU架构优势、倚天服务器使用场景及生态支持&#xff1a; 阿里云倚天云服务…

FastAPI+React全栈开发02 什么是FARM技术栈

Chapter01 Web Development and the FARM Stack 02 What is the FARM stack and how does it fit together? FastAPIReact全栈开发02 什么是FARM技术栈 It is important to understand that stacks aren’t really special, they are just sets of technologies that cover…