数据结构 —— B树

article/2025/9/9 4:41:02

文章目录

    • 1、B树的定义
        • 1.1、B树的特性
        • 1.2、B树的高度
        • 1.3、性能分析
        • 1.4、B树的补充说明
        • 1.5 、B树、B-树 、B-tree、B tree的区别
    • 2、B树的插入操作
        • 以5阶B树为例,介绍B树的插入操作,
    • 3、 B树的删除操作
        • 以5阶B树为例,介绍B树的删除操作
    • 4、B树相关的文章

1、B树的定义

B-tree 即 B树,B 即 Balanced,平衡的意思。

B树 是一颗多路平衡查找树。
在这里插入图片描述

B 树又叫平衡多路查找树。一棵m阶的B 树 (m叉树)的特性如下:

  1. 根节点至少有两个孩子 。
  2. 每个非根节点至少有M/2(上取整)个孩子,至多有M个孩子。
  3. 每个叶子节点 至少有 M/2-1(上取整)个关键字,至多有 M-1 个关键字。并以升序排列。(注:叶子节点是没有孩子)
  4. key[i] 和 key[i+1] 之间的孩子节点的值介于 key[i] 和 key[i+1] 之间。
  5. 所有的叶子节点都在同一层。

1.1、B树的特性

一棵m阶B树(m>=3),或是空树,或是具有如下几个特征的树:

  1. 如果是根结点,则 2 <= 根结点的孩子数 <= m;(根结点至少包含一个关键字)。
  2. 非叶子节点(除根结点和叶子结点外),ceil(m/2) <= 其包含的孩子数 <= m,其包含的关键字数 = 它的孩子数-1。【注:ceil(x):向上取整】
  3. 所有叶子结点都出现在同一层,ceil(m/2)-1 <= 结点包含的 关键字数 <= m - 1;
  4. 每个结点中的 关键字 从小到大排列,并且非叶子结点的k-1个 关键字 ,正好是它k个孩子包含的关键字的值域分划。
    【即:父结点中的第i个关键字(如果存在) < 第i个孩子中的所有关键字 < 父结点中的第i+1个关键字(如果存在)】

1.2、B树的高度

对于一个m(m>=3)阶B树,假设关键字总数目为n,高度为h:

  1. 根结点至少有2个孩子(根结点至少有一个关键字),因此第二层至少有两个结点;
  2. 除根和叶子结点外,其他结点至少有t=ceil(m/2)个孩子(取最小时,除根结点外,其他结点包含的关键字个数为t-1)。因此,第三层至少有2t个结点(第二层每个结点包含的关键字个数为t-1),第四层至少有 2t^2 个结点(第三层每个结点包含的关键字个数为t-1),……,第h-1层至少有2t^(h-3)个结点(第h-2层每个结点包含的关键字个数为t-1);
  3. 将所有结点包含的关键字相加:

在这里插入图片描述

由此可知:

  1. 在B树上增删改查的磁盘IO次数为为O(logtn),CPU时间为O(mlogtn)。
  2. 在关键字总数目不变的情况下,结点包含的关键字越多,B树的高度越小。这也是为什么SQL Server中应尽量以窄键建立聚集索引。因为键越小,结点可容纳的关键字越多,B树的高度越小,从而提升了查询性能。

1.3、性能分析

  1. n个关键字的平衡二叉排序的高度(lgn)比B树的高度约大lgt倍。

  2. 若作为在内存中使用的表结构,B树不一定比平衡二叉树好,尤其当m较大时更是如此。
    这是因为B树增删改查的CPU时间:O(mlogtn)=0(lgn·(m/lgt))

    而m/lgt>1,因此当m较大时,O(mlogtn)比平衡二叉排序树的CPU时间O(lgn)大得多。故,若B树仅作为在内存中使用,则应取较小的m。(通常取最小值m=3,此时B树每个内部结点孩子数目可为2或3,这种3阶的B-树称为2-3树)。

