B树和B+树的总结
B树
为什么要B树
磁盘中有两个机械运动的部分,分别是盘片旋转和磁臂移动。盘片旋转就是我们市面上所提到的多少转每分钟,而磁盘移动则是在盘片旋转到指定位置以后,移动磁臂后开始进行数据的读写。那么这就存在一个定位到磁盘中的块的过程,而定位是磁盘的存取中花费时间比较大的一块,毕竟机械运动花费的时候要远远大于电子运动的时间。当大规模数据存储到磁盘中的时候,显然定位是一个非常花费时间的过程,但是我们可以通过B树进行优化,提高磁盘读取时定位的效率。
简介
这里的B树,也就是英文中的B-Tree,一个 m 阶的B树满足以下条件:
- 每个结点至多拥有m棵子树;
- 除了根结点以外,其余每个分支结点至少拥有 m/2 棵子树;
- 根结点至少拥有两颗子树(存在子树的情况下);
- 所有的叶结点都在同一层上,其可以看作是外部结点,不包含任何信息;
- 有 k 棵子树的非叶子结点则其存在 k-1 个关键码,关键码按照递增次序进行排列;
- 关键字数量需要满足ceil(m/2)-1 <= n <= m-1;
举个栗子:

B树上大部分的操作所需要的磁盘存取次数和B树的高度是成正比的,在B树中可以检查多个子结点,由于在一棵树中检查任意一个结点都需要一次磁盘访问,所以B树避免了大量的磁盘访问。
操作
既然是树,那么必不可少的操作就是插入和删除,这也是B树和其它数据结构不同的地方,当然了,还有必不可少的搜索,分享一个对B树的操作进行可视化的网址,它是由usfca提供的。
假定对高度为h的m阶B树进行操作。
插入
新结点一般插在第h层,通过搜索找到对应的结点进行插入,那么根据即将插入的结点的数量又分为下面几种情况。
- 如果该结点的关键字个数没有到达m-1个,那么直接插入即可;
- 如果该结点的关键字个数已经到达了m-1个,那么根据B树的性质显然无法满足,需要将其进行分裂。分裂的规则是该结点分成两半,将中间的关键字进行提升,加入到父亲结点中,但是这又可能存在父亲结点也满员的情况,则不得不向上进行回溯,甚至是要对根结点进行分裂,那么整棵树都加了一层。
其过程如下:




删除
同样的,我们需要先通过搜索找到相应的值,存在则进行删除,需要考虑删除以后的情况,
- 如果该结点拥有关键字数量仍然满足B树性质,则不做任何处理;
- 如果该结点在删除关键字以后不满足B树的性质(关键字没有到达ceil(m/2)-1的数量),则需要向兄弟结点借关键字,这有分为兄弟结点的关键字数量是否足够的情况。
- 如果兄弟结点的关键字足够借给该结点,则过程为将父亲结点的关键字下移,兄弟结点的关键字上移;
- 如果兄弟结点的关键字在借出去以后也无法满足情况,即之前兄弟结点的关键字的数量为ceil(m/2)-1,借的一方的关键字数量为ceil(m/2)-2的情况,那么我们可以将该结点合并到兄弟结点中,合并之后的子结点数量少了一个,则需要将父亲结点的关键字下放,如果父亲结点不满足性质,则向上回溯;
- 其余情况参照BST中的删除。
其过程如下:



