B-树(不是B减树)原理剖析(1)

目录

B树的主要特性:

B树的操作:

B树的优点:

为什么要发明出B-树?

B树的概念和原理剖析

原理图讲解(部分讲解在图中)

初始化结点:

处理数据数量计算(了解)

底层代码实现(加深理解)


前些日子我们学了AVl树,红黑树感受到了搜索树在底层和实际应用的广泛和其规则的复杂性,今天我们继续学习一下原理也是搜索树的B-树。

B树是一种自平衡的树数据结构,常用于实现数据库和文件系统的索引。它的设计目的是保持数据有序,并允许高效的插入、删除和搜索操作。B树的特点是它的节点可以包含多个子节点,而不是像二叉树那样每个节点只有两个子节点。这样可以减少树的高度,从而减少查找和更新操作的时间复杂度。

B树的主要特性:

  1. 有序性:B树中的所有节点按升序排列,这使得查找非常高效。每个节点包含一个键值的有序列表,以及指向其子节点的指针。

  2. 多子节点:与二叉树不同,B树中的每个节点可以有多个子节点。节点中的键值和子节点之间有一定的关系:子节点中的值总是介于父节点键值之间。

  3. 平衡性:B树是平衡树,它通过在插入和删除时重新分布节点的键值,确保树的所有叶节点都位于同一层级上。因此,查找的时间复杂度始终为 O(log n),其中 n 是树中的键值总数。

  4. 分支因子:B树的分支因子(通常称为阶数,order)决定了每个节点可以有多少个子节点。一个阶数为 mmm 的 B 树,意味着每个节点最多可以有 m−1m-1m−1 个键和 mmm 个子节点。

  5. 高效磁盘访问:由于每个节点可以存储多个键和指针,B树减少了对磁盘的访问次数。因此,B树在数据库管理系统和文件系统中广泛应用,特别适用于处理大量需要存储在外存(如硬盘)上的数据。

B树的操作:

  • 查找:查找操作从根节点开始,逐层深入,通过比较键值找到目标元素。每次查找时,最多需要访问树的高度层数,这使得查找效率较高。

  • 插入:插入时,首先通过查找找到应插入的位置,然后将新键值插入到合适的节点中。如果节点已满,节点会被拆分,部分键值上移到父节点中。

  • 删除:删除操作更为复杂,如果直接删除某节点会导致树失衡,因此可能需要将相邻节点的键值重新分配,或者将节点合并以保持树的平衡性。

B树的优点:

  • 高效的插入、删除、查找操作,特别是在处理大量数据时。
  • 保证树的高度始终较低,从而减少操作的复杂度。
  • 适用于外存系统的索引结构,因为它减少了对磁盘的访问次数。

常见的改进版本包括 B+(B加)树,它在叶节点中包含所有的数据,并使用顺序链表链接叶节点,从而提高了范围查询的效率。

为什么要发明出B-树?

其实B-树最初被发明出来是为了解决磁盘上读取数据普遍较慢的问题。B-树即使用于内查找也适用于外查找。

这里有人就有意见了呀,为什么别的数据结构不行,偏偏要选择B-呢?

首先,由于磁盘数据过多,假设需要查找磁盘里10亿个值,我们可以看到以上图不同的数据结构的时间复杂度可以看出,最优的就是哈希和平衡二叉树的那两个,AVl树比红黑树相对选择条件更严格,所以选择AVl树,那也需要logn次,也就是说10亿个数据就是30次可以查完,虽然已经很短了,但是磁盘的访问速度太慢了,30次还是显得太多了。

那使用哈希表行不行呢,虽然时间复杂度为o1,但是由于会产生负面的哈希冲突问题,所以比较难以处理多个数据重复映射到同一个位置,比较麻烦!!!

由于磁盘一般不存在空间不足的问题,所以即便使用位图和布隆过滤器也是没有用的。

下面有更清晰的解释可供参考:

所以最大的问题就是磁盘自己本身访问数据太慢了,需要将次数降至个位数才行,于是由于之前的搜索二叉树都是二叉的(一个根最多只有2个孩子节点),所以这里要想提高速率只能降低树的高度,增加根节点的孩子个数(变成多叉)。

就这样B树就诞生了!!!

B树的概念和原理剖析

