平衡二叉树、红黑树、B树、B+树

Tree

  • 1、前言
  • 2、平衡二叉树和红黑树
  • 3、B树和B+树
    • 3.1、B树的构建
    • 3.2、B树和B+树的区别
    • 3.3、数据的存储方式

1、前言

本文侧重在理论方面对平衡二叉树、红黑树、B树和B+树的各方面性能进行比较。不涉及编程方面的实现。而关于于平衡二叉树在C++中的实现,我的上一篇文章平衡二叉树(AVLTree)有所介绍。

2、平衡二叉树和红黑树

平衡二叉树又称平衡二叉搜索树,由于是Adelson-Velsky and Landis二人发明的,所以又叫AVL树。平衡二叉树要求左右子树的高度差不能大于一。所以极限条件下,搜索的时间复杂度是O(logn)。但由于其调整起来十分麻烦,所以并不适用于经常需要进行插入和删除的环境。因此引入红黑树(也是二叉搜索树的一种)来解决这一问题。
红黑树,顾名思义是有红黑两种节点。然而对于红黑树的构成却有许多限制,我们先来看看这些限制。

  • 1、根节点必须是黑色的。
  • 2、不能有两个红节点构成亲子关系,即不能有两个连在一起的红节点。
  • 3、从任意节点到叶子节点的所有路径都包含相同数目的黑节点。
  • 4、所有叶子节点都是黑色的,这里的叶子节点指的是最末端的虚拟节点(NULL节点)。个人觉得,设置这些虚拟节点,是为了使限制3不失一般性。

通过以上四点设置便可以限制左右子树的高度差在一倍之内。我们不妨设一种极限情况,从根节点出来的左路径全是黑节点,右路径全是红黑交叉的节点。那么由于红节点不能两两相连,且右路径的黑节点数必须和做路径相同,所以右路径的节点是顶多是左路径的两倍。
在这里插入图片描述
如果把所有红色节点擦除,那么N个黑色节点所构成的必然是一颗平衡二叉树,搜索时的时间复杂度是logn。那么加上所有红色节点,由于极限情况下,最长路径是纯黑色节点的两倍。故而搜索时间复杂度是2logn,忽略常数项,那么复杂度还是O(logn)。
此外,基于红黑树的限制条件,在插入一个新的节点之后,红黑树的调整次数通常较少,大多数情况下不超过三次旋转。这是因为红黑树的设计允许它在维持平衡的同时允许某种程度的不完全平衡,因此调整的复杂性和频率通常低于AVL树。
至于如何插入节点,仅作了解吧。
首先,除了根节点之外,任何新增的节点都先被视为红节点,然后再进行以下判定。请添加图片描述
这里的左旋右旋具体时如何操作的,和平衡二叉树那里基本差不多,所以不赘述了。
由于红黑树在搜索中,时间复杂度是O(logn),且插入节点所需的调整的频率也低于AVL树,所以应用比较广泛。如C++中map和set这两种容器的底层就是红黑树。
以map为例,在C++中,map和python的字典很想,其第一个元素被视为key,第二个元素被视为value。而key是不允许修改和重复的,存储key的数据结构正式红黑树。这也保证了map在搜索时,时间复杂度为O(logn)。

using namespace std;map<int, int> myMap;
myMap[0] = 5;
myMap[1] = 7;

当然map也允许key是字符串类型,但即使是字符串类型,其还是会以红黑树的方式进行存储。只不过不再此时要按照字典顺序进行排序。

map<string, int> myMap1;
map<string, string>	myMap2;

3、B树和B+树

B树和B+树都是被广泛应用的数据结构。它们最显著的特征便是每一个节点可以存放多个数据,且可以有N个子树。下图是B树的示意图。
在这里插入图片描述
在构建一棵B树的时候,需要预先定义它的阶数m,限制一个节点至多存放m-1个值,并且也表明一个节点至多可以有m个子树。故而B树也可以被叫做m叉树。
一颗m叉树的每一个节点大概长这样。
在这里插入图片描述
n表示这个节点存放n个数据,k1,k2,…,kn-1是这个节点存放的数据,这些数据从小到达依次排序。p0,p2,…,pn是指向子树的指针。其中p0所指的子树的值全部在0和k1之间,p1所指子树的值全部在k1和k2之间,以此类推。

3.1、B树的构建

为了方便演示,我所展示的一个B树是一棵三叉树,即m=3。然后我依次插入1,3,5,2。流程图如下,当我们插入的数大于3个数的时候,变会取中间的值变成一个新的节点。当然我应该再演示一下它有三个子树的情况,但已经懒得画了。。。
在这里插入图片描述
总之B树的构建大抵如此。
其实B树更像是在2叉树和单链表之间妥协的产物。因为在每一个节点上进行搜索,其实就相当于在链表上进行搜索,所以当m取很大的时候,其搜索时间复杂度就接近一个链表了。当然由于其是一个有序的链表,我们在节点上也可以进行二分查找以降低复杂度。总而言之,m的取值是两种数据结构的权衡,故而也很重要。

3.2、B树和B+树的区别

