39.B树,B+树(王道第7章查找补充知识)

news2024/9/23 5:24:27

目录

一. B树

(1)B树的定义

(2)B树的高度

(3)B树的插入

(4)B树的删除

二. B+树

(1)B+树的定义

(2)B+树与B树的区别


一. B树

(1)B树的定义

我们首先从二叉查找树到m叉查找树:如下是一个5叉查找树,这里每个结点最多可以有4个关键字,一个关键字可以把区间分成两个部分。

为了保证查找效率,防止树过高的策略:

(1)m叉查找树中,规定除了根节点外,任何结点至少有\left \lceil m/2 \right \rceil个分叉,即至少含有\left \lceil m/2 \right \rceil-1个关键字。如对于5叉排序树,每个结点至少要有3个分叉,2个关键字。

(2)仿照平衡二叉树:在m叉查找树中,规定对于任何一个结点,其所有子树的高度都要相同。

对于以上的m叉树,就称为m阶B树,下面给出B树的定义:

B树,又称多路平衡查找树,B树中所有结点的孩子个数的最大值称为B树的阶,通常用m表示。一棵m阶B树或为空树,或为满足如下特性的m叉树:

  • 1)树中每个结点至多有m棵子树,即至多含有m-1个关键字。
  • 2)若根结点不是终端结点,则至少有两棵子树。
  • 3)除根结点外的所有非叶结点至少有\left \lceil m/2 \right \rceil棵子树,即至少含有\left \lceil m/2 \right \rceil-1个关键字。
  • 4)所有非叶子结点的结构如下:
    nP_0K_1P_1K_2P_2...K_nP_n
  • 其中,Ki (i= 1,2.., n)为结点的关键字,且满足K1<K2<...<Kn;Pi (i = 0,1..., n)为指向子树根结点的指针,且指针Pi-1所指子树中所有结点的关键字均小于Ki,Pi所指子树中所有结点的关键字均大于Ki,n(\left \lceil m/2 \right \rceil-1\leq n\leq m-1)为结点中关键字的个数。
  • 5)所有的叶结点(失败结点)都出现在同一层次上,并且不带信息(可以视为外部结点或类似于折半查找判定树的查找失败结点,实际上这些结点不存在,指向这些结点的指针为空)。
     

(2)B树的高度

下面讨论B树的高度:对于一个包含n个关键字,高度为h,阶数为m的B树(需要说明的是高度一般不包含叶子结点/失败结点):

最小高度:尽可能填满。第一层1个结点,每个结点有m-1个关键字;第二层m个结点,每个结点有m-1个关键字;第三层m^2个结点,每个结点有m-1个关键字;所以有n\leq (m-1)(1+m+m^2+...+m^{h-1})=m^h-1,因此h\geq log_m(n+1)

最大高度:尽可能空置。第一层1个结点,第二层2个结点,第三层有2\left \lceil m/2 \right \rceil个结点,第h层有2\left \lceil m/2 \right \rceil^{h-2}个结点,叶子结点最少有2\left \lceil m/2 \right \rceil^{h-1}个,由于叶子结点就是n+1个(n个关键字分成n+1段区间),所以2\left \lceil m/2 \right \rceil^{h-1}\leq n+1,也就是h\leq log_{\left \lceil m/2 \right \rceil}((n+1)/2)+1

(3)B树的插入

核心要求:

(1)对m阶B树——除根节点外,结点关键字个数\left \lceil m/2 \right \rceil-1\leq n\leq m-1

(2)子树0<关键字1<子树1<关键字2<子树2<....

(3)新元素一定是插入到最底层“终端节点”,用“查找”来确定插入位置(否则失败结点将不在同一层)。


在插入key后,若导致原结点关键字数超过上限,则从中间位置(\left \lceil m/2 \right \rceil)将其中的关键字分为两部分,左部分包含的关键字放在原结点中,右部分包含的关键字放到新结点中,中间位置\left \lceil m/2 \right \rceil的结点插入原结点的父结点。若此时导致其父结点的关键字个数也超过了上限,则继续进行这种分裂操作,直至这个过程传到根结点为止,进而导致B树高度增1.

