计算机基础数据结构讲解第三篇-B树和B+树
这一小节将介绍B树和B+树的内容。
一:B树
1.介绍
B树又称多路平衡查找树,所有结点的平衡因子均等于0,所有孩子结点的最大值成为B树的阶,用m表示。一颗m阶B树或为空树,或者满足:
(1)树中每个结点至多有m棵子树,至多有m-1个关键字。
(2)若根结点不是终端结点,则至少有两棵子树。
(3)除根结点外的所有非叶结点至少有m/2棵子树(取整数最大值)至少有m/2-1个关键字(取整数最大值).
(4)所有叶结点不带信息,实际上这些结点并不存在,指向这些结点的指针为空。
2.B树的结构
B树的结构举例如下:
3.B树的性质
(1)结点的孩子个数=改结点的关键字个数+1。
(2)如果根节点有关键字,则其子树不然大于等于两棵。
(3)除根结点外所有非叶结点至少有m/2(取整数最大值)子树,至少有m/2-1(取整数最大值)关键字;至多有m棵子树,至多有m-1个关键字。 这里m/2等同于Math.ceil(m/2),即取上线的整数值。
(4)结点的下层结点关键字落在上层结点关键字所划分的区间内。
(5)所有叶结点均在最后一层,代表查找失败的位置。
4.B树的高度
要明确的是B树的高度不包括最后的不带任何信息的叶结点所处的那一层。
对于任意一颗包括n个关键字,高度为h,阶数为m的B树:
(1)因为B树中每个结点最多有m棵子树,m-1个关键字,所以在一颗高度为h的m阶B树中关键字的个数满足n <= (m-1)(1+m+m2+...+m(h-1))。
(2)若让每个结点的关键字个数达到最小,则容纳同样多关键字的B树的高度达到最大。由B树的定义,第一层至少有1个结点,第二层至少有2个结点,除根结点外的每个非终端结点至少有m/2(取最大值)棵子树,则第h+层至少有2*(m/2)^(h-1)个结点。
对于关键字个数为n的B树,查找不成功的结点个数为n+,因此有n+1>=2(m/2)^(h-1)。
综上计算出B树的高度范围为:
logm(n+1)<= h <=log(ceil(m/2)) (n+1)/2 + 1
5.B树的查找
在B树上进行查找与二叉查找树很相似,只是不同的是每个结点都是多个关键字的有序表,在每个结点上都有多个子树的多路分支。
B树的查找包含两个基本操作:在B树上找结点;在结点内找关键字。前一个操作是在磁盘上进行的,后一个操作是在内存中进行的。
查找时现在有序表中进行查找,查找不成功时到所指的子树中去查找,查找到叶结点时(对应指针为空指针),则说明树中没有对应的关键字,查找失败。
6.B树的插入
B树的插入比二叉查找树复杂。在二叉查找树中,仅需查找到需要插入的终端结点的位置。但是,在B树中找到插入位置的时候,直接插入可能会导致整个树不再满足B树定义的要求。将关键字key插入B树的过程如下:
定位:先利用B树查找算法。找到插入该关键字的最低层的某个非叶结点,插入位置一定是最低层中的某个非叶结点。
插入:如果插入后的结点关键字个数少于m个,可以直接插入,当插入后的结点关键字个数大于m-1,即大于子树个数+1的话,就不符合规定了,必须对结点进行分裂。
分裂的方法是:取一个新结点,在插入关键字的原结点,以结点中间的key为中心分裂成左右两部分,然后将这个中间的key插入到父结点中,这个key的左子树指向分裂后的左半部分,这个key的右子支指向分裂后的右半部分,然后将当前结点指向父结点。若此时导致其父结点的关键字个数也超过了上线,则继续。
7.B树的删除
B树的删除操作要复杂一些,要使得删除后的关键字个数大于等于(m/2)-1,这里(m/2)-1等同于Math.ceil(m/2)-1,需要进行合并。
因为B树的删除操作和插入操作比较复杂,下一篇讲具体来讲B树的插入和删除和他们算法实现的细节。
二:B+树
B+树是针对数据库需求而出现的一种B树的变形树。
B+树最重要的特点是 关键字个数和孩子结点个数相同。如果关键字个数比孩子结点个数小1,就会变成一棵B树。
B+树还满足下列条件:
(1)每个分支结点最多有m棵子树。
(2)非叶根节点至少有两棵子树,其他分支结点至少有Math.ceil(m/2)-1棵子树(和B树一样)。
(3)所有叶结点包含全部的关键字及指向相应记录的指针,并将关键字按大小顺序排列,相邻叶结点按大小顺序链接起来,非叶结点的关键字也会出现在叶结点中。
(4)所有分支中仅包含它的各个子结点中关键字的最大值及指向其子结点的指针。
(5)B+树子树和关键字大小范围都和B树子树范围一样,为[Math.ceil(m/2)-1,Math.ceil(m/2)]。
B+树与B树最大的不同是非叶结点不保存数据,只用于索引,不含有关键字对应记录的存储地址。所有数据(或者说记录)都保存在叶子结点中 。
指向B树的指针有两个,一个指向根结点,另一个指向关键字最小的叶结点。因此对B树有两种查找运算,一种是从关键字开始的顺序查找,另一种是从根结点开始的多路查找。当找到非叶节点的关键字等于给定值时并不终止,继续向下查找,直到找到叶结点上的该关键字为止。
所以无论查找成功与否,每次查找都是一条从根结点到叶结点的路径。
B+树的结构例子如下: