B树与B+树

参考:
https://www.jianshu.com/p/a858bb15cbf0

https://www.jianshu.com/p/71700a464e97

https://blog.csdn.net/Fmuma/article/details/80287924

http://data.biancheng.net/view/61.html

B树

B数是一种平衡的多叉树,适用于外查找的树。

一些概念

在看定义之前我们先了解一些概念。
关键字个数:节点内存储的元素个数。
阶:任意非叶子结点最多只有M个儿子,那么就是M阶。

定义

一棵m阶B树(balanced tree of order m)是一棵平衡的m路搜索树。它或者是空树,或者是满足下列性质的树:

  1. 根结点至少有两个子女;
  2. 每个非根节点所包含的关键字个数 j 满足:┌m/2┐ - 1 <= j <= m - 1;
  3. 除根结点以外的所有结点(不包括叶子结点)的度数正好是关键字总数加1,故内部子树个数 k 满足:┌m/2┐ <= k <= m ;
  4. 所有的叶子结点都位于同一层。

注意:若根节点为叶子节点,那么整棵树只有一个根节点。
4阶B树

B树的查找

B树是类似二叉搜索树的多叉搜索树。存储是有顺序的。

  1. 从根节点开始查找。
  2. 当前节点可能有一个或多个关键字,对比是否有与查找值相同的关键字。如果有则结束查询。
  3. 如果在当前节点未找到,则到对应的子节点中查找。(比如,查找值的大小在某两个相邻关键字的中间,那么则去它们的子节点中找。又比如,查找值小于最左关键字,则去最左子节点中找。)
  4. 重复2和3,直到搜索过所有的节点。如果还没找到则返回未找到。

B树的插入

对高度为k的m阶B树,新结点一般是插在叶子层。通过检索可以确定关键码应插入的结点位置。然后分两种情况讨论:
  1、 若该结点中关键码个数小于m-1,则直接插入即可。
  2、 若该结点中关键码个数等于m-1,则将引起结点的分裂。以中间关键码为界将结点一分为二,产生一个新结点,并把中间关键码插入到父结点(k-1层)中。父节点关键字小于m-1则直接插入,若等于m-1也需要分裂。
  重复上述工作,最坏情况一直分裂到根结点,建立一个新的根结点,整个B树增加一层。
  在这里插入图片描述
  在这里插入图片描述

B树的删除

B树的删除操作相对较为复杂,我看许多文档解释的都十分官方且难懂。所以我准备用更为简单的图来对删除操作的不同情况进行解释。希望大家看完后能够理解。

首先,根据key删除记录,如果B树中的记录中不存对应key的记录,则删除失败。
之后我们需要分一下四种情况来考虑。(下面的例子中以5阶B树为例,介绍B树的删除操作,5阶B树中,结点最多有4个key,最少有2个key)对于删除key的过程来说,对于叶结点和非叶结点其实差别在一个地方,那就是如果当前我们操作的是非叶结点,那么后继key(这里的后继key指最接近当前删除值,且大于当前删除值的值)覆盖要删除的key,然后在后继key所在的子支中删除该后继key。

例如:

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

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

image.png
之后我们就把非叶结点的情况转换为了处理叶结点的情况。

此时我们就要分一下几种情况来考虑如何处理叶结点。

①该结点key个数>=Ceil(m/2)-1(上界,例如m=5,那么最后为2),结束删除操作,否则执行下一步。
②该结点key的个数<Ceil(m/2)-1,且兄弟结点key个数>Ceil(m/2)-1,则父结点中的key下移到该结点,兄弟结点中的一个key上移,删除操作结束。
a)紧接上面的例子。

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

image.png
③如果该结点key的个数<Ceil(m/2)-1,且兄弟结点key个数<=Ceil(m/2)-1,那么将父结点中的key下移与当前结点及它的兄弟结点中的key合并,形成一个新的结点。原父结点中的key的两个孩子指针就变成了一个孩子指针,指向这个新结点。
例如:

a)原图为

image.png
b)在上述情况下删除32。

image.png
当删除后,当前结点中只有一个key(个数<Ceil(m/2)-1),而兄弟结点中也仅有2个key(<=Ceil(m/2)-1)。所以只能让父结点中的30下移和这个两个孩子结点中的key合并,成为一个新的结点,当前结点的指针指向父结点。结果如下图所示。

image.png
由于我们移动了父结点中的数据,所以其key值减少,那么我们就要对当前父结点进行考虑。

下面看一个考虑父结点的例子。

a)原图

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

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

image.png
同理,对于当前结点而言只能继续合并了,最后结果如下所示。(根据情况③)

image.png
合并后结点当前结点满足条件,删除结束

B+树

B+树是B树的一种变形形式,B+树上的叶子结点存储关键字以及相应记录的地址,叶子结点以上各层作为索引使用。

定义

(1)每个结点至多有m个子女;
(2)除根结点外,每个结点至少有[m/2]个子女,根结点至少有两个子女;
(3)有k个子女的结点必有k个关键字。

