《深刻浅出话数据结构》系列之什么是B树、B+树?为何二叉查找树不行?

本文将为你们介绍B树和B+树,首先介绍了B树的应用场景,为何须要B树;而后介绍了B树的查询和插入过程;最后谈了B+树针对B树的改进。
在谈B树以前,先说一下B树所针对的应用场景。那么B树是用来作什么的呢? B树是一种为辅助存储设计的一种数据结构,广泛运用在数据库和文件系统中。举个例子来讲,数据库你们确定都不陌生,好比如今有一张表,其中有100万条记录,如今要查找查找其中的某条数据,如何快速地从100万条记录中找到须要的那条记录呢?你们的第一反应确定是二叉查找树,下面先谈谈为何二叉树不行。算法

为何二叉查找树不行

仍是刚刚那个例子,如今一张表中有100万条记录,咱们以表的主键来构建一个二叉查找树。先不考虑二叉树不平衡退化成链表的状况,假设是理想状况,这个二叉树是彻底平衡的。那么构建完成以后应该是下面这个样子的(示意图)
二叉查找树
树的高度应该为

如今开始查找,加入咱们要查找值为100的节点,怎么找呢?首先应该获取树的根节点。通常来讲,表的索引自己也很大,不可能所有存储在内存中,所以索引每每以索引文件的形式存储的磁盘上。也就是说咱们构建的二叉查找树太大了,内存放不下,通常要存在磁盘上,用的时候再从磁盘读入到内存。如今假设咱们知道了根节点所在的磁盘位置,那么应该首先将根节点读入内存中,这里进行了一次IO操做,而后判断要找的值比根节点大仍是小,100比4大,因此去右子树查找。那么如何找到6所在的节点呢?根节点中存储着6所在节点在磁盘上存放的位置。一样,须要将其先读入内存中,而后再判断继续向下查找,这里又是一次IO操做。下面的过程相似,再也不展开。总结一下,查找到咱们所需的那条记录大概须要进行20次IO操做,也就是树的高度,由于每向下查找一层,就要进行一次IO操做。
为何要强调IO操做,而不是在内存中比较的次数呢? 由于磁盘的速度相比内存而言是很是的慢。好比常见的7200RPM的硬盘,摇臂转一圈须要60/7200≈8.33ms,换句话说,让磁盘完整的旋转一圈找到所须要的数据须要8.33ms,这比内存常见的100ns慢100000倍左右,这还不包括移动摇臂的时间。因此在这里制约查找速度的不是比较次数,而是IO操做的次数。换句话说,若是可以减小一次IO操做,那么多在内存中比较100次也无所谓,由于两者的速度相差100000倍。而咱们能够认为IO操做的次数就大约等于树的高度,树的高度是如何计算的呢?看一下这个公式

咱们想让这个值尽量的小,就只能让真数小,或者底数大。真数是数据记录的条数,不是咱们能决定的。那么底数呢?这个2来自哪呢?固然是来自二叉树中的那个二。那么这个底数能不能变大呢?固然能!!!那就是不要用二叉树,而要用多叉树,这就是咱们要说的B树了。数据库

B树是什么

B树也称B-树,它是一颗多路平衡查找树。B树和后面讲到的B+树都是从最简单的二叉树变换而来的。描述一颗B树时须要指定它的阶数,阶数表示了一个节点最多有多少个孩子节点,通常用字母m表示阶数。下面咱们来看看B树的定义
(1)树中每一个节点至多有m 棵子树(m指的是树的阶);
解释:有的定义说的是每一个节点最多有m-1个关键字,是同样的,对于每一个节点来讲子树的数目等于关键字数目加1,下面会举例说明。
(2)若根结点不是叶子结点,则至少有两棵子树;
解释:当根节点为叶子节点时,能够没有子树;不为叶子节点时,至少有一个关键字,也就是至少有两棵子树。
(3)除根结点以外的全部非叶子结点至少有⌈m/2⌉个子节点;
解释:⌈m/2⌉表示向上取整,好比m=5时,⌈m/2⌉=3,表示至少有3个子节点,固然最多有5个。
(4)全部的非叶子结点中包含如下数据:(n,A0,K1,A1,K2,…,Kn,An)
解释:n为节点中关键字的数目,Ki(i=1,2,…,n)为关键字,且Ki<Ki+1编程

Ai 为指向孩子节点的指针(i=0,1,…,n),且指针Ai-1 所指子树中全部结点的关键字均小于Ki (i=1,2,…,n),An 所指子树中全部结点的关键字均大于Kn。(这里也能够看到对于每一个节点来讲子节点数量比关键字数量多1)

(5)全部的叶子结点都出如今同一层次上,即全部叶节点具备相同的深度,等于树高度。叶子节点除了包含了关键字和关键字记录的指针外也有指向其子节点的指针只不过其指针地址都为null。
下面具体举个例子说明,相信看了这个例子会对上面的定义有更加深入的理解。
4阶B树示例缓存

B树的查找

以上图为例,假设要查找15的节点,查找流程以下
(1)获取根节点的关键字进行比较,当前根节点关键字为50,50>15,因此找到指向左边的子节点;
(2)拿到关键字10和30,10<15<30 因此直接找到10和30中间的指针指向的子节点;
(3)拿到关键字15,就是要查找的目标值, 因此直接返回关键字和指针信息(若是树结构里面没有包含所要查找的节点则返回null)
至此咱们便完成了B树的查找过程,比较简单,且与二叉查找树相似。
关于B树的插入操做,能够参考【为何有红黑树?什么是红黑树?看完这篇你就明白了】这篇推文中关于2-3树的插入操做的详细介绍,其实2-3树就是一种特殊的B树。限于篇幅,本文再也不赘述。安全

从B树到B+树

B+树是从B树衍生而来的,比B树更具备优越性。B+树相对于B树主要作了两点改进:
(1)非叶结点仅具备索引做用,跟记录有关的信息均存放在叶结点中。
解释:B+树的非叶子节点不保存关键字记录的指针,只进行数据索引;B+树叶子节点保存了父节点的全部关键字记录的指针,全部数据地址必需要到叶子节点才能获取到。仍是举刚才B树的例子,B树中根节点的关键字为50。假如咱们就要查找主键为50的记录,那么在B树中只需进行一次IO操做,将根节点读入内存,即可以直接命中。而在B+树中则不一样,B+树中任何查询必需要到叶子节点才能获取到,因此每次数据查询的次数都同样,这一点和B树有很大区别。
(2)树的全部叶节点构成一个有序链表,能够按照关键字排序的次序遍历所有记录。
解释:这样作有两点好处。一是进行范围查询更快,数据紧密性很高,缓存的命中率也会比B树高。二是B+树全节点遍历更快,B+树遍历整棵树只须要遍历全部的叶子节点便可,而不须要像B树同样须要对每一层进行遍历,这有利于数据库作全表扫描。
推荐阅读
为何有红黑树?什么是红黑树?看完这篇你就明白了
都2020年了,据说你还不会归并排序?手把手教你手写归并排序算法
为何会有多线程?什么是线程安全?如何保证线程安全?数据结构

以为文章有用的话, 点赞+ 关注呗,好让更多的人看到这篇文章,也激励博主写出更多的好文章。
更多关于 算法、数据结构和计算机基础知识的内容,欢迎扫码关注个人原创公众号「 超悦编程」。

超悦编程

相关文章
相关标签/搜索