B+树
为什么要B+树
由于B+树的数据都存储在叶子结点中,分支结点均为索引,方便扫库,只需要扫一遍叶子结点即可,但是B树因为其分支结点同样存储着数据,我们要找到具体的数据,需要进行一次中序遍历按序来扫,所以B+树更加适合在区间查询的情况,所以通常B+树用于数据库索引,而B树则常用于文件索引。
简介
同样的,以一个m阶树为例:
- 根结点只有一个,分支数量范围为[2,m];
- 分支结点,每个结点包含分支数范围为[ceil(m/2), m];
- 分支结点的关键字数量等于其子分支的数量;
- 所有叶子结点都在同一层,其关键字的数量范围为[ceil(m/2), m],从小到达进行排序;
操作
其操作和B树的操作是类似的,不过需要注意的是,在增加值的时候,如果存在满员的情况,将选择结点中的值作为新的索引,还有在删除值的时候,索引中的关键字并不会删除,也不会存在父亲结点的关键字下沉的情况,因为那只是索引。
B树和B+树的区别
这都是由于B+树和B具有这不同的存储结构所造成的区别,以一个m阶树为例。
- 关键字的数量不同;B+树中分支结点有m个关键字,其叶子结点也有m个,其关键字只是起到了一个索引的作用,但是B树虽然也有m个子结点,但是其只拥有m-1个关键字。
- 存储的位置不同;B+树中的数据都存储在叶子结点上,也就是其所有叶子结点的数据组合起来就是完整的数据,但是B树的数据存储在每一个结点中,并不仅仅存储在叶子结点上。
- 分支结点的构造不同;B+树的分支结点仅仅存储着关键字信息和儿子的指针(这里的指针指的是磁盘块的偏移量),也就是说内部结点仅仅包含着索引信息。
- 查询不同;B树在找到具体的数值以后,则结束,而B+树则需要通过索引找到叶子结点中的数据才结束,也就是说B+树的搜索过程中走了一条从根结点到叶子结点的路径。
B树和B+树的总结的更多相关文章
- wpf 逻辑树与可视化树
XAML天生就是用来呈现用户界面的,这是由于它具有层次化的特性.在WPF中,用户界面由一个对象树构建而成,这棵树叫作逻辑树.逻辑树的概念很直观,但是为什么要关注它呢?因为几乎WPF的每一方面(属性.事 ...
- 浅谈算法和数据结构: 十 平衡查找树之B树
前面讲解了平衡查找树中的2-3树以及其实现红黑树.2-3树种,一个节点最多有2个key,而红黑树则使用染色的方式来标识这两个key. 维基百科对B树的定义为“在计算机科学中,B树(B-tree)是一种 ...
- B树、B+树的实现
B树的定义 假设B树的度为t(t>=2),则B树满足如下要求:(参考算法导论) (1) 每个非根节点至少包含t-1个关键字,t个指向子节点的指针:至多包含2t-1个关键字,2t个指向子女的指针 ...
- B树、B-树、B+树、B*树
B树 即二叉搜索树: 1.所有非叶子结点至多拥有两个儿子(Left和Right) 2.所有结点存储一个关键字 3.非叶子节点的左指针指向小于其关键字的字数,右指针指向大于其关键字的字数: 如: B树的 ...
- 人人都是 DBA(VII)B 树和 B+ 树
B 树(B-Tree)是为磁盘等辅助存取设备设计的一种平衡查找树,它实现了以 O(log n) 时间复杂度执行查找.顺序读取.插入和删除操作.由于 B 树和 B 树的变种在降低磁盘 I/O 操作次数方 ...
- 字典树(Trie树)
1. trie基础 (1) 是什么? Trie,又称单词查找树或键树,是一种树形结构,是一种哈希树的变种. (2) 性质 根节点不包含字符,除根节点外每一个节点都只包含一个字符 从根节点到某一节点,路 ...
- (转)B-树、B+树、B*树
B-树 是一种多路搜索树(并不是二叉的): 1.定义任意非叶子结点最多只有M个儿子:且M>2: 2.根结点的儿子数为[2, M]: 3.除根结点以外的非叶子结点的儿子数为[M/2, M]: 4. ...
- 从B 树、B+ 树、B* 树谈到R 树
从B 树.B+ 树.B* 树谈到R 树 作者:July.weedge.Frankie.编程艺术室出品. 说明:本文从B树开始谈起,然后论述B+树.B*树,最后谈到R 树.其中B树.B+树及B*树部分由 ...
- B树和B+树
当数据量大时,我们如果用二叉树来存储的会导致树的高度太高,从而造成磁盘IO过于频繁,进而导致查询效率下降.因此采用B树来解决大数据存储的问题,很多数据库中都是采用B树或者B+树来进行存储的.其目的就是 ...
- 转 浅谈算法和数据结构: 十 平衡查找树之B树
前面讲解了平衡查找树中的2-3树以及其实现红黑树.2-3树种,一个节点最多有2个key,而红黑树则使用染色的方式来标识这两个key. 维基百科对B树的定义为"在计算机科学中,B树(B-tre ...
随机推荐
- angular 实现时间段选择组件
前段时间公司有个后台项目需要使用一个选择时间段的组件,看了一下就自己写了一下,用angular写这种插件还是很简单的. 先看看最终是什么样子的: 功能是用户可以选择任意时间段,鼠标可以拖动任意的一周的 ...
- 由CODEVS笨小猴1053引发的一些思考
#include<cstdio> #include<cstring> ]; ]; int check(int n) { ||n==) ; ;m*m<=n;++m) ) ; ...
- iOS开发 - Swift使用GCD实现计时器功能
前言 开发中,经常会用到定时执行网络请求.倒计时.计时器等功能,本篇文章介绍在iOS开发中,Swift怎样使用GCD实现这些功能. 执行一次 下面的代码将会在5秒后执行,且只执行一次. let tim ...
- Java 第一个程序案HelloWorld例记录
1.编辑源代码,先看代码: class HelloWorld{ public static void main(String[] args) { System.out.println("He ...
- java:Comparator比较器
/*Comparator是java.util包里的一个接口,使用时应该实现导入相应的包, *再写一个实现了Comparator接口的类,并复写int compare(Object o)方法, *写出你 ...
- ST-2
1.第一个程序没有覆盖到下表为0的数.第二个程序找到的是x中第一个等于0的数的下标. 2.对于第一个程序:x = [2,3,5], y = 3 对于第二个程序:X = [2,0,6] 3.对于两个程序 ...
- macOS10.12部署sonarqube5.6.3 + mysql5.7.17
所需安装包已全部上传云盘:https://pan.baidu.com/s/1i5LvOCd 密码:s47e 1. 安装mysql 下载云盘的dmg包,一路默认安装,注意:一定要记住最后一步弹出的默认密 ...
- 利用PHPExcel读取Excel的数据和导出数据到Excel
PHPExcel是一个PHP类库,用来帮助我们简单.高效实现从Excel读取Excel的数据和导出数据到Excel.也是我们日常开发中,经常会遇到的使用场景.比如有个客户信息表,要批量导出发给同事,我 ...
- linux下实时监测命令运行结果工具:watch
watch是一个非常实用的工具,可以实时监测一些经常变化的命令结果或文件,而不需要手动一次一次的输入命令. 语法: watch [选项] [命令参数] 选项: -n :指定刷新间隔时间,默认2秒. - ...
- LeetCode 题解(一):Two Sum
LeetCode : two sum 第一次写博客,算是熟悉这些编辑环境吧,本来是打算在csdn上用markdown写的,结果改了博客介绍就被关闭了,晕死...好了,话不多说,今天打算拿LeetCod ...