1970年,R.Bayer和E.mccreight提出了一种适合外查找的树,它是一种平衡的多叉树,称为B树 (后面有一个B的改进版本B+树,然后有些地方的B树写的的是B-树,注意不要误读成"B减树")。一 棵m阶(m>2)的B树,是一棵平衡的M路平衡搜索树,可以是空树或者满足一下性质:

1. 根节点至少有两个孩子//为了增加叉数而设置的

2. 每个分支节点都包含k-1个关键字和k个孩子,其中 ceil(m/2) ≤ k ≤ m ceil是向上取整函数

3. 每个叶子节点都包含k-1个关键字,其中 ceil(m/2) ≤ k ≤ m

4. 所有的叶子节点都在同一层

5. 每个节点中的关键字从小到大排列,节点当中k-1个元素正好是k个孩子包含的元素的值域划 分 6. 每个结点的结构为:(n,A0,K1,A1,K2,A2,… ,Kn,An)其中,Ki(1≤i≤n)为关键 字,且Ki。Ai(0≤i≤n)为指向子树根结点的指针。且Ai所指子树所有结点中的 关键字均小于Ki+1。 n为结点中关键字的个数,满足ceil(m/2)-1≤n≤m-1。

解析开始:我们可以看到这个B树的规则还是比较复杂的。先理清楚几个概念

关键字:就是每一层的节点个数(相当于根)

孩子:就是每个关键字所引出的节点(相当于根的子节点)

2,和3规则可以看出B树是多叉搜索树,如果阶数m为10,那关键字最少为4,最多为9,孩子最少为5,最多为10,并且可以看出,每层的关键字的个数总比其孩子节点少1,说明有一个孩子必定同时是两个相邻的关键字的孩子

第5条规则体现了其仍为搜索树,需要按从大到小排列关键字才可以在后面分裂后通过取中位数的方式取到新的关键字(根)

说到分裂,由于规则3每个叶子节点都包含k-1个关键字,其中 ceil(m/2) ≤ k ≤ m,所以每行的关键字个数最多为阶数-1,当插入的关键字的个数等于阶数m时,就需要进行分裂,分裂具体是怎么样的后面会体现。

原理图讲解(部分讲解在图中)

由于我们这边设的阶数为m = 3,但是我们必须给每行的关键字m个空间,因为如果只给2个(对于m ==3来说,每行关键字最多为2)就无法判断是否关键字等于m,是否需要分裂,因为第3个数无法插入了,多开一个空间方便判断,磁盘很大的不差那一个空间!

刚开始插入时,由于还没有明显的头结点,需要通过不断插入关键字来完成第一次分裂产生,这也比较符合先利用已经开辟好的空间的逻辑

当第一次分裂完成后会产生一个新的单个头节点,之后我们在插入节点的时候必须从叶子节点开始插入,这样才不会剖坏之前已经插入的节点的位置,因为B树仍然是搜索树。从上图也证明了一个结点可能会成为两个根的孩子的理论,所以B树中根节点的个数不是其孩子的两倍,因为根据图可以看出有些孩子被重复利用了,且根节点是通过子节点分裂产生的

分裂引起的根的移动,需要连同着其孩子节点一起移动。种种异样表明B树的设计完全是为了插入数据的方便,不是为了保持平衡而设计的,所以和其他的搜索树不太一样。

这里关键是画图出来,一下展示我画的图:

初始化结点:

根据规则6和演示图解就可以很轻松的得出,每个结点的构造。

由于每个结点是有可能形成多叉的,且一个结点可能会成为两个根的孩子,所以一个结点会先有一个存放关键字的数组,然后为了访问其孩子,还需要一个存有指向此根的全部孩子的指针数组(这里不是单纯的左右指针那么简单了,因为孩子有点多),另外根据上图还需要一个变量n统计关键字的个数(就是当层的结点数),由于我们之前的搜索树都还有一个指向其父亲结点的指针,所以这里也可以考虑加入。

struct BTreeNode
{
    //K _keys[M - 1];
    //BTreeNode<K, M>* _subs[M];

    // 为了方便插入以后再分裂,多给一个空间
    K _keys[M];//关键字(本行节点)
    BTreeNode<K, M>* _subs[M+1];//子节点(快速连串访问,体现树结构)
    BTreeNode<K, M>* _parent;//父亲节点,体现原本三叉链的本质结构
    size_t _n; // 记录实际存储多个关键字 

};

处理数据数量计算(了解)

实际情况运用B树时,阶层通常会很大(B树阶层越大处理的节点数(关键字)就越多数据量就越大),所以我们以下定义形成一个1023阶层的4层的B树。

