热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

【数据结构】B树(B树)和B+树

B树的定义B树,又称为多路平衡查

B树的定义

B树,又称为多路平衡查找树,B树中所有结点的孩子个数的最大值称为B树的阶,通常用m表示。一颗m阶B树或为空树,或为满足如下特性的m叉树:
1)树中每个结点至多有m颗子树,即最多含有m-1个关键字。
2)若根结点不是终端节点,则至少有两颗子树。
3)除根节点外的所有非叶结点至少有⌈m/2⌉颗子树,即至少含有⌈m/2⌉-1个关键字。
4)所有非叶结点的结构如下:

np0k1p1k2p2knpn

其中,ki为结点的关键字,且满足k1 【ki若是对应了value,则还需要将value考虑进去】
【B树的非叶结点中保存m-1个关键字,以及其所对应的记录的地址,保存m个指向子树/子结点的指针,保存一个整数n,即记录该节点中实际关键字个数的整数】
5)所有叶结点都出现在同一层次上,并且不带信息(可以视为外部结点或类似于折半查找判定树的查找失败结点,实际上这些结点不存在,指向这些结点的指针为空)。

B树的高度(磁盘存取次数)

对于一颗包含n个关键字、高度为h、阶数为m的B树:

1)因为B树中每个结点最多有m棵子树,m-1个关键字,所以在一颗高度为h的m阶B树中关键字的个数应满足n <= (m-1)(1 + m + m^2 + … + m^h-1) = m^h - 1,因此有:h >= logm(n+1)

2)若让每个结点中的关键字个数达到最少,则容纳同样多的关键字的B树的高度达到最大。由B树的定义:第一层至少有1个结点;第二层至少有两个结点;除了根结点外的每个非终端结点至少有⌈m/2⌉颗子树,则第三层至少有2⌈m/2⌉个结点,第h+1层至少有2⌈m/2⌉^(h-1)个结点,注意到第h+1层是不包含任何信息的叶子结点。
对于关键字个数为n的B树,叶结点即查找不成功的结点为n+1,由此有n+1 >= 2(⌈m/2⌉)^(h-1)
h <= log⌈m/2⌉((n+1)/2) + 1

例如,假设一颗3阶B树共有8个关键字,其高度范围为2 <= h <= 3.17

B树的查找

1)在B树中找结点
2)在结点内找关键字
由于B树常存储在磁盘上,因此前一个查找操作是在磁盘上进行的,而后一个查找操作是在内存中进行的,即在找到目标结点后,先将结点信息读入内存,然后在结点内采用顺序查找或折半查找法。查找到叶结点时(对应指针为空指针),则说明树中没有对应的关键字,查找失败。

B树的插入

1)定位。利用前述的B树查找算法,找出插入该关键字的最低层中的某个非叶结点。
2)插入。在B树中,每个非失败结点的关键字个数都在区间⌈m/2⌉-1到m-1内。插入后的结点关键字个数小于m,可以直接插入;插入后检查被插入结点内的关键字的个数,当插入后的结点关键字个数大于m-1时,必须对结点进行分裂。
分裂的方法:取一个新结点,在插入key后的原结点,从中间位置(⌈m/2⌉)将其中的关键字分为两部分,左部分包含的关键字放在原结点中,右部分包含的关键字放在新结点中,中间位置(⌈m/2⌉)的结点插入原结点的父结点。若此时导致其父结点的关键字个数也超过了上限,则继续进行这种分裂操作,直至这个过程传到根节点为止,进而导致B树高度增1。

B树的删除

当被删除关键字k不在终端结点(最低层非叶结点)中时,可以用k的前驱(或后继)k’来代替k,然后在相应的结点中删除k’,关键字k’必定落在某个终端结点中,则转换成了被删关键字在终端结点中的情形。因此只需讨论删除终端结点中关键字的情形。

当被删关键字在终端节点中时,有下列三种情况:

1)直接删除关键字。若被删除关键字所在结点的关键字个数 ≥ ⌈m/2⌉,表明删除该关键字后仍满足B树的定义,则直接删去该关键字。

2)兄弟够借。若被删除关键字所在结点删除前的关键字个数 = ⌈m/2⌉-1,且与此结点相邻的右(或左)兄弟结点的关键字个数 >= ⌈m/2⌉,则需要调整该结点、右(或左)兄弟结点、及其双亲结点(父子换位法),以达到新的平衡。

3)兄弟不够借。若兄弟不够借时,就将该结点删除,删除完后将兄弟结点和双亲结点进行合并。在合并过程中,双亲结点中的关键字个数会减1。若其双亲结点是根结点且关键字个数减少至0,则直接将根节点删除,合并后的新结点成为根;若双亲结点不是根节点,且关键字个数减少到⌈m/2⌉-2,则又要与它自己的兄弟结点进行调整或合并操作。

B+树的定义