顾明思意B+树事B树的升级版,克服了B树的许多缺点,有更高的搜索效率。但它们之间的较量关乎内存和磁盘,我放在最后讲。先来看看B树和B+树在构成上的区别。

  • 1、B+树的每一个子节点都会存储父节点的key,这里的key就是图中节点的值。
  • 2、B+树的所有叶子节点(末端的那些节点)通过指针串在一起。因而B+树除了随机搜索的方式(从根节点开始搜索),还多了一种顺序搜索方式(直接从叶子节点开始按顺序搜索)。

在这里插入图片描述
以上两点就是B树和B+树从观感上比较明显的差别。但其核心差距还是在存储方式上。

3.3、数据的存储方式

前文反复提到了B树和B+树节点中存放的数字是一个key,key有钥匙的含义。之所以这样叫,是因为key是访问另一个信息的钥匙。以B树为例,很多时候,节点中的key存放的看似是一个数字,其实是一个段文本信息的代表。而如果希望这些文本信息不至于在程序结束的时候随着程序而丢失,我们就需要将其放入磁盘当中。
在这里插入图片描述
这就涉及到一些操作系统的知识。我们在运行一个程序的时候,实际上是在RAM(Random Access Memory)上开辟一块区域,此时如果需要读取看到磁盘中的内容,就需要通过I/O操作以block为单位去把磁盘中的内容加载进RAM中。这里的block是数据读取的最小单位。在B树中,一般一个节点的数据,包括key,key指向的文本信息,指针等都放在同一个block中。这样block存储的key就不会很多,那么搜索一个信息的时候就不得不读取很多个block,进行很多次I/O操作。而I/O操作时非常费时的。
在这里插入图片描述
为了解决这个问题,B+树在非叶子节点(末端节点)上,只存放key,而把各个节点key对应的文本信息都存放到最后一个叶子节点上。通过这样的操作,每个block,即每个非叶子节点能存放的key就大大增多。当我们搜索一个信息的时候,需要经过的节点就减少了,从而I/O操作的频率也随之降低,进而提高了搜索效率。这便是B树和B+树的核心区别。

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

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

相关文章

Vue Router基础知识整理

Vue Router基础知识整理 1. 安装与使用&#xff08;Vue3&#xff09;安装使用 2. 配置路径别名和VSCode路径提示&#xff08;了解&#xff09;3. 使用查询字符串或路径传参query动态路由 与 params 4. router-link、定义别名、定义路由名称、编程式导航定义别名 aliasrouter-li…

李沐66_使用注意力机制的seq2seq——自学笔记

加入注意力 1.编码器对每次词的输出作为key和value 2.解码器RNN对上一个词的输出是query 3.注意力的输出和下一个词的词嵌入合并进入RNN 一个带有Bahdanau注意力的循环神经网络编码器-解码器模型 总结 1.seq2seq通过隐状态在编码器和解码器中传递信息 2.注意力机制可以根…

ELK技术介绍:背景、功能及应用场景全面解析

一、ELK概述 ELK是由Elasticsearch、Logstash和Kibana三个开源软件组成的日志管理解决方案&#xff0c;这一组合在近年来得到了广泛的关注和应用。ELK的出现&#xff0c;源于大数据和云计算技术的快速发展&#xff0c;以及对高效日志管理的迫切需求。 随着企业信息化程度…

【10-10-10旁观思维】项目管理必会的思维分析工具 08(送模板~)

&#x1f468;‍&#x1f4bb;&#x1f469;‍&#x1f4bb;面对一个决策或选择&#xff0c;当你犹豫不决时&#xff0c;可以想一下 ⏰10分钟后&#xff0c;自己是怎么看待自己现在的决策&#xff0c;依然保持一致亦或会后悔&#xff1b; ⏰10个月后&#xff0c;你又会如何思…

Javascript 插值搜索与二分搜索

插值搜索和二分搜索都是在有序数组中查找目标元素的算法。它们之间的核心区别在于确定中间元素的方式。 1、二分搜索&#xff08;Binary Search&#xff09;&#xff1a;二分搜索是一种通过将目标值与数组中间元素进行比较&#xff0c;然后根据比较结果缩小搜索范围的算…

Docker资源管理-数据管理

一、CPU 资源控制&#xff1a; 1.cgroups&#xff1a; cgroups&#xff0c;是一个非常强大的linux内核工具&#xff0c;他不仅可以限制被 namespace 隔离起来的资源&#xff0c; 还可以为资源设置权重、计算使用量、操控进程启停等等。 所以 cgroups&#xff08;Control grou…

深度剖析SSD掉电保护机制-1

随着固态硬盘&#xff08;Solid State Drives, SSD&#xff09;在数据中心、企业存储、个人计算设备等领域广泛应用&#xff0c;其数据安全性与可靠性成为至关重要的考量因素。其中&#xff0c;应对突发电源故障导致的数据丢失风险的掉电保护&#xff08;Power Loss Protection…

MA-Chitosan MA甲基丙烯酸修饰羧甲基壳聚糖 MA-Chitosan

