B树、B+树

了解B树之前,先要了解一下二叉查找树。

二叉查找树

众所周知,二叉查找树是每个节点最多由两个子树的树结构,而其还有一个特点是,在任意一颗树中,根节点的左孩子永远小于根节点,根节点的右孩子永远大于根节点,用二叉查找树作为索引,确实可以提高查找效率,其可以使用二分查找将时间复杂度控制在O(logn),但是二叉查找树有一个显而易见的缺陷,当某种特殊情况(按照某个特定顺序插入树)发生时,二叉查找树将变为下图右侧(线性二叉树)的状况:
在这里插入图片描述

此时二叉查找树不只是外观变得怪异了,在查找任意某个元素时,其查找顺序与逐行查找无异,查询时间复杂度又将回到O(n),查询效率无法保持。

怎么解决这个问题呢?这就涉及二叉树的自平衡了。二叉树自平衡的方式有很多种,如红黑树、AVL树、B树等。

B树原理

B-Tree,俗名:B树。它是一种平衡多路查找树(不是二路),先看下它的结构:
在这里插入图片描述

一颗m阶的B树特性如下:

  1. 根节点至少包含两个孩子

  2. 树中每个节点至多含有N个孩子(N>=2)

  3. 除根节点和叶节点外,其它每个节点至少有ceil(N/2)个孩子

  4. 拥有K个孩子的非叶子结点,含有K-1个键值

  5. 所有叶子节点都位于同一层,或者说根节点到每个叶子节点的长度都相同

  6. 假设每个非终端节点包含n个关键字信息(P0,P1…Pn,k1…kn),其中:

    1、ki(i=1…n)为关键字,且关键字按顺序升序排序k(i-1)<ki。
    2、关键字的个数必须满足:[ceil(m/2)-1]<=n<=m-1]。
    3、非叶子节点的指针:P[1],P[2]…P[M];其中P[1]指向关键字小于K[1]的子树,P[N]指向关键字大于K[N-1]的子树,其它P[i]指向关键字属于(K[i-1],K[i])的子树。

  7. 每个节点的关键字,都记录着对应的数据在磁盘中的位置,即数据在每个节点上。

  8. B树中所有节点的孩子节点数中的最大值称为B树的阶,记为M

举个例子,模拟一下查找过程,以便于理解:假设我们要查询关键字为10的数据,则从根节点出发,10<17,于是通过P1进入其孩子节点,10>8且10<12,于是通过P2进入其孩子节点,最后寻找到10。如果不使用索引,而使用逐行扫描的方式进行查找,则从0开始至少扫描10次才能查找到10号数据,有了索引之后可以看到,查找次数从10变为3,大大提高了查找效率。

如果这里是二叉查找树,会出现极端情况,使得查找时间复杂度为O(n),而如果是B-Tree,由于上述五个约束,可以让节点通过合并、分裂、上移、下移等操作,使得树高度较二叉查找树小,查找效率显然更高。

B+Tree原理

B+ -Tree是B-Tree的一个变体,其定义基本与B树相同,除了:

  1. 非叶子节点的子树指针与关键字个数相同,其表明B+树能存储更多的关键字
  2. 非叶子节点的子树指针P[i],指向关键字值[K[i],K[i+1])的子树。
  3. 非叶子节点仅用来做索引,数据到保存在叶子节点中。(B+树的所有检索都是从根部开始,直到搜索到叶子节点结束。)
  4. 所有叶子节点均有一个链指针,指向下一个叶子节点,树的所有叶结点构成一个有序链表,可以按照关键码排序的次序遍历全部记录。(方便直接在叶子节点直接做范围统计)
    在这里插入图片描述

B+树相较于B树的优势:

  • B+树的磁盘读写代价更低。

  • B+树的查询效率更加稳定。由于B+树在内部节点上不包含数据信息,因此在内存页中能够存放更多的key。 数据存放的更加紧密,具有更好的空间局部性。因此访问叶子节点上关联的数据也具有更好的缓存命中率。

  • B+树更有利于对数据库的扫描。B+树的叶子结点都是相链的,因此对整棵树的便利只需要一次线性遍历叶子结点即可。而且由于数据顺序排列并且相连,所以便于区间查找和搜索。而B树则需要进行每一层的递归遍历。相邻的元素可能在内存中不相邻,所以缓存命中性没有B+树好。

参考文章

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值