B/B+树

B/B+树

在之前的数据库索引的文章里面,提到了一个数据结构,B树和B+树,这两天看面试题的时候,发现B树,B+树,红黑树很常见,所以就查了一下

本文内容
  1. B树
  2. B+树
B树

B树,有些地方也写成B-tree(B-树),可不是读作“B减树”,中间的横杠是连接符,B-树就是B树

在数据库索引里面讲了,索引的数据结构就是B/B+树,而B+树可以说是B树的一个升级,所以先得介绍清楚B树

我们都知道,树结构做查询操作是很快的,效率很高,而且有序,最基础的就是二叉查找树,我们来对比着说,先来一个二叉查找树
在这里插入图片描述
那么我们现在要查找9这个元素,步骤是8–>12–>10–>9,假设这棵树就是数据库的索引,索引存储在磁盘上,那么我们就需要进行四次IO操作才可以找到我们需要的数据,这里就可以发现,在最坏的情况下,我们需要的IO操作的次数就是这棵树的高度,所以,在大量数据的情况下,这个树会变得很“高”,为了方便查询的快,我们要把这个树变“矮”,这就是B树的特征之一

一个m阶的B树具有如下特征:

  1. 根结点至少有两个子女。
  2. 每个中间节点都包含k-1个元素和k个孩子,其中 m/2 <= k <= m
  3. 每一个叶子节点都包含k-1个元素,其中 m/2 <= k <= m
  4. 所有的叶子结点都位于同一层。
  5. 每个节点中的元素从小到大排列,节点当中k-1个元素正好是k个孩子包含的元素的值域分划。

下面来把上面那棵树转换成B树
在这里插入图片描述
按照上面的规则检验,根结点有两个孩子,m=3,1<=k<=3,所以中间节点包含三个孩子,自己有两个元素,每个叶子节点都包含一到两个元素,所有叶子节点都在第三层,节点中的元素从小到大排列,1满足小于2,3和4都满足大于2小于5,6和7都满足大于5,右边的同理,所以这是一个B树

对比二叉查找树来说,同样的元素,同样最坏的情况也是IO操作次数是树的高度,但是B树比二叉查找树要“矮”的多,对应的IO操作也会少的多,所以查询效率也会高得多

下面说一下B树的增加和删除操作
在这里插入图片描述
假设我们要把4这个元素插入到这个树,本来应该放在3和5的中间,但是该节点已经有两个元素,所以往上看父节点,父节点也是两个元素,再往上看,根结点只有一个元素8,所以把4插到根结点,然后调整这棵树,就变成了这样
在这里插入图片描述
可以看到,由于数据的插入,导致了一些节点的拆分,看起来很麻烦,但是也让B树能够维持多路平衡,这也是B树的特点之一,自平衡

现在在这个基础上,删除15这个元素,这时候(11,14)这个节点孩子少了一个,不符合B树的规范,所以需要进行调整,就变成了
在这里插入图片描述
这个过程叫做“左旋”,这个在下一篇博客写红黑树的时候再说

这个增加和删除操作可能有点绕,变换规则就是围绕上面说的那五点特征,所以没看懂的自己拿笔画两下

B树主要用于文件系统以及部分数据库索引,比如MongoDB,所以还是蛮重要的一个数据结构

B+树

B+树是B树的一个升级,比B树有更高的查询效率,先来说一下B+树的特点,B+树除了有B树的特点,还具有以下特点

一个m阶的B+树具有如下特征:

  1. 有k个子树的中间节点包含有k个元素(B树中是k-1个元素),每个元素不保存数据,只用来索引,所有数据都保存在叶子节点。
  2. 所有的叶子结点中包含了全部元素的信息,及指向含这些元素记录的指针,且叶子结点本身依关键字的大小自小而大顺序链接。
  3. 所有的中间节点元素都同时存在于子节点,在子节点元素中是最大(或最小)元素。

文字居多,可能不容易理解,那就直接把上面的二叉查找树转换成B+树来解释
在这里插入图片描述
来一点一点解释,这是一个三阶的B+树,所以m=3,1<=k<=3,所以叶子节点的元素个数不超过两个,在B+树中的中间节点是有几个孩子就有几个元素,所以有三个孩子有三个元素,在B+树中所有信息保存在叶子节点,所有的中间节点元素都同时存在于子节点,在子节点元素中是最大(或最小)元素,所有的叶子结点中包含了全部元素的信息,及指向含这些元素记录的指针,这几句话实际上就是说,中间的数据作为索引,真的数据全部在叶子节点,从图中可以看出来,中间节点的每一个元素都存在于他们的孩子,并且是孩子节点的元素的最大值,但是真实查找还是的找叶子节点的元素,打个比方,我们要找6这个数据,在根结点就找到了6,但是还得继续向下,找他的左边第一个孩子,(2,4,6)也有6,不是叶子节点,再接着往下找最右边的孩子,(5,6),是叶子节点,这里的6才是我们要找的6

然后所有的叶子节点都有一个指向下一个叶子节点的指针,形成了一个有序链表

这里要说一个概念,卫星数据,画个图来说
在这里插入图片描述
就是每个节点,都可以带有一个卫星数据,比如说这棵树是一个数据库索引,那么卫星数据就可以是数据库中的某一行,这个卫星数据的位置也是B+树的特点之一,在B树里面,不管是中间节点还是叶子节点都带有卫星数据,但是在B+树中只有叶子节点才带有卫星数据,中间节点仅仅只是叶子节点的索引(在数据库的聚集索引中,叶子节点直接包含卫星数据。在非聚集索引中,叶子节点带有指向卫星数据的指针)

前面说这么多,好像看起来很麻烦,也没比B树好到哪去,下面来说一下B+树比B树的优点

首先是单条数据查询,在B树,中间节点也是数据,比如我们要找6,在哪找到了,那就在哪结束了,但是在B+树里面必须要找到叶子节点才算结束,似乎是麻烦了一点,但实际上是方便了很多,B+树的中间节点没有卫星数据,中间节点只是叶子节点的索引,所以在相同数据量的情况下,B+树会比B树要更“矮”,对应的IO操作要更少,这是第一点,其次B树的查询效率是不稳定的,最好的情况是在根结点一次查询,最坏的情况是要找到根结点,而B+树是什么情况都要找到叶子节点

再说一下范围查询,这就是B+树把叶子节点用指针连起来的好处,在B树上要查询一个范围的数据,比如要查3到8中间的所有数据,B树就需要做几次遍历,而B+树就可以直接找到3,然后从叶子节点的有序链表直接遍历到8,很明显要快很多

B+树的增加和删除操作都和B树差不多,所以就不多说了

所以总结一下B+树对比B树的优点:

  • B+树的单一节点可以存储更多元素,使得查询的IO次数更少。
  • B+树所有查询都要查找到叶子节点,查询性能稳定。
  • B+树所有叶子节点形成有序链表,便于范围查询。

B+树更多的用于数据库索引,比如MySQL的索引就是用的B+树,所以掌握这个数据结构很重要,面试基本上都会问到

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值