1.4、B树的补充说明

  1. B树的 阶数 是指 树中 的 最多子节点个数。比如,2-3树的阶是3,2-3-4树的阶是4;
  2. B-树的搜索,从根结点开始,对结点内的关键字(有序)序列进行二分查找,如果命中则结束,否则进入查询关键字所属范围的儿子结点;重复,直到所对应的儿子指针为空,或已经是叶子结点;
  3. 关键字集合分布在整棵树中, 即叶子节点和非叶子节点都存放数据;
  4. 搜索有可能在非叶子结点结束;
  5. 其搜索性能等价于在关键字全集内做一次二分查找;

在这里插入图片描述

上图是一颗阶数为4的B树。

在实际应用中的B树的阶数m都非常大(通常大于100),所以即使存储大量的数据,B树的高度仍然比较小。每个结点中存储了关键字(key)和关键字对应的数据(data),以及孩子结点的指针。

我们将一个key和其对应的data称为一个记录但为了方便描述,除非特别说明,后续文中就用key来代替(key, value)键值对这个整体。在数据库中我们将B树(和B+树)作为索引结构,可以加快查询速速,此时B树中的key就表示键,而data表示了这个键对应的条目在硬盘上的逻辑地址。

1.5 、B树、B-树 、B-tree、B tree的区别

  1. B树B树 的原英文名称为 B-tree

  2. B-树:国内很多人喜欢把 B-tree 译作 B-树 。其实,这是个非常不好的直译,很容易让人产生误解。 初学者可能误认为 B-树 是一种树,而 B树 又是另一种树。 而事实上是 它们都是指的同一种 “树” 。

  3. B tree : 就是 B树

总结: B树 == B-树 == B-tree == B tree

2、B树的插入操作

插入操作是指插入一条记录,即(key, value)的键值对。如果B树中已存在需要插入的键值对,则用需要插入的value替换旧的value。若B树不存在这个key,则一定是在叶子结点中进行插入操作。

1)根据要插入的key的值,找到叶子结点并插入。

2)判断当前结点key的个数是否小于等于m-1,若满足则结束,否则进行第3步。

3)以结点中间的key为中心分裂成左右两部分,然后将这个中间的key插入到父结点中,这个key的左子树指向分裂后的左半部分,这个key的右子支指向分裂后的右半部分,然后将当前结点指向父结点,继续进行第3步。( 当阶数m为偶数时,需要分裂时就不存在排序恰好在中间的key,那么我们选择中间位置的前一个key或中间位置的后一个key为中心进行分裂即可。

以5阶B树为例,介绍B树的插入操作,

根B定义规则2( 至少有Math.ceil(m/2)-1个关键字 ),在5阶B树中,结点最多有4个key,最少有2个key。


a)在空树中插入39
在这里插入图片描述
此时根结点就一个key,此时根结点也是叶子结点


b)继续插入22、97、41

在这里插入图片描述
根结点此时有4个key


c)继续插入53

在这里插入图片描述

插入后超过了最大允许的关键字个数4,所以以key值为41为中心进行分裂,结果如下图所示,分裂后当前结点指针指向父结点,满足B树条件,插入操作结束。

当阶数m为偶数时,需要分裂时就不存在排序恰好在中间的key,那么我们选择中间位置的前一个key或中间位置的后一个key为中心进行分裂即可。

在这里插入图片描述


d)依次插入13、21、40,

在这里插入图片描述
同样会造成分裂,结果如下图所示。

在这里插入图片描述


e)依次插入30、27、 33 ;36、35、34; 24、29,

插入 30、27、 33

在这里插入图片描述


插入 36、35、34;

在这里插入图片描述

在这里插入图片描述


插入 24、29

结果如下图所示。

在这里插入图片描述


f)插入26

插入后的结果如下图所示。

在这里插入图片描述

当前结点需要以27为中心分裂,并向父结点进位27,然后当前结点指向父结点,结果如下图所示。

在这里插入图片描述

进位后导致当前结点(即根结点)也需要分裂,分裂的结果如下图所示。

在这里插入图片描述

分裂后当前结点指向新的根,此时无需调整。


g)最后再依次插入key为 17、28、31、32 的记录,