MA-Chitosan MA甲基丙烯酸修饰羧甲基壳聚糖 MA-Chitosan、 【中文名称】甲基丙烯酸化羧甲基壳聚糖 【英文名称】Chitosan-MA 【结 构】 【纯 度】95%以上 【保 存】-20℃ 【规 格】10mg,500mg,1g,5g,10g 【产品特性】 Chitosan-MA&#xff08;壳聚糖-甲基丙烯酸…

Verilog基础语法——parameter、localparam与`define

Verilog基础语法——parameter、localparam与define 写在前面一、localparam二、parameter三、define写在最后 写在前面 在使用Verilog编写RTL代码时&#xff0c;如果需要定义一个常量&#xff0c;可以使用define、parameter和localparam三种进行定义与赋值。 一、localparam …

大模型都在用的:旋转位置编码

写在前面 这篇文章提到了绝对位置编码和相对位置编码&#xff0c;但是他们都有局限性&#xff0c;比如绝对位置编码不能直接表征token的相对位置关系&#xff1b;相对位置编码过于复杂&#xff0c;影响效率。于是诞生了一种用绝对位置编码的方式实现相对位置编码的编码方式——…

机器学习day1

一、人工智能三大概念 人工智能三大概念 人工智能&#xff08;AI&#xff09;、机器学习&#xff08;ML&#xff09;和深度学习&#xff08;DL&#xff09; 人工智能&#xff1a;人工智能是研究计算代理的合成和分析的领域。人工智能是使用计算机来模拟&#xff0c;而不是人类…

关于Android中的限定符

很多对于Android不了解或是刚接触Android的初学者来说&#xff0c;对于Android开发中出现的例如layout-large或者drawable-xxhdpi这样的文件夹赶到困惑&#xff0c;这这文件夹到底有什么用&#xff1f;什么时候用&#xff1f;这里简单的说一下。 其实&#xff0c;在上面例子中&…

基于OpenCV的人脸签到系统

效果图 目录文件 camerathread.h 功能实现全写在.h里了 class CameraThread : public QThread {Q_OBJECT public:CameraThread(){//打开序号为0的摄像头m_cap.open(0);if (!m_cap.isOpened()) {qDebug() << "Error: Cannot open camera";}//判断是否有文件,人脸…

iframe实现pdf预览,并使用pdf.js修改内嵌标题,解决乱码问题

项目中遇到文件预览功能,并且需要可以打印文件.下插件对于内网来说有点麻烦,正好iframe预览比较简单,且自带下载打印等功能按钮. 问题在于左上方的文件名乱码,网上找了一圈没有看到解决的,要么就是要收费要会员(ztmgs),要么直接说这东西改不了. 使用: 1.引入 PDF.js 库&…

Spring Boot集成Redisson实现延迟队列

项目场景&#xff1a; 在电商、支付等领域&#xff0c;往往会有这样的场景&#xff0c;用户下单后放弃支付了&#xff0c;那这笔订单会在指定的时间段后进行关闭操作&#xff0c;细心的你一定发现了像某宝、某东都有这样的逻辑&#xff0c;而且时间很准确&#xff0c;误差在1s内…

与AI对话:探索最佳国内可用的ChatGPT网站

与AI对话&#xff1a;探索最佳国内可用的ChatGPT网站 &#x1f310; 链接&#xff1a; GPTGod 点击可注册 &#x1f3f7;️ 标签&#xff1a; GPT-4 支持API 支持绘图 Claude &#x1f4dd; 简介&#xff1a;GPTGod 是一个功能全面的平台&#xff0c;提供GPT-4的强大功能&…

JavaEE——Spring Boot + jwt

目录 什么是Spring Boot jwt&#xff1f; 如何实现Spring Boot jwt&#xff1a; 1. 添加依赖 2、创建JWT工具类 3. 定义认证逻辑 4. 添加过滤器 5、 http请求测试 什么是Spring Boot jwt&#xff1f; Spring Boot和JWT&#xff08;JSON Web Token&#xff09;是一对常…

苍穹外卖学习

并不包含全部视频内容&#xff0c;大部分都按照操作文档来手搓代码&#xff0c;资料&#xff0c;代码都上传git。 〇、实际代码 0.1 Result封装 package com.sky.result;import lombok.Data;import java.io.Serializable;/*** 后端统一返回结果* param <T>*/ Data pub…

软考 系统架构设计师系列知识点之软件可靠性基础知识(5)

接前一篇文章&#xff1a;软考 系统架构设计师系列知识点之软件可靠性基础知识&#xff08;4&#xff09; 所属章节&#xff1a; 第9章. 软件可靠性基础知识 第1节 软件可靠性基本概念 9.1.3 可靠性目标 前文定量分析软件的可靠性时&#xff0c;使用失效强度来表示软件缺陷对…

20232937文兆宇 2023-2024-2 《网络攻防实践》实践七报告

20232937文兆宇 2023-2024-2 《网络攻防实践》实践七报告 1.实践内容 &#xff08;1&#xff09;使用Metasploit进行Linux远程渗透攻击 任务&#xff1a;使用Metasploit渗透测试软件&#xff0c;攻击Linux靶机上的Samba服务Usermap_script安全漏洞&#xff0c;获取目标Linux…