应用于外存查找树的B-树分析

B-的引入

查找树中的二叉搜索树(二叉查找树)、及其延伸AVL树/伸展树等等都是当数据存储在内存中对应的搜索结构。当我们在内存数据中搜索的时候,用AVL树表示就可以获得很好的搜索性能了。但是,当数据量很大的时候,内存已经无法容纳了,我们就只好把数据存储在外存(如磁盘)中,这个时候由于磁盘读取数据非常耗时。磁盘的读写时间远远慢于内存访问的时间。如果我们可以减少磁盘存取操作的次数,那么就可以提高外搜索算法的性能。 我们必须使用一些外存数据结构来配合搜索算法,这样才能取得很好的性能。B树就是常用的一种外存数据结构。B-树不同于内存中查找树它可以不是二叉

B-的定义

一个m阶B-树要么是空树,要么是如下:

1每个节点包含关键字和指向子节点的指针;

2根节点要么是叶子,要么非叶子,非叶子时,节点里指向子节点数(分支数)范围2-m,关键字数目1-(m-1);

3除了根节点,其他非叶子节点,节点里指向子节点数(分支数)范围ceil(m/2)-m,关键字数目(ceil(m/2)-1)-(m-1);

4对于叶子节点,只有关键字,且关键字数目(ceil(m/2)-1)-(m-1);

5所有的非终端结点包含信息:(n,P0,K1,P1,K2,P2,……,Kn,Pn), 其中Ki为关键字,Pi为指向子树根结点的指针,并且Pi-1所指子树中的关键字均小于Ki,而Pi所指的关键字均大于Ki(i=1,2,……,n),n+1表示B-树的阶,n表示关键字个数,即[ceil(m / 2)-1]<= n <= m-1;

6所有叶子节点同一层

B-的高度和点数

根据B-树定义,第一层为根有一个结点,至少两个分支,第二层至少2个结点,i≥3时,令ceil(m/2)=a,可讨论:

i=3,至少2*a个节点

i=4,至少2*a*a个节点

i=5,至少2*a*a*a个节点

第i层则至少2*a^(i-2)个节点

设该树h层故最少含有节点树n=1+2+2*a+2*a*a+…+*a^(h-2)=2*a^(h-1)-1

对于一颗树h层,N个节点则N>=2*a^(h-1)-1,相反,若存在N个这样的节点要想层数最大,只需按照上面分析每层取最少个点数即可此时h=log(a)(N+1)/2+1

每一层至少有2乘以([m/2])的i-2次方个结点([m/2]表示取大于m/2的最小整数)。若m阶树中共有N个结点,那么可以推导出N必然满足N≥2*(([m/2])的h-1次方)-1 (h≥1),因此若查找成功,则高度h≤1+log[m/2](N+1)/2,h也是磁盘访问次数(h≥1),保证了查找算法的高效率。

B-的基本操作(插入和删除)

1 插入关键字k

首先需要找到插入的位置,如找到和k相同的关键字,则直接返回不用插入否则插入位置必然在叶子层某节点处,插入时只需考虑待插入的节点的关键字数目是否小于m-2:

若满足,直接插入,那么插入后数目也是满足不大于m-1的条件;

如不满足,需要分裂裂节点,把原结点上的关键字和k按升序排序后,从中间位置把关键字(不包括中间位置的关键字)分成两部分。左部分所含关键字放在旧结点中,右部分所含关键字放在新结点中,中间位置的关键字生成新结点的存储位置插入到父结点中。如果父结点的关键字个数也超过(m-1),则要再分裂,再往上插。直至这个过程传到根结点为止。

举例

关键字序列{1,2,6,7,11,4,8,13,10,5,17,9,16,20,3,12,14,18,19,15}创建一m=5的B-树

《应用于外存查找树的B-树分析》

2 删除关键字k

同插入类似,需要判断所找节点是否满足节点关键字树最小值条件即是否大于ceil(m/2)-1,且还需要关注该节点的左右兄弟

首先还是查找到关键字所在的节点,若没有则直接返回,若找到则:

一当该节点是非节点时,设带删除的关键字ki==k,则可从Pi所指子树里找出最小关键字Min以带低ki位置,然后再从叶子节点中删除Min,

二当该节点就是叶子节点时,故无论是否是否叶子节点,问题最后都是落在叶子节点的删除上。

在B-树叶结点上删除一个关键字的方法是:

首先将要删除的关键字 k直接从该叶子结点中删除。然后根据不同情况分别作相应的处理,共有三种可能情况:

情况a.如果被删关键字所在结点的原关键字个数n>=ceil(m/2),说明删去该关键字后该结点仍满足B-树的定义。这种情况最为简单,只需从该结点中直接删去关键字即可。

情况b.如果被删关键字所在结点的关键字个数n等于ceil(m/2)-1,说明删去该关键字后该结点将不满足B-树的定义,需要调整。调整过程为:

如果其左右兄弟结点中有“多余”的关键字,即与该结点相邻的右(左)兄弟结点中的关键字数目大于ceil(m/2)-1。则可将右(左)兄弟结点中最小(大)关键字上移至双亲结点。而将双亲结点中小(大)于该上移关键字的关键字下移至被删关键字所在结点中。

情况c.如果左右兄弟结点中没有“多余”的关键字,即与该结点相邻的右(左)兄弟结点中的关键字数目均等于ceil(m/2)-1。这种情况比较复杂。需把要删除关键字的结点与其左(或右)兄弟结点以及双亲结点中分割二者的关键字合并成一个结点,即在删除关键字后,该结点中剩余的关键字加指针,加上双亲结点中的关键字Ki一起,合并到Ai(即双亲结点指向该删除关键字结点的左(右)兄弟结点的指针)所指的兄弟结点中去。如果因此使双亲结点中关键字个数小于ceil(m/2)-1,则对此双亲结点做同样处理。以致于可能直到对根结点做这样的处理而使整个树减少一层。

总之,设所删关键字为非终端结点中的Ki,则可以指针Ai所指子树中的最小关键字Y代替Ki,然后在相应结点中删除Y。对任意关键字的删除都可以转化为对最下层关键字的删除。

举例

关键字序列{1,2,6,7,11,4,8,13,10,5,17,9,16,20,3,12,14,18,19,15}创建一m=5的B-树后如上图,再删除6,16,15,4

《应用于外存查找树的B-树分析》



    原文作者:B树
    原文地址: https://blog.csdn.net/yanerhao/article/details/53325864
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞

发表评论

电子邮件地址不会被公开。 必填项已用*标注