在这里插入图片描述

结果如下图所示:

在这里插入图片描述


在实现B树的代码中,为了使代码编写更加容易,我们可以将结点中存储记录的数组长度定义为m而非m-1,这样方便底层的结点由于分裂向上层插入一个记录时,上层有多余的位置存储这个记录。同时,每个结点还可以存储它的父结点的引用,这样就不必编写递归程序。

一般来说,对于确定的m和确定类型的记录,结点大小是固定的,无论它实际存储了多少个记录。但是分配固定结点大小的方法会存在浪费的情况,比如key为28,29所在的结点,还有2个key的位置没有使用,但是已经不可能继续在插入任何值了,因为这个结点的前序key是27,后继key是30,所有整数值都用完了。所以如果记录先按key的大小排好序,再插入到B树中,结点的使用率就会很低,最差情况下使用率仅为50%。

3、 B树的删除操作

删除操作是指,根据key删除记录,如果B树中的记录中不存对应key的记录,则删除失败。

1)如果当前需要删除的key位于非叶子结点上,则用后继key(这里的后继key均指后继记录的意思)覆盖要删除的key,然后在后继key所在的子支中删除该后继key。此时后继key一定位于叶子结点上,这个过程和二叉搜索树删除结点的方式类似。删除这个记录后执行第2步

2)该结点key个数大于等于Math.ceil(m/2)-1,结束删除操作,否则执行第3步。

3)如果兄弟结点key个数大于Math.ceil(m/2)-1,则父结点中的key下移到该结点,兄弟结点中的一个key上移,删除操作结束。

否则,将父结点中的key下移与当前结点及它的兄弟结点中的key合并,形成一个新的结点。原父结点中的key的两个孩子指针就变成了一个孩子指针,指向这个新结点。然后当前结点的指针指向父结点,重复上第2步。

有些结点它可能即有左兄弟,又有右兄弟,那么我们任意选择一个兄弟结点进行操作即可。

以5阶B树为例,介绍B树的删除操作

5阶B树中,结点最多有4个key,最少有2个key

a)原始状态
在这里插入图片描述

b)在上面的B树中删除21,删除后结点中的关键字个数仍然大于等2,所以删除结束。

在这里插入图片描述

c)在上述情况下接着删除27。从上图可知27位于非叶子结点中,所以用27的后继替换它。从图中可以看出,27的后继为28,我们用28替换27,然后在28(原27)的右孩子结点中删除28。删除后的结果如下图所示。
在这里插入图片描述

删除后发现,当前叶子结点的记录的个数小于2,而它的兄弟结点中有3个记录(当前结点还有一个右兄弟,选择右兄弟就会出现合并结点的情况,不论选哪一个都行,只是最后B树的形态会不一样而已),我们可以从兄弟结点中借取一个key。所以父结点中的28下移,兄弟结点中的26上移,删除结束。结果如下图所示。

在这里插入图片描述

d)在上述情况下接着32,结果如下图。
在这里插入图片描述

当删除后,当前结点中只key,而兄弟结点中也仅有2个key。所以只能让父结点中的30下移和这个两个孩子结点中的key合并,成为一个新的结点,当前结点的指针指向父结点。结果如下图所示。

在这里插入图片描述

当前结点key的个数满足条件,故删除结束。

e)上述情况下,我们接着删除key为40的记录,删除后结果如下图所示。

在这里插入图片描述

同理,当前结点的记录数小于2,兄弟结点中没有多余key,所以父结点中的key下移,和兄弟(这里我们选择左兄弟,选择右兄弟也可以)结点合并,合并后的指向当前结点的指针就指向了父结点。

在这里插入图片描述

同理,对于当前结点而言只能继续合并了,最后结果如下所示。
在这里插入图片描述

合并后结点当前结点满足条件,删除结束。

4、B树相关的文章

https://www.cnblogs.com/jing99/p/11736003.html

https://blog.csdn.net/kalikrick/article/details/27980007

https://blog.csdn.net/herry816/article/details/89525077