B+树的查找与B树不同,当索引部分某个结点的关键字与所查的关键字相等时,并不停止查找,应继续沿着这个关键字左边的指针向下,一直查到该关键字所在的叶子结点为止。
在这里插入图片描述
每一个父节点都出现在子节点中,是子节点最大或者最小的元素。
在这里,根节点中最大的元素是15,也就是整个树中最大的元素。以后无论插入多少元素要始终保持最大元素在根节点当中。
每个叶子节点都有一个指针,指向下一个数据,形成一个有序链表。
在这里插入图片描述
而只有叶子节点才会有data,其他都是索引。

B+树和B树的区别

  • 有k个子结点的结点必然有k个关键码;
  • 非叶结点仅具有索引作用,跟记录有关的信息均存放在叶结点中。
  • 树的所有叶结点构成一个有序链表,可以按照关键码排序的次序遍历全部记录。

比起B树,B+树 ①IO次数更少 ②查询性能很稳定 ③范围查询更简便

B+树的查询操作

在单元查询的时候,B+树会自定向下逐层查找,最终找到匹配的叶子节点。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

B+树的插入

图一
图一

在B+树中插入关键字时,需要注意以下几点:

  • 插入的操作全部都在叶子结点上进行,且不能破坏关键字自小而大的顺序;
  • 由于 B+树中各结点中存储的关键字的个数有明确的范围,做插入操作可能会出现结点中关键字个数超过阶数的情况,此时需要将该结点进行“分裂”;

B+树中做插入关键字的操作,有以下 3 种情况:
1、 若被插入关键字所在的结点,其含有关键字数目小于阶数 M,则直接插入结束;
例如,在图 1 中插入关键字13,其结果如图 2 所示:
在这里插入图片描述
图 2 插入 13 后的B+树

2、 若被插入关键字所在的结点,其含有关键字数目等于阶数 M,则需要将该结点分裂为两个结点,一个结点包含⌊M/2⌋,另一个结点包含⌈M/2⌉。同时,将⌈M/2⌉的关键字上移至其双亲结点。假设其双亲结点中包含的关键字个数小于 M,则插入操作完成。(注意还有一个横向的索引,途中没有)
例如,在图 1 的基础上插入关键字 95,其插入后的 B+树如图 3 所示:
在这里插入图片描述
图 3 插入95后的B+树

3、在第 2 情况中,如果上移操作导致其双亲结点中关键字个数大于 M,则应继续分裂其双亲结点。
例如,在图 1 的B+树中插入关键字 40,则插入后的 B+树如图 4 所示:
在这里插入图片描述
图 4 插入40后的B+树

注意:如果插入的关键字比当前结点中的最大值还大,破坏了B+树中从根结点到当前结点的所有索引值,此时需要及时修正后,再做其他操作。例如,在图 1 的 B+树种插入关键字 100,由于其值比 97 还大,插入之后,从根结点到该结点经过的所有结点中的所有值都要由 97 改为 100。改完之后再做分裂操作。

B+树的删除

在 B+树中删除关键字时,有以下几种情况:
1、 找到存储有该关键字所在的结点时,由于该结点中关键字个数大于⌈M/2⌉,做删除操作不会破坏 B+树,则可以直接删除。
例如,在图 1 所示的 B+树中删除关键字 91,删除后的 B+树如图 5 所示:
在这里插入图片描述
图 5 删除91的B+树
2、 当删除某结点中最大的关键字,就会涉及到更改其双亲结点一直到根结点中所有索引值的更改。
例如,在图 1的 B+树中删除关键字 97,删除后的 B+树如图 6 所示:
在这里插入图片描述
图 6 删除97后的B+树
3、 当删除该关键字,导致当前结点中关键字个数小于⌈M/2⌉,若其兄弟结点中含有多余的关键字,可以从兄弟结点中借关键字完成删除操作。
例如,在图 1 的 B+树中删除关键字 51,由于其兄弟结点中含有 3 个关键字,所以可以选择借一个关键字,同时修改双亲结点中的索引值,删除之后的 B+树如图 7 所示:

在这里插入图片描述
图 7 删除关键字51后的B+树

4、 第 3 种情况中,如果其兄弟结点没有多余的关键字,则需要同其兄弟结点进行合并。
例如,在图 7 的 B+树种删除关键字 59,删除后的 B+树为:
在这里插入图片描述
图 8 删除关键字59后的B+树

5、 当进行合并时,可能会产生因合并使其双亲结点破坏 B+树的结构,需要依照以上规律处理其双亲结点。
例如,在图 6 的 B+树中删除关键字 63,当删除后该结点中只剩关键字 72,且其兄弟结点中只有 2 个关键字,无法实现借的操作,只能进行合并。但是合并后,合并后的效果图如图 9 所示:
在这里插入图片描述
图 9 合并操作后的效果图

如图 9 所示,其双亲结点中只有一个关键字,而其兄弟结点中有 3 个关键字,所以可以通过借的操作,来满足 B+树的性质,最终的 B+树如图 10 所示:
在这里插入图片描述
图 10 删除63后的B+树
总之,在 B+树中做删除关键字的操作,采取如下的步骤:

  1. 删除该关键字,如果不破坏 B+树本身的性质,直接完成操作;
  2. 如果删除操作导致其该结点中最大(或最小)值改变,则应相应改动其父结点中的索引值;
  3. 在删除关键字后,如果导致其结点中关键字个数不足,有两种方法:一种是向兄弟结点去借,另外一种是同兄弟结点合并。(注意这两种方式有时需要更改其父结点中的索引值。)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值