关于B树的思考:m阶B树的非根非叶节点为什么要至少为ceil(m/2)个孩子?

B树(B-tree)本质上是一种针对外存储器设备设计的多路平衡查找树,该数据结构及其扩展结构(B+树,B*树等)被广泛应用于文件系统,数据库索引等。

B树最早出现于德国教授Rudolf Bayer等人的经典论文:Rudolf Bayer, Edward M. McCreight. Organization and maintenance of large ordered indexes[J]. Acta Informatica, 1972,18(1):173-189. (原文地址见Springer)

m阶B树的定义如下:

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

2. 树中每个节点最多含有m个孩子(m>=2);

3. 除根节点和叶节点外,其他每个节点至少有ceil(m/2)个孩子(ceil()为向上取整);

4. 所有叶子节点都位于同一层;

5. 每个非叶节点包括n个关键字信息,其中ceil(m/2)-1<=n<=m-1。


在学习和实现B树的过程中,关于B树的第三条定义,我产生了一些疑问和想法:

针对一棵符合定义的m阶B树,则每个节点孩子树M的取值范围为ceil(m/2)<=M<=m且m>=2;即m阶B树可以不存在满足m个孩子的节点,但M必须在这个范围内。

由M可得到,n=M-1,即ceil(m/2)-1<=n<=m-1;

那么,m阶B树的非根非叶节点的下界为什么要至少为ceil(m/2)个孩子?


首先,先来复习一下B树的平衡过程。

如下图,一棵5阶B树,即树中最多含有m=5个孩子,关键字的范围为[2,4],接下来依次删除关键字R和E。

关于B树的思考:m阶B树的非根非叶节点为什么要至少为ceil(m/2)个孩子?_第1张图片

删除R:R在叶子结点中,但是该结点中元素数目为2,删除导致只有1个元素,已经小于最小元素数目ceil(5/2)-1=2,而由前面我们已经知道:如果其某个相邻兄弟结点中比较丰满(元素个数大于ceil(5/2)-1=2),则可以向父结点借一个元素,然后将最丰满的相邻兄弟结点中上移最后或最前一个元素到父节点中,在这个实例中,右相邻兄弟结点中比较丰满(3个元素大于2),所以先向父节点借一个元素W下移到该叶子结点中,代替原来S的位置,S前移;然后X在相邻右兄弟结点中上移到父结点中,最后在相邻右兄弟结点中删除X,后面元素前移。

关于B树的思考:m阶B树的非根非叶节点为什么要至少为ceil(m/2)个孩子?_第2张图片

删除E:直接删除E后会导致很多问题,因为E所在的结点数目刚好达标,刚好满足最小元素个数(ceil(5/2)-1=2),而相邻的兄弟结点也是同样的情况,删除一个元素都不能满足条件,所以需要该节点与某相邻兄弟结点进行合并操作;首先移动父结点中的元素(该元素在两个需要合并的两个结点元素之间)下移到其子结点中,然后将这两个结点进行合并成一个结点。所以在该实例中,咱们首先将父节点中的元素D下移到已经删除E而只有F的结点中,然后将含有D和F的结点和含有A,C的相邻兄弟结点进行合并成一个结点。

关于B树的思考:m阶B树的非根非叶节点为什么要至少为ceil(m/2)个孩子?_第3张图片

此时,发现父节点只包含一个元素G,没达标(因为非根节点包括叶子结点的关键字数n必须满足于2=

关于B树的思考:m阶B树的非根非叶节点为什么要至少为ceil(m/2)个孩子?_第4张图片


通过上面例子中B树删除关键字的过程,针对B树定义中的非根非叶节点孩子数下界至少为ceil(m/2),有反证法分析如下。

反证法:

对于非根非叶节点,假如存在节点孩子树小于ceil(m/2),即该节点关键数小于ceil(m/2)-1。

情况一,兄弟节点关键数数量大于ceil(m/2)-1,即兄弟节点减少一个关键数后仍满足n>=ceil(m/2)-1,则该节点可以向邻近兄弟节点“借”一个关键数转化为他俩的新父节点,原父节点下移至该节点的最右边,依次类推。

情况二,兄弟节点关键数n=ceil(m/2)-1,此时不能再想兄弟借,则,从将父节点中位于兄弟俩中间的数下移,同时将该节点,下一的父节点中间数,以及兄弟节点进行合并。此时可知,合并后的关键数n<=m-1。证明略。


通过情况一和情况二的若干次转换,可消除关键数小于ceil(m/2)的非根非叶节点。所以关键数小于ceil(m/2)的非根非叶节点在平衡过程中势必可以合并消除,即一棵标准的B树应该满足此平衡状态。

因为B树是针对外存储器设计的多路查找结构,而一次外存储器IO操作的时间代价要比主存储器读写高出上万倍,降低一棵B树的层数减少一层,就是在减少一次外存储器的IO操作。所以说此种平衡限制是为了最大限度降低层高,提高搜索效率。


继续思考:

求m阶B树的最大高度?高度最高时,B树的节点树达到最小,及ceil(m/2),可得h_(max)=log_ceil(m/2)N。

反之,当知道高为h的m阶B树,此时少节点数应为

1+2+2*ceil(m/2)+2*ceil(m/2)*ceil(m/2)+....+2*(ceil(m/2))^(h-1)

=[2(1-ceil(m/2)^(h-1))/(1-ceil(m/2))]+1。


参考资料:

http://blog.csdn.net/v_JULY_v/article/details/6530142/

你可能感兴趣的:(数据结构与算法)