https://blog.csdn.net/jimo_lonely/article/details/82716142


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

相关文章

B树和B+树详解

B树、B树看这一篇就够了 [TOC](B树、B树看这一篇就够了) 引言B树什么是B树以及B树是怎么来的B树的基本性质B树的新增和删除B树的插入B树的删除 B树什么是B树以及为什么要有B树B树的基本性质B树的查找 B树与B树的比较B树的优势B树的优势两者的细节对比 B树与B树在实际代码中的应…

B-树(B树)详解

https://www.jianshu.com/p/7dedb7ebe033 具体讲解之前&#xff0c;有一点&#xff0c;再次强调下&#xff1a;B-树&#xff0c;即为B树。因为B树的原英文名称为B-tree&#xff0c;而国内很多人喜欢把B-tree译作B-树&#xff0c;其实&#xff0c;这是个非常不好的直译&#xf…

B树和B+树

目录 一、BST树到AVL树到B树的简介 1.1 BST树 --- 二叉排序树 1.2 AVL树 --- 平衡二叉树 1.3 B树 --- 平衡多路查找树 1.3.1 B树的查找结点过程 1.3.2 B树的添加结点过程&#xff08;和结点分裂过程&#xff09; 1.3.3 B树的删除结点过程 二、B树 2.1 B树和B树 一…

在群晖NAS部署_开源在线项目任务管理工具【dooTask】

一、dooTask简介 1.1、说明 Dootask 是一款由国人开源的轻量级在线项目任务管理工具&#xff0c;它提供各类文档协作工具、在线思维导图、在线流程图、项目管理、任务分发、即时通讯IM&#xff0c;文件管理等功能。基于PHP与Vue编写&#xff0c;遵守AGPL3.0开源协议。 1.2、特…

软件项目管理的重点知识

软件项目管理的重点知识 1.软件项目管理概述 1.1项目是什么 项目是为了创造一个唯一的产品或提供一个唯一的服务而进行的临时性的努力。 1.2常见的项目 生活中的项目 生日聚会野餐活动集体婚礼 大项目 微软的操作系统阿波罗计划神州飞船计划鸿蒙操作系统开发一个网站运…

推荐八款好用的项目管理工具

要想取得项目成功&#xff0c;避不开包括计划、执行、监控等。使用项目管理工具可以帮助项目经理制定项目计划&#xff0c;监控项目执行&#xff0c;跟踪项目进度。 1、进度猫 进度猫是国产的一款项目管理工具以甘特图为向导&#xff0c;基于任务清单todolist&#xff0c;支持…

工程项目管理软件有哪些?这六款很好用!

工程项目管理软件哪个好用&#xff1f;这六款很不错&#xff01; 在现代社会中&#xff0c;软件已经成为了企业信息化、项目管理等方面必不可少的工具。尤其是对于工程项目管理而言&#xff0c;借助软件进行协同、计划、控制等方面的工作&#xff0c;已经成为了必要的手段。但…

项目管理-软件:国内外知名IT项目管理工具【Worktile、PingCode、Jira、Clarizen、禅道】

IT项目管理随着敏捷的普及&#xff0c;支持其开发模式的工具也越来越多。它和瀑布工具的巨大差异在于一个是任务管理模式&#xff0c;一个是需求驱动管理模式。在这里&#xff0c;我列出了在国内外最知名最好用的敏捷工具及其网站。IT项目管理&#xff0c;或者说研发管理软件是…

10款最佳项目管理工具推荐

1、进度猫 进度猫是一款以甘特图为向导的轻量级在线免费项目进度管理工具。 特点&#xff1a; 基于甘特图、进度管理、任务管理ToDo、在线思维导图、团队协作随时把控项目进度,让项目管理一目了然。 甘特图显示项目的进度和具体任务清单。 对未完成任务、已完成任务进行分类…

知乎热推 6 款在线项目管理工具测评

用了一段时间的项目管理工具后&#xff0c;简单的总结项目管理工具就是&#xff1a; 一个能够满足项目经理对项目资源&#xff08;人员、文件和时间&#xff09;的管理&#xff0c;同时提供了项目进度可视化展示和支持团队合作的平台工具。 在这里&#xff0c;对知乎上热推的几…

