目录
B树的性质、定义
B树即多路平衡查找树,不同于平衡二叉树仅有两路,B树中的所有结点至多有m路即B树中所有结点的子树个数(孩子个数)最大为m,m称为该B树的阶,m阶B树要么是空树,要么需要满足如下特征:
- B树中所有结点的子树高度相同(平衡二叉树则规定左右子树高度差最大为1)
- 若根节点不为终端结点则至少有两颗子树
- 除根节点外所有的非叶结点至少有m/2-1个关键字即至少有m/2颗子树(分叉)
- 所有叶结点均在同一层(叶结点为失败结点,实际不存在,而含实际数据的最下层结点称为终端结点)
- 所有关键字左侧的子树值均小于该关键字,右侧的子树值均大于该关键字
B树的高度范围
求有n个关键字的m阶B树最小高度即让每层尽可能的满,即每个结点均有m个子树,有m-1个关键字,设其高度为h即n<=(1+m+m^2+.....+m^(h-1))(m-1),则h>=logm(n+1)。
求有n个关键字的m阶B树最大高度即让每层尽可能的少,即除根节点只有一个关键字,两个子树外,每个结点均有m/2个子树,m/2-1个关键字,令k=m/2,设其高度为h,第一层有1个关键字2颗子树,第二层有2(k-1)个关键字,2k颗子树,第三层有2k(k-1)个关键字,有2k^2颗子树,即第h层有2k^(h-2)(k-1)个关键字。即n>=1+2(k-1)(1+k+....+k^(h-2)),即h<=logk((n+1)/2)+1。
B树的插入
对于m阶B树的插入,每次都在其终端结点对其关键字进行对比插入,在插入key后,如果当前结点的关键字个数超过最大个数m-1则需要从中间位置[m/2]处将其关键字分为两部分,左部分包含的关键字放在原结点中,右部分的关键字则放入新结点,中间位置的[m/2]处的关键字插入原结点的父结点中即可,如果父结点关键字也超过上限则继续进行此种分裂操作即可,直至到根结点。
B树的删除
对于m阶B树的删除,如果删除关键字在终端结点则直接删除即可,如果删除的关键字在非终端结点则调整方式同二叉排序树的删除,找删除关键字的直接前驱(左侧子树的最右下关键字)或者直接后继(右侧子树的最左下关键字)代替即可。以上为删除后不低于每个结点的最小关键字个数m/2-1的情况,如果删除后当前结点关键字个数不足m/2-1,则需要如下调整(保证B树特性):
- 如果删除结点的右兄弟结点关键字较充足,则用被删除结点的后继以及后继的后继来填补空缺
- 如果删除结点的左兄弟结点关键字较充足,则用被删除结点的前驱以及前驱的前驱来填补空缺
- 如果左右兄弟结点都不充足且相邻的左右兄弟结点的关键字个数均为m/2-1则将当前结点与其左兄弟或者右兄弟结点以及夹在中间的双亲结点的关键字进行合并即可,若双亲结点为根结点且关键字减少为0,则需要删除根结点,合并后的结点作为新的根结点,如果不为根结点,则需要判断此时是否符合B树的要求,不符合则分情况继续做上述调整直至符合B树要求
拓展:B+树
在B+树中,最底层的结点为叶子节点,是实际存在的,其余的结点称为分支节点,此处不同于B树的叶结点(失败结点)是不实际存在的,m阶B+树需要满足以下条件:
- 每个分支结点最多有m颗子树(即有m个孩子)
- 每个结点的关键字个数和子树个数保持一致(B树中关键字个数为子树个数-1)
- 非叶子结点的根结点至少有两颗子树,而其他的分支结点至少有m/2颗子树、m/2个关键字
- 所有叶子结点包含全部的关键字以及指向相应记录的指针,叶子结点中将关键字按照大小排序,并且相邻的叶子结点按大小顺序互相链接起来
- 所有分支结点中仅包含它的各个子结点中关键字的最大值以及指向其子结点的指针(类似于分块查找中的索引表),分支结点仅仅起到索引的作用
在B+树中因为记录的地址均存放在叶子结点中,所以查找必须要查找到叶子结点,在分支结点中如果找到了还需要向下直至叶子结点。