例:对于一个5阶B树,结点关键字个数是\left \lceil m/2 \right \rceil-1\leq n\leq m-1,也就是2\leqslant n\leqslant 4,现插入25,38,49,60,80,90,99,88,83,87,70,92,93,94,73,74,75

插入80的时候溢出,所以把49提到父结点

插入88的时候溢出,所以把88提到父结点

插入70的时候溢出,所以把80提到父结点(请注意这里的指针联系)

插入94的时候溢出,所以把93提到父结点(请注意这里的指针联系)

插入75的时候溢出,所以把73提到父结点,但此时父结点也溢出,所以要再次操作
把80往上提,得到最后的B树
(4)B树的删除

(1)若被删除关键字在终端节点,则直接删除该关键字(要注意节点关键字个数是否低于下限\left \lceil m/2 \right \rceil-1)

如在上面的B树里删除60:

(2)若被删除关键字在非终端节点,则用直接前驱或直接后继来替代被删除的关键字。对非终端结点关键字的删除,必然可以转化为对终端结点的删除操作。
直接前驱:当前关键字左侧指针所指子树中“最右下”的元素;直接后继:当前关键字左侧指针所指子树中“最左下”的元素;

直接前驱/直接后继一定是终端结点!

如在(1)的基础上删除80,找直接前驱77替代:

然后再删除77,用后继82替代:

(3)如果删除叶子结点导致结点关键字个数低于下限,且与此结点右(或左)兄弟结点的关键字个数还很宽裕,则需要调整该结点、右(或左)兄弟结点及其双亲结点(父子换位法)
说白了,当右兄弟很宽裕时,用当前结点的后继、后继的后继来填补空缺。

例如删除38,借用右面的兄弟结点中的70:

再删除90,借用左面的兄弟结点中的87:

(4)若被删除关键字所在结点删除前的关键字个数低于下限,且此时与该结点相邻的左、右兄弟结点的关键字个数均为\left \lceil m/2 \right \rceil-1,则将关键字删除后与左(或右)兄弟结点及双亲结点中的关键字进行合并。

例如:继续删除49:

此时合并完73又不满足最低关键字个数,所以还要合并一步

二. B+树

(1)B+树的定义

一棵m阶的B+树需满足下列条件:

  • 每个分支结点最多有m棵子树(孩子结点)。
  • 非叶根结点至少有两棵子树,其他每个分支结点至少有\left \lceil m/2 \right \rceil棵子树。
  • 结点的子树个数与关键字个数相等。
  • 所有叶结点包含全部关键字及指向相应记录的指针,叶结点中将关键字按大小顺序排列,并且相邻叶结点按大小顺序相互链接起来(支持顺序查找)。
  • 所有分支结点中仅包含它的各个子结点中关键字的最大值及指向其子结点的指针。

需要注意的是:对于多路查找,无论查找成功与否,最终都会走到叶子结点,这是和B树不一样的地方。

在B+树中,非叶结点不含有该关键字对应记录的存储地址。可以使一个磁盘块可以包含更多个关键字,使得B+树的阶更大,树高更矮,读磁盘次数更少,查找更快。

(2)B+树与B树的区别

对于m阶B+树与m阶B树:

1)B+树结点中的n个关键字对应n棵子树,B树结点中的n个关键字对应n+1棵子树

2)对m阶B+树,根结点关键字个数n\in \left [ 2,m \right ],其他结点关键字个数n\in \left [ \left \lceil m/2 \right \rceil,m \right ]。对m阶B树,根结点关键字个数n\in \left [ 1,m-1 \right ],其他结点关键字个数n\in \left [ \left \lceil m/2 \right \rceil-1,m-1 \right ]

3)在B+树中,叶结点包含全部关键字,非叶结点中出现过的关键字也会出现在叶结点中。在B树中,各结点中包含的关键字是不重复的。

4)在B+树中,叶结点包含信息,所有非叶结点仅起索引作用,非叶结点中的每个索引项只含有对应子树的最大关键字和指向该子树的指针,不含有该关键字对应记录的存储地址。B树的结点中都包含了关键字对应的记录的存储地址。

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

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