项目管理系统源码

项目管理系统源码 功能介绍&#xff1a; 1&#xff1a;权限管理 。 对公司人员&#xff0c;组织架构进行管理&#xff0c;对用户采用角色授权的方式控制结点、菜单权限 3&#xff1a;项目管理。 对一个项目可以进行分阶段&#xff0c;分任务…划分&#xff0c;对每个划分点…

说好求一款在线项目管理软件,你们为什么推荐钉钉?

作为一名整天被各种项目虐得发际线不断后移的项目经理&#xff0c;对于项目管理工具&#xff0c;我是认真的。然而&#xff0c;混迹某些交流群中&#xff0c;时不时碰到有人询问推荐在线项目管理工具&#xff0c;总有人出来说&#xff1a;钉钉。纳尼&#xff1f;钉钉在我眼里真…

如何在项目管理中使用PERT图

PERT是一个项目管理计划工具&#xff0c;用于计算实际完成项目所需的时间。PERT代表计划评估审查技术。PERT图表是用于计划项目内任务的工具 - 可以更轻松地安排和协调完成工作的团队成员。 PERT图表创建于20世纪50年代&#xff0c;旨在帮助管理美国海军的武器和防御项目的创建…

项目资源管理

目录 申明1. 核心概念2. 虚拟团队/分布式团队3. 规划质量管理3.1.1 输入3.1.2 工具和技术3.1.2.1 责任分配矩阵 3.1.3 输出 4. 估算活动资源4.1.1 输入4.1.2 工具与技术4.1.3 输出4.1.3.1 资源分解结构RBS 5. 获取资源5.1.1 输入5.1.2 工具与技术5.1.3 输出 6. 建设团队6.1.1 输…

发现一款好用的在线项目管理工具(有免费版)

&#xff08;注&#xff1a;本文转载自网络&#xff09; 在线项目管理工具指的是不用安装服务器的云部署项目管理软件&#xff0c;这种部署方式的软件可随时开通、节约成本&#xff0c;但质量也参差不齐。 考虑到多方面因素&#xff0c;我们公司最终决定用在线的项目管理工具&…

计算机毕业设计PHP在线项目管理(源码+程序+VUE+lw+部署)

该项目含有源码、文档、程序、数据库、配套开发软件、软件安装教程。欢迎交流 项目运行 环境配置&#xff1a; phpStudy Vscode Mysql5.7 HBuilderXNavicat11VueExpress。 项目技术&#xff1a; 原生PHP Vue 等等组成&#xff0c;B/S模式 Vscode管理前后端分离等等。 环境需要…

Jpom(Java Project Online Management)Java项目在线管理

Jpom(Java Project Online Management)Java项目在线管理 在linux 中管理jar包运行&#xff0c;如SpringBoot、Jboot、jfinal、t-io项目如果是打包为Jar那么我们一般是使用shell 命令来管理, 如果有多个项目管理起来显得比较麻烦。 如果新增、更新、删除项目都不是很方便。 再或…

[附源码]Sprintboot计算机毕业设计在线项目管理【源码+数据库+LW+部署】

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

解决问题ModuleNotFoundError: No module named 'PyQt4'

在用IDLE运行pyqt4程序的时候,出现程序一按button&#xff0c;程序无响应。 然后在cmd中运行文件&#xff1a; C:\Users\XX\Desktop>C:\Users\XX\Desktop\button_one.py 出现以下错误&#xff1a; C:\Users\XX\Desktop>button_one.py Traceback (most recent call last…

PyQt4入门

首先上个图&#xff0c;看看PyQt运行长什么样&#xff1a; 图片来自&#xff1a; http://static.oschina.net/uploads/space/2013/0423/083239_08UQ_5189.jpg PyQt是一个Python GUI库。 PyQt4兼容Python 2.x和Python 3.x&#xff0c;PyQt5只能用于Python 3.x。 这里以PyQt4…