一颗m阶的B+树需满足下列条件:
1)每个分支结点最多有m棵子树(孩子节点)。
2)非叶根节点至少有两棵子树,其他每个分支结点至少有⌈m/2⌉棵子树。
3)结点的子树个数与关键字个数相等
4)所有叶结点包含全部关键字及指向相应记录的指针,叶结点中将关键字按大小顺序排列,并且相邻叶结点按大小顺序相互链接起来。
5)所有分支结点(可以视为索引的索引)中仅包含它的各个子结点(即下一级索引块)中关键字的最大值及指向其子结点的指针。

B+树和B树的差异

1)在B+树中,具有n个关键字的结点含有n棵子树;而在B树中,具有n个关键字的结点至少含有n+1棵子树。
2)在B+树中,每个结点(除根节点外)中的关键字个数n的取值范围为⌈m/2⌉ <= n <= m 。根结点n的取值范围为2 <= n <= m。而在B树中,除根节点外,其他所有非叶子结点的关键字个数n的取值范围是⌈m/2⌉-1 <= n <= m -1,根结点n的取值范围是1 <= n <= m - 1。
3)在B+树中,所有叶子结点包含了全部关键字,即其他非叶子结点中的关键字也包含在叶子结点中;而在B树中,关键字是不重复的。
4)在B+树中,所有非叶子结点仅仅起到了索引的作用,即结点中的每个索引项只包含对应子树的最大关键字和指向子树的指针,不包含该关键字对应记录的存储地址;而在B树中,每个关键字对应一个记录的存储地址。
5)在B+树中有两个头指针,一个指向根节点,另一个指向关键字最小的叶子结点,所有叶子结点链接成一个链表;而在B树中,叶子节点并不会有指针相连。


推荐阅读
  • 优化ListView性能
    本文深入探讨了如何通过多种技术手段优化ListView的性能,包括视图复用、ViewHolder模式、分批加载数据、图片优化及内存管理等。这些方法能够显著提升应用的响应速度和用户体验。 ... [详细]
  • 使用Numpy实现无外部库依赖的双线性插值图像缩放
    本文介绍如何仅使用Numpy库,通过双线性插值方法实现图像的高效缩放,避免了对OpenCV等图像处理库的依赖。文中详细解释了算法原理,并提供了完整的代码示例。 ... [详细]
  • 1:有如下一段程序:packagea.b.c;publicclassTest{privatestaticinti0;publicintgetNext(){return ... [详细]
  • C++实现经典排序算法
    本文详细介绍了七种经典的排序算法及其性能分析。每种算法的平均、最坏和最好情况的时间复杂度、辅助空间需求以及稳定性都被列出,帮助读者全面了解这些排序方法的特点。 ... [详细]
  • 本文详细介绍了如何使用 Yii2 的 GridView 组件在列表页面实现数据的直接编辑功能。通过具体的代码示例和步骤,帮助开发者快速掌握这一实用技巧。 ... [详细]
  • Yii 实现阿里云短信发送 ... [详细]
  • golang常用库:配置文件解析库/管理工具viper使用
    golang常用库:配置文件解析库管理工具-viper使用-一、viper简介viper配置管理解析库,是由大神SteveFrancia开发,他在google领导着golang的 ... [详细]
  • Linux 系统启动故障排除指南:MBR 和 GRUB 问题
    本文详细介绍了 Linux 系统启动过程中常见的 MBR 扇区和 GRUB 引导程序故障及其解决方案,涵盖从备份、模拟故障到恢复的具体步骤。 ... [详细]
  • 本文探讨了Hive中内部表和外部表的区别及其在HDFS上的路径映射,详细解释了两者的创建、加载及删除操作,并提供了查看表详细信息的方法。通过对比这两种表类型,帮助读者理解如何更好地管理和保护数据。 ... [详细]
  • 深入理解 SQL 视图、存储过程与事务
    本文详细介绍了SQL中的视图、存储过程和事务的概念及应用。视图为用户提供了一种灵活的数据查询方式,存储过程则封装了复杂的SQL逻辑,而事务确保了数据库操作的完整性和一致性。 ... [详细]
  • 本文详细介绍了 Dockerfile 的编写方法及其在网络配置中的应用,涵盖基础指令、镜像构建与发布流程,并深入探讨了 Docker 的默认网络、容器互联及自定义网络的实现。 ... [详细]
  • c# – UWP:BrightnessOverride StartOverride逻辑 ... [详细]
  • 解决Linux系统中pygraphviz安装问题
    本文探讨了在Linux环境下安装pygraphviz时遇到的常见问题,并提供了详细的解决方案和最佳实践。 ... [详细]
  • 深入理解C++中的KMP算法:高效字符串匹配的利器
    本文详细介绍C++中实现KMP算法的方法,探讨其在字符串匹配问题上的优势。通过对比暴力匹配(BF)算法,展示KMP算法如何利用前缀表优化匹配过程,显著提升效率。 ... [详细]
  • 本文详细介绍了Java编程语言中的核心概念和常见面试问题,包括集合类、数据结构、线程处理、Java虚拟机(JVM)、HTTP协议以及Git操作等方面的内容。通过深入分析每个主题,帮助读者更好地理解Java的关键特性和最佳实践。 ... [详细]
author-avatar
破背包
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有