相关文章

什么是自动证书管理环境(ACME)

组织的网站需要 24x7 全天候可用&#xff0c;以建立信任并提供信息&#xff0c;如果网站因证书过期而停机&#xff0c;那么很难恢复失去的客户信任、收入和品牌声誉&#xff0c;手动管理证书基础结构会使组织面临中断、中间人 &#xff08;MITM&#xff09; 攻击等的严重风险。…

新上线游戏产品需不需要防御?

游戏运营免不了遭受恶意DDoS和CC攻击&#xff0c;且攻击常达百G以上&#xff0c;攻击流量过大&#xff0c;超过一般服务器的基础防护能力&#xff0c;不少企业面对大流量攻击显得束手无策&#xff0c;只能选择被迫停机&#xff0c;其次游戏行业利润高&#xff0c;很容易被黑客盯…

智慧矿山:如何快速识别带式运输机空载状态!

带式运输机作为一种常见的物料输送设备&#xff0c;广泛应用于矿山、建筑、化工等行业。但在使用过程中&#xff0c;经常会出现空载运行的情况&#xff0c;即带式运输机无物料传送时仍不停工作&#xff0c;导致能源和设备的浪费。因此&#xff0c;对带式运输机进行空载识别并采…

【期刊】IEEE系列指定期刊模版下载(LaTeX或者Word)全网最细教程

IEEE旗下有很多期刊&#xff0c;例如&#xff1a; IEEE Transactions on Pattern Analysis and Machine Intelligence IEEE Transactions on Cybernetics IEEE Transactions on Neural Networks and Learning Systems IEEE Transactions on Industrial Informatics IEEE Tra…

代理服务器可能有问题,或地址不正确的解决办法

问题&#xff1a; 解决办法&#xff1a; 1.找到代理服务器设置 2.代理服务器&#xff0c;设置关闭

基于springboot实现在线考试平台管理系统【项目源码+论文说明】计算机毕业设计

基于Springboot实现在线考试平台管理系统演示 摘要 网络的广泛应用给生活带来了十分的便利。所以把在线考试管理与现在网络相结合&#xff0c;利用java技术建设在线考试系统&#xff0c;实现在线考试的信息化管理。则对于进一步提高在线考试管理发展&#xff0c;丰富在线考试管…

[笔记] Windows 审计《一》判断是否SACL系统记录权限、DACL管理权限是否继承

文章目录 前言代码总结 前言 安全对象&#xff1a;由微软定义为可以具有安全描述符的对象&#xff0c;包括诸如文件&#xff0c;线程&#xff0c;远程注册表&#xff0c;Active Directory对象等许多东西。 安全描述符&#xff1a;包含许多字段的二进制结构&#xff0c;包括对…

K-Means和KNN

主要区别 从无序 —> 有序 从K-Means —> KNN KNN&#xff1a;监督学习&#xff0c;类别是已知的&#xff0c;对已知分类的数据进行训练和学习&#xff0c;找到不同类的特征&#xff0c;再对未分类的数据进行分类。K-Means&#xff1a;无监督学习&#xff0c;事先不知道…

一套成熟的ERP系统,应具备哪些能力?

随着制造业数字化、智能化的不断升级&#xff0c;企业的金字塔静态管理模式也在向扁平化动态管理模式转变&#xff0c;而企业管理系统则是推动这一趋势发展的重要载体。 为了更好地实现企业管理信息化&#xff0c;越来越多的企业在应用ERP系统。ERP对企业经营起着至关重要的辅…

Kafka-Java一:Spring实现kafka消息的简单发送

目录 写在前面 一、创建maven项目 二、引入依赖 2.1、maven项目创建完成后&#xff0c;需要引入以下依赖 2.2、创建工程目录 三、创建生产者 3.1、创建生产者&#xff0c;同步发送消息 3.2、创建生产者&#xff0c;异步发送消息 四、同步发送消息和异步发送消息的区别…

ChinaSoft 论坛巡礼 | 开源软件生态健康度量论坛