根据规则,那么每个分支的关键字数最多就为m - 1 = 1023,其孩子为m等于1024,根据下图的逐层推算可以得出每行的关键字和孩子节点的个数。可以看出B树成功的通过压缩了高度同时存储了更多的数据

底层代码实现(加深理解)

欲知后事如何,请听下文分解!!!持续关注博主以解锁B树更多秘密!!!

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

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

相关文章

MySQL InnoDB undo log生成逻辑分析

引用《InnoDB存储引擎》中有一句话&#xff0c;特别重要&#xff1a; 用户通常对undo有这样的误解&#xff1a;undo用于将数据库物理地恢复到执行语句或事务之前的样子---但事实并非如此。 undo是逻辑日志&#xff0c;因此只是将数据库逻辑地恢复到原来的样子。所有的修改都被…

通信工程学习:什么是NFV网络功能虚拟化

NFV&#xff1a;网络功能虚拟化 NFV&#xff08;Network Function Virtualization&#xff09;&#xff0c;即网络功能虚拟化&#xff0c;是一种通过虚拟化技术实现网络功能的技术手段。它借鉴了x86服务器的架构&#xff0c;将传统的网络硬件设备如路由器、交换机、防火墙、负载…

neo4j:ubuntu环境下的安装与使用

一、neo4j安装 1. 下载安装包 进入网站&#xff1a;https://neo4j.com/deployment-center/#community 在上图中选择下载即可&#xff08;社区版免费&#xff09; 注意&#xff1a;neo4j的版本要和电脑安装的jdk版本对应&#xff0c;jdk版本使用java --version查看&#xff1a;…

华为认证HCIA篇--网络通信基础

大家好呀&#xff01;我是reload。今天来带大家学习一下华为认证ia篇的网络通信基础部分&#xff0c;偏重一些基础的认识和概念性的东西。如果对网络通信熟悉的小伙伴可以选择跳过&#xff0c;如果是新手或小白的话建议还是看一看&#xff0c;先有个印象&#xff0c;好为后续的…

复制他人 CSDN 文章到自己的博客

文章目录 0.前言步骤 0.前言 在复制别人文章发布时&#xff0c;记得表明转载哦 步骤 在需要复制的csdn 文章页面&#xff0c;打开浏览器开发者工具&#xff08;F12&#xff09;Ctrl F 查找"article_content"标签头 右键“Copy”->“Copy element”新建一个 tx…

【Godot4自学手册】第四十八节创建雨粒子效果

今天我们要利用GPU粒子节点玩雨粒子效果&#xff0c;下雨天。 一、添加GPU粒子系统 添加GPUParticles2D节点。选择根节点&#xff0c;单击添加按钮&#xff0c;选择GPUParticles2D&#xff0c;完成添加。 二、修改属性 1.设置粒子数量。 在GPUParticles2D检查器中将Amount设…

速记篇 |TCP/IP五层模型怎么背,OSI七层模型怎么背?

背景 记忆TCP/IP五层模型和OSI七层模型可以通过理解每一层的功能、作用以及它们之间的逻辑关系来进行。下面分别给出这两个模型的记忆方法和要点&#xff1a; TCP/IP五层模型 TCP/IP五层模型是一个简化的模型&#xff0c;从下到上依次为&#xff1a; 1.物理层&#xff08;Physi…

计算机毕业设计之:云中e百货微信小程序设计与实现(源码+文档+定制)

博主介绍&#xff1a; ✌我是阿龙&#xff0c;一名专注于Java技术领域的程序员&#xff0c;全网拥有10W粉丝。作为CSDN特邀作者、博客专家、新星计划导师&#xff0c;我在计算机毕业设计开发方面积累了丰富的经验。同时&#xff0c;我也是掘金、华为云、阿里云、InfoQ等平台…

微信小程序转化为uni-app项目

前言&#xff1a; 之前自己做一个uni-app的项目的时候前端需要实现一个比较复杂的动态tab和swiper切换的功能&#xff0c;但是由于自己前端抠脚的原因没有写出来&#xff0c;然后自己在网上搜索的时候发现了有个微信小程序里面的页面及极其的符合我的需求。那么问题来了我该如何…

『功能项目』QFrameWork拾取道具UGUI【69】

