B树的定义
B树,又称为多路平衡查找树,B树中所有结点的孩子个数的最大值称为B树的阶,通常用m表示。一颗m阶B树或为空树,或为满足如下特性的m叉树:
1)树中每个结点至多有m颗子树,即最多含有m-1个关键字。
2)若根结点不是终端节点,则至少有两颗子树。
3)除根节点外的所有非叶结点至少有⌈m/2⌉颗子树,即至少含有⌈m/2⌉-1个关键字。
4)所有非叶结点的结构如下:
n | p0 | k1 | p1 | k2 | p2 | … | kn | pn |
---|
其中,ki为结点的关键字,且满足k1 < k2 < k3 < … < kn;pi为指向子树根结点的指针,且指针pi-1所指子树中所有结点的关键字均小于ki,pi所指子树中所有结点的关键字均大于ki,n(⌈m/2⌉-1 <= n <= m -1)为结点中关键字的个数。
【ki若是对应了value,则还需要将value考虑进去】
【B树的非叶结点中保存m-1个关键字,以及其所对应的记录的地址,保存m个指向子树/子结点的指针,保存一个整数n,即记录该节点中实际关键字个数的整数】
5)所有叶结点都出现在同一层次上,并且不带信息(可以视为外部结点或类似于折半查找判定树的查找失败结点,实际上这些结点不存在,指向这些结点的指针为空)。
B树的高度(磁盘存取次数)
对于一颗包含n个关键字、高度为h、阶数为m的B树:
1)因为B树中每个结点最多有m棵子树,m-1个关键字,所以在一颗高度为h的m阶B树中关键字的个数应满足n <= (m-1)(1 + m + m^2 + … + m^h-1) = m^h - 1,因此有:h >= logm(n+1)
2)若让每个结点中的关键字个数达到最少,则容纳同样多的关键字的B树的高度达到最大。由B树的定义:第一层至少有1个结点;第二层至少有两个结点;除了根结点外的每个非终端结点至少有⌈m/2⌉颗子树,则第三层至少有2⌈m/2⌉个结点,第h+1层至少有2⌈m/2⌉^(h-1)个结点,注意到第h+1层是不包含任何信息的叶子结点。
对于关键字个数为n的B树,叶结点即查找不成功的结点为n+1,由此有n+1 >= 2(⌈m/2⌉)^(h-1)
h <= log⌈m/2⌉((n+1)/2) + 1
例如,假设一颗3阶B树共有8个关键字,其高度范围为2 <= h <= 3.17
B树的查找
1)在B树中找结点
2)在结点内找关键字
由于B树常存储在磁盘上,因此前一个查找操作是在磁盘上进行的,而后一个查找操作是在内存中进行的,即在找到目标结点后,先将结点信息读入内存,然后在结点内采用顺序查找或折半查找法。查找到叶结点时(对应指针为空指针),则说明树中没有对应的关键字,查找失败。
B树的插入
1)定位。利用前述的B树查找算法,找出插入该关键字的最低层中的某个非叶结点。
2)插入。在B树中,每个非失败结点的关键字个数都在区间⌈m/2⌉-1到m-1内。插入后的结点关键字个数小于m,可以直接插入;插入后检查被插入结点内的关键字的个数,当插入后的结点关键字个数大于m-1时,必须对结点进行分裂。
分裂的方法:取一个新结点,在插入key后的原结点,从中间位置(⌈m/2⌉)将其中的关键字分为两部分,左部分包含的关键字放在原结点中,右部分包含的关键字放在新结点中,中间位置(⌈m/2⌉)的结点插入原结点的父结点。若此时导致其父结点的关键字个数也超过了上限,则继续进行这种分裂操作,直至这个过程传到根节点为止,进而导致B树高度增1。
B树的删除
当被删除关键字k不在终端结点(最低层非叶结点)中时,可以用k的前驱(或后继)k’来代替k,然后在相应的结点中删除k’,关键字k’必定落在某个终端结点中,则转换成了被删关键字在终端结点中的情形。因此只需讨论删除终端结点中关键字的情形。
当被删关键字在终端节点中时,有下列三种情况:
1)直接删除关键字。若被删除关键字所在结点的关键字个数 ≥ ⌈m/2⌉,表明删除该关键字后仍满足B树的定义,则直接删去该关键字。
2)兄弟够借。若被删除关键字所在结点删除前的关键字个数 = ⌈m/2⌉-1,且与此结点相邻的右(或左)兄弟结点的关键字个数 >= ⌈m/2⌉,则需要调整该结点、右(或左)兄弟结点、及其双亲结点(父子换位法),以达到新的平衡。
3)兄弟不够借。若兄弟不够借时,就将该结点删除,删除完后将兄弟结点和双亲结点进行合并。在合并过程中,双亲结点中的关键字个数会减1。若其双亲结点是根结点且关键字个数减少至0,则直接将根节点删除,合并后的新结点成为根;若双亲结点不是根节点,且关键字个数减少到⌈m/2⌉-2,则又要与它自己的兄弟结点进行调整或合并操作。
B+树的定义
一颗m阶的B+树需满足下列条件:
1)每个分支结点最多有m棵子树(孩子节点)。
2)非叶根节点至少有两棵子树,其他每个分支结点至少有⌈m/2⌉棵子树。
3)结点的子树个数与关键字个数相等
4)所有叶结点包含全部关键字及指向相应记录的指针,叶结点中将关键字按大小顺序排列,并且相邻叶结点按大小顺序相互链接起来。
5)所有分支结点(可以视为索引的索引)中仅包含它的各个子结点(即下一级索引块)中关键字的最大值及指向其子结点的指针。
B+树和B树的差异
1)在B+树中,具有n个关键字的结点含有n棵子树;而在B树中,具有n个关键字的结点至少含有n+1棵子树。
2)在B+树中,每个结点(除根节点外)中的关键字个数n的取值范围为⌈m/2⌉ <= n <= m 。根结点n的取值范围为2 <= n <= m。而在B树中,除根节点外,其他所有非叶子结点的关键字个数n的取值范围是⌈m/2⌉-1 <= n <= m -1,根结点n的取值范围是1 <= n <= m - 1。
3)在B+树中,所有叶子结点包含了全部关键字,即其他非叶子结点中的关键字也包含在叶子结点中;而在B树中,关键字是不重复的。
4)在B+树中,所有非叶子结点仅仅起到了索引的作用,即结点中的每个索引项只包含对应子树的最大关键字和指向子树的指针,不包含该关键字对应记录的存储地址;而在B树中,每个关键字对应一个记录的存储地址。
5)在B+树中有两个头指针,一个指向根节点,另一个指向关键字最小的叶子结点,所有叶子结点链接成一个链表;而在B树中,叶子节点并不会有指针相连。