2023年CCF中国软件大会&#xff08;CCF ChinaSoft 2023&#xff09;由CCF主办&#xff0c;CCF系统软件专委会、形式化方法专委会、软件工程专委会以及复旦大学联合承办&#xff0c;将于2023年12月1-3日在上海国际会议中心举行。 本次大会主题是“智能化软件创新推动数字经济与社…

京东销量(销额)数据分析:2023年9月京东奶粉行业品牌销售排行榜

鲸参谋监测的京东平台9月份奶粉市场销售数据已出炉&#xff01; 根据鲸参谋平台的数据显示&#xff0c;今年9月份&#xff0c;京东平台奶粉&#xff08;包括婴幼儿奶粉、孕妈奶粉、婴幼儿液态奶&#xff09;市场的销量约730万&#xff0c;环比降低约6%&#xff0c;同比降低约19…

【C语言】指针那些事(上)

C语言系列 文章目录 文章目录 一. 字符指针 一.&#xff08;1 &#xff09; 数组创建空间的地址和指针指向的地址 二. 指针数组 二.&#xff08;1&#xff09;指针数组模拟一个二维数组 ​ 三. 数组指针 三.(1)数组指针到底有什么用 对一维数组没有什么用 二.(…

VC++程序崩溃时,使用Visual Studio静态分析dump文件

1、通过Visual Studio直接把Dump文件打开 2、点击【仅限本机进行调试】&#xff0c;启动Dump 3.1、本机调试启动后&#xff0c;如果程序运行模块和pdb文件在同一个目录的&#xff0c;直接定位到异常代码行 3.2、如果显示找不到pdb文件&#xff0c;则需要通过【新建路径】设置…

Python-列表、元组和字典

目录 一、列表概述 二、列表的循环遍历 1、使用for循环遍历列表 2、使用while循环遍历列表 三、列表的常见操作 1、在列表中增加元素 &#xff08;1&#xff09;使用append方法 &#xff08;2&#xff09;使用extend方法 &#xff08;3&#xff09;使用insert方法 2、…

温馨提示!小心不法分子的隐藏陷阱

《绝地求生》国服的”老兵回归”活动一经推出就受到广大玩家欢迎&#xff0c;因此也有不法分子想趁虚而入。就在近日&#xff0c;我们接到玩家举报&#xff0c;发现一些不法分子通过伪基站邮件群发的形式&#xff0c;以“第XXXX位老兵奖励”为主题&#xff0c;向用户推荐一个非…

【薅羊毛】免费领取6个月语雀会员-关于语雀 23 日故障的公告

关于语雀 23 日故障的公告 关于语雀 23 日故障的公告 语雀团队 语雀 2023-10-24 21:11 发表于浙江 各位语雀的用户&#xff1a; 10 月 23 日语雀出现重大服务故障&#xff0c;且持续 7 个多小时才完全恢复&#xff0c;给用户使用造成极大不便&#xff0c;对此我们深感抱歉。…

Go 包操作之如何拉取私有的Go Module

Go 包操作之如何拉取私有的Go Module 在前面&#xff0c;我们已经了解了GO 项目依赖包管理与Go Module常规操作&#xff0c;Go Module 构建模式已经成为了 Go 语言的依赖管理与构建的标准。 在平时使用Go Module 时候&#xff0c;可能会遇到以下问题&#xff1a; 在某 modul…

关于报错java.util.ConcurrentModificationException: null的源码分析和解决

一般有这种问题,方法中至少会有List或者Map下的至少两个子类,有可能参数类型相同,也有可能不同都有可能触发这个问题!其主要原因是使用了ArrayList进行删除操作或者使用iterator遍历集合的同时对集合进行修改都有可能会出现这个问题 ArrayList属于List下的子类 需要区分的是Li…

AI小百科 - 什么是生成式AI中的提示语 “Prompt“

定义 "Prompt" 是指在生成式AI中用于指导模型生成输出的输入文本或问题。它是一种方法&#xff0c;通过提供特定的信息或指示&#xff0c;引导AI生成与所需任务相关的响应。 让我们用一个小学生可以理解的方式来解释提示语。想象一下&#xff0c;你是一名小学生&am…