本章项目成果展示 我们打开上一篇68QFrameWork扔到地上UGUI的项目&#xff0c; 本章要做的事情是实现当物品在地上时&#xff0c;点击物品将对应物品转移到道具栏中 制作一个提示UI界面 添加Button组件设置为点击即将父物体隐藏 拖拽到文件夹中在场景中删除 创建脚本&#xf…

springboot实战学习(9)(配置mybatis“驼峰命名“和“下划线命名“自动转换)(postman接口测试统一添加请求头)(获取用户详细信息接口)

接着学习。之前的博客的进度&#xff1a;完成用户模块的注册接口的开发以及注册时的参数合法性校验、也基本完成用户模块的登录接口的主逻辑的基础上、JWT令牌"的组成与使用以及完成了"登录认证"&#xff08;生成与验证JWT令牌&#xff09;具体往回看了解的链接…

python虚拟环境创建使用

环境变量中配置 vi /etc/profile 注意安装完python环境之后要添加以下代码&#xff0c;配置虚拟环境的命令才能正确使用&#xff1a; PATH$PATH:/usr/local/python3 PATH$PATH:/usr/local/python3/bin 创建&#xff1a;virtualenv venv 激活虚拟环境&#xff1a;source ./v…

从预测性维护到智能物流:ARM边缘计算控制器的工业实践

工业4.0时代的到来&#xff0c;边缘计算技术成为连接物理世界与数字世界的桥梁。ARM架构的边缘计算控制器凭借其低功耗、高能效和灵活性等特点&#xff0c;在工业自动化领域展现出巨大潜力。本文将通过几个实际应用案例来探讨ARM边缘计算控制器是如何提升生产线效率和安全性的&…

【数据结构之线性表】有序表的合并(链表篇)

链表有序表的合并 思路图 将链表L1和L2按照顺序合并到L3中&#xff08;注&#xff1a;三个链表都是带头结点的&#xff09; A、要实现有序合并&#xff0c;必须先比较L1,L2两表中结点的大小&#xff0c;这里我们暂时先不讨论&#xff0c;直接根据图中来进行思路整理&#xff…

plt常用函数介绍二

目录 fig.add_subplot()ax.set()plt.legend()plt.subplots_adjust()plt.suptitle()plt.grid() fig.add_subplot() fig.add_subplot() 是 Matplotlib 中 Figure 对象的方法&#xff0c;用于在图形中添加子图&#xff08;subplot&#xff09;。 其语法为&#xff1a; subplot(…

linux网络编程8

24.9.25学习目录 一.原始套接字&#xff08;续&#xff09;1.sendto发送数据原始套接字1.ARP 二.Web编程1.概述2.HTML 一.原始套接字&#xff08;续&#xff09; 混杂模式&#xff1a; 指一台机器的网卡能够接受所有经过它的数据包&#xff0c;不论其目的地址是否是它&#xf…

程序人生:软件测试 非技术性面试题【建议每个测试人观看】

1、自我介绍&#xff1a;三分钟左右 2、为什么从郑州/太原离职&#xff1f; 3、你的职业规划是什么样的&#xff1f; 4、对下一家公司有什么自己的想法吗&#xff1f; 5、你觉得作为一名测试工程师&#xff0c;应该具备什么样的素养&#xff1f; 6、你觉得管理层&#xff…

echart实现渐变色-vue2

let selectData5 [{name: "有功电量",type: "bar",data: data.data.historyKwhList,unit: "MW",itemStyle: {// 使用渐变色color: {type: "linear",x: 0,y: 0,x2: 0,y2: 1,colorStops: [{offset: 0,color: "#04C886",},{of…

市面第一款 C++ 版本的U盘装机软件(即将上线)

市面大部分U盘装机软件&#xff0c;都是采用Au3脚本开发&#xff0c;而且有各种捆绑&#xff0c;闲来无聊&#xff0c;采用Qt C制作一款CU盘装机软件&#xff0c;从此告别Au3脚本&#xff0c;各种炫酷界面随便换&#xff0c;敬请期待 另外两个界面暂时不公布&#xff0c;防止Au…

C/C++语言基础--C++类数据、静态与非静态、常成员、友员、成员变量与函数指针等相关知识点

本专栏目的 更新C/C的基础语法&#xff0c;包括C的一些新特性 前言 通过前面几节&#xff0c;我们介绍了C的类与对象、构造与析构函数、拷贝等相关知识&#xff0c;这一篇将详细介绍了C的成员变量相关的知识点与扩展C语言后面也会继续更新知识点&#xff0c;如内联汇编&#…