二叉搜索树进阶之红黑树

前言:

在上文我们已经学习了AVL树的相关知识以及涉及的四种旋转的内容,但是AVL树追求平衡导致旋转操作过多,一些情况下影响性能,由此我们就来了解一下二叉搜索树的另外一个分支,红黑树。

(倘若对旋转知识不了解的可以先移步:http://t.csdnimg.cn/waigV)

红黑树的概念:

红黑树是一种二叉搜索树,通过对每个节点增加一个存储位表示节点的颜色,(红色或者黑色),再通过对任何一条从根到叶子的路径的各个节点的着色方式进行限制,从而保证没有一条路径会比其他路径长出两倍,从而确保诸多基本操作例如插入删除和查找的时间复杂度始终O(log⁡n)。

红黑树被广泛运用道许多计算机科学领域,比如C++的stl库的map与set容器的底层实现,java的TreeMap与TreeSet也采用了红黑树。

 红黑树的性质:

1. 每个结点不是红色就是黑色
2. 根节点是黑色的 
3. 如果一个节点是红色的,则它的两个孩子结点是黑色的 
4. 对于每个结点,从该结点到其所有后代叶结点的简单路径上,均 包含相同数目的黑色结点 
5. 每个叶子结点都是黑色的 ( 此处的叶子结点指的是空结点)
只要满足上面五种条件,就能保证没有一条路径会比其他路径长出两倍,确保了红黑树不会变得过于不平衡,从而保证了高效的操作。

红黑树的性质的平衡:

红黑树是否进行旋转主要是依据他的叔叔节点进行判断的,以红黑树的插入操作为例,当我们在叶子处插入新节点时,要把它的默认颜色设置为红色,然后对比他的父节点颜色是否为红,为红色就要进行一系列的检查,为黑,就不用进行检查。
通常我们面临的需要选择的情况是这样的:
cur为我们新插入的节点,此时他的父亲节点parent的颜色也为红,于是找到父亲的父亲节点pparent,随后判断parent是pparent的左节点还是右节点,随后就能找到叔叔节点uncle。重要的就来了,当此时叔叔节点也为红色时,我们就可以把parent与叔叔的颜色更改为黑色,随后把爷爷节点颜色改为红色。在这种情况下,我们就不用对红黑树进行任何旋转,但是由于我们更改了爷爷节点的颜色为红色,所以我们要继续对爷爷进点进行又一次的判断。
由此可见,cur的位置其实不一定为新插入的节点,也可能时一路调整上来的节点:

 

比如这张图来看,最底下的节点为新增,此时我们就要把a,b颜色更改为黑,把cur颜色更改为红,此时cur与parent的眼色都为红,违反了规则,所以要继续进行判断。
总之,当我们检查到叔叔节点的颜色为红色,跟父亲一样时,就不需要进行旋转,只需要更改颜色就行。
但是如果叔叔节点为黑色或者叔叔节点不存在时,单纯进行颜色的更改已经不能满足我们的红黑树的五大规则了,所以只能进行旋转了。

叔叔存在但是为黑色: 

此时只能对爷爷节点进行旋转,以图片的情况为例,就是对爷爷节点进行右单旋,然后交换爷爷节点与父亲节点的颜色就可以了。

这种情况自然也是进行左单旋。

那么什么时候进行双旋呢?

对于红黑树来说,当父亲节点时爷爷节点的左节点时,cur节点是父亲节点的右节点,就可以进行左右双旋操作。或者当父亲节点时爷爷节点的右节点,cur是父亲节点的左节点,就对爷爷节点进行右左双旋操作来保持红黑树的性质。 

红黑树的优缺点

优点

  • 红黑树的插入、删除和查找操作的时间复杂度始终为 O(log⁡n)O(\log n)O(logn),适合频繁插入和删除的动态数据集。
  • 红黑树能够保持相对较好的平衡,避免了极端情况下的退化。

缺点

  • 相对于 AVL 树,红黑树的平衡程度稍差,这意味着查找操作的性能在某些情况下可能不如 AVL 树。
  • 实现红黑树比其他二叉搜索树(如普通的二叉搜索树或 AVL 树)要复杂得多。

结语

红黑树在计算机科学中有着广泛的应用,尤其是在需要频繁插入和删除操作的数据结构中。虽然其实现较为复杂,但红黑树通过严格的平衡规则和旋转操作,能够提供稳定、高效的性能表现,是一种非常重要的自平衡二叉搜索树。了解红黑树的基本性质和操作过程,对于深入理解高级数据结构以及其在实际应用中的优化是非常有帮助的。

希望本文对您有所帮助!!

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

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

相关文章

2024版Assimp配置教程

最近想看看图形学,选择速通LearnOpenGL,不出意外最耗时间的依然是配置环境。按照教程上的把GLFW等等配置的没有问题,但是在Assimp这里卡住了。原因是教程上说的不详细,而网上查的又和现在的版本相去甚远,导致捣鼓了好一…

从web.xml动态读取sunspringmvc.xml文件

文章目录 1.问题分析1.SunWebApplicationContext.java 中sunspringmvc.xml是写死的2.但是web.xml已经配置了init-param,所以应该是可以读取的 2.具体实现1.SunDispatcherServlet.java 得到ServletConfig传递给Spring容器完成初始化2.SunWebApplicationContext.java …

Python中的“for循环”:探索其无限潜力

引言 for循环是任何Python程序员工具箱中的必备技能之一。无论是在处理数据时需要遍历数组,还是在编写Web应用时循环处理请求,亦或是进行复杂的算法实现,for循环都能派上大用场。通过掌握for循环的不同用法,我们可以更高效地解决…

【C++从小白到大牛】C++的隐式和显示类型转换基础知识讲解

目录 1、C语言中的类型转换 2、C语言和C中可以相互转换的类型总结 C语言: CPP: 3. 为什么C需要四种类型转换 4、C四大强制类型转换 4.1static_cast 4.2 reinterpret_cast 4.3 const_cast 4.4dynamic_cast 注…

基于x86 平台opencv的图像采集和seetaface6的性别识别功能

目录 一、概述二、环境要求2.1 硬件环境2.2 软件环境三、开发流程3.1 编写测试3.2 配置资源文件3.3 验证功能一、概述 本文档是针对x86 平台opencv的图像采集和seetaface6的性别识别功能,opencv通过摄像头采集视频图像,将采集的视频图像送给seetaface6的性别识别模块从而实现…

JS将class转换为function

类定义与构造函数 在JavaScript中,类的定义可以通过class关键字来实现,也可以通过传统的构造函数和原型链的方式来实现。上述代码展示了这两种不同的实现方式。 使用class关键字 class Example {constructor(name) {this.name name;}func() {console…

谓词和量词

一、个体词和谓词 命题是一句陈述句,命题由个体词和谓词组成。 个体词是句子中的主语部分,比如这里的王童。 谓词是句子里的剩余部分,比如是一个三好学生 个体词用小写字母表示,谓词用大写字母+(&#…

Java核心API——io类缓冲流

在前面的学习中我们学习了如何向文件中简单的传输写入数据 java将流分为两类 节点流与处理流 节点流: 又称为低级流,特点:实际连接程序与另一端的"管道",负责实际读写数据的流. IO一定是建立在某个低级流的基础上进行的. 文件流就是低级流,它们是实际连接程序与…

数据库(专业存储数据)

数组、链表、变量----->内存:程序运行结束,数据丢失 文件-------------->硬盘 数据库:专业存储数据,大量数据----------->硬盘 一、数据库文件与普通文件区别: 1.普通文件对数据管理(增刪改查)效率低 2.数据库对数据…

算法: 双指针

题目:环形链表 题目讲解: 判断环 要判断链表是否有环,可以使用快慢指针的方法。快指针每次走两步,慢指针每次走一步。如果链表有环,快慢指针最终会相遇;如果没有环,快指针会先到达链表末尾。 …

11.舵机控制

jd就是cnt,分别对应着 0.5ms-------------0度; 1 1.0ms------------45度; 2 1.5ms------------90度; 3 2.0ms-----------135度; 4 2.5ms-----------180度; 5 并且软…

【PostgreSQL教程】PostgreSQL 高级篇之索引

博主介绍:✌全网粉丝20W+,CSDN博客专家、Java领域优质创作者,掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域✌ 技术范围:SpringBoot、SpringCloud、Vue、SSM、HTML、Nodejs、Python、MySQL、PostgreSQL、大数据、物联网、机器学习等设计与开发。 感兴趣的可…

java操作zookeeper

java操作zookeeper 文档 linux安装java -centos安装java -linux配置java环境变量zookeeper单机安装zookeeper集群安装zookeeper客户端命令行操作、节点类型及监听器zookeeper集群写数据原理java操作zookeeper 依赖信息 <dependency><groupId>junit</groupId…

MySQL:简述对事务的认识

浅谈对Spring事务的认识&#xff1a;https://xiaoer.blog.csdn.net/article/details/80849971 一、事务的特性 事务是数据库永恒不变的话题&#xff0c; ACID&#xff1a;原子性&#xff0c;一致性&#xff0c;隔离性&#xff0c;持久性。 &#xff08;1&#xff09;原子性&am…

基于麒麟信安操作系统的光伏发电功率预测系统完成大规模部署建设

麒麟信安操作系统&#xff0c;作为行业数智化建设的安全根基&#xff0c;为电力业务系统提供了稳定可靠的底层平台&#xff0c;在全球能源结构转型大潮中扮演着至关重要的角色。某光伏电站项目中&#xff0c;基于麒麟信安操作系统的光伏发电功率预测系统完成大规模部署建设&…

手机游玩植物大战僵尸杂交版V2.3.7最新版教程(文章末尾免费直接下载链接)

最新版植物大战僵尸杂交版V2.3.7手机游玩教程 【V2.3.7全面升级】植物大战僵尸杂交版&#xff1a;跨平台终极安装指南 - 苹果、安卓、电脑、电视兼容&#xff0c;界面革新&#xff0c;16卡槽扩展&#xff0c;高分辨率支持&#xff0c;BUG修复&#xff0c;畅享游戏乐趣 前言 …

C++实现的购物小程序

以下是一个详细的C实现的购物小程序。这段代码模拟了一个基础的购物车系统&#xff0c;用户可以通过交互式菜单与程序进行交互&#xff0c;执行各种购物相关的操作&#xff0c;如添加商品到购物车、查看购物车中的商品列表、计算购物车中的商品总价等。 购物小程序 问题描述 …

Java Web —— 第九天(事务)

事务管理 & AOP 事务回顾 概念 事务 是一组操作的集合&#xff0c;它是一个不可分割的工作单位&#xff0c;这些操作 要么同时成功&#xff0c;要么同时失败 操作 开启事务(一组操作开始前&#xff0c;开启事务): start transaction / begin 提交事务(这组操作全部成功…

ros2--jupyter

问题 import rclpy---报错 链接 strings /usr/lib32/libstdc.so.6 | grep GLIBCXX_3.4.30

python 打包exe

python打包&#xff1a; pyinstaller --onefile wc_main3.pypyi-makespec wc_main3.py 》pyi-makespec wc_main3.py Wrote /home/a/wc_main3.spec. Now run pyinstaller.py to build the executable.pyinstaller wc_main3.specFile "/home/a/anaconda3/envs/l/lib/pyt…