树形索引(B-树查找、插入、删除)

一、B-树定义

B-树上每个节点包含多个关键码从小到大排序,是一种平衡的多路查找树。最底层节点称为外节点或叶结点,一般可省略。除了外结点,B-树上的节点还有终端结点(叶结点的上一层)和非终端结点(终端结点层以上的结点)。

一颗m阶B-树,或为空树,或为满足下列特性的m叉树:

(1)树中每个结点最多有m颗子树

(2)若根节点不是空节点(或根节点不是叶结点),子树个数2~m

(3)除根节点和外节点之外的每个结点,子树个数[m/2](向上取整)~m

(4)除外结点之外的每个结点中都包含下列信息数据:(n,A0,K1,A1,K2,A2,…,Kn,An),n为结点中关键码的个数,Ki为关键码,i=1,2…,n,且Ki<K(i+1),i=1,2,…,n-1。

若该节点为根节点,则1<=n<=m-1,否则,[m/2]向上取整<=n<=m-1。若该结点为终端节点,则Ai,i=0,1,…,n为指向外结点的指针,即空指针。若该结点为根或非终端结点,则Ai为指向子树根节点的指针,指针Ai-1所指子树中所有结点的关键码均小于Ki,指针Ai所指子树中所有节点的关键码均大于Ki。

(5)所有外结点都出现在同一层次上,并且不带信息。

根节点关键字个数 1~m-1(根非叶子),非根结点关键字个数 m/2向上取整-1~m-1

二、B-树的查找

(1)在B-树中找结点

(2)在节点中找关键码

B-树通常存在磁盘上,则前一查找操作是在磁盘上进行的,后一查找操作在内存中进行,,即在磁盘上找到指针p所指结点后,先将结点中信息读入内存,然后,再利用顺序查找或二分查找查询等于K的关键码。显然,在磁盘上进行一次查找比在内存上进行一次查找耗时,故,在磁盘上进行查找的次数,即待查关键码所在结点在B-树的层次数,是决定B-树查找效率的首要因素

[m/2]为向上取整。讨论深度为l+1的m阶B-树所具有的最少结点数。

第一层至少有1个结点,第二层至少有2个结点,由于除根结点外每个非叶结点至少有[m/2]颗子树,则第三层至少有2[m/2]个结点,第四层至少有2[m/2]^2个结点,….,以此类推,第l+1层至少有2[m/2]^(l-1)个结点,而l+1层为外结点。若m阶B-树有n个关键码,则外结点即查找不成功的节点数位n+1,故

n+1>=2([m/2])^(l-1),l<=log[m/2](n+1)/2+1。在含有n个结点的B-树上查找时,从根节点到关键码所在结点的路径上结点数不超过

l=log[m/2](n+1)/2+1,这就是n个关键码m阶B-树实际最大深度。

三、B-树的插入

首先在某个终端结点中插入一个关键码,若该结点关键码个数<=m-1,插入完成,若超过m-1,即插入后结点中关键码个数为m时,则要对该结点进行分裂操作,使得结点中关键码个数满足[m/2]-1<=n<=m-1。

a.利用前述的B-树的查找算法查找关键字的插入位置。若找到,则说明该关键字已经存在,直接返回。否则查找操作必失败于某个最低层的终端结点上。

b.判断该结点是否还有空位置。即判断该结点的关键字总数满足n<m-1,则直接把关键字k插入到该结点的合适位置上。若不满足,说明该结点己没有空位置,需要把结点分裂成两个。

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

以3阶B-树为例:

《树形索引(B-树查找、插入、删除)》《树形索引(B-树查找、插入、删除)》

《树形索引(B-树查找、插入、删除)》

《树形索引(B-树查找、插入、删除)》

四、B-树的删除

首先找到要删除的关键码所在结点,假设所删关键码为非终端结点中Ki,则可用指针Ai所指子树中最小关键码Y代替Ki,然后在相应终端结点中删去Y,这样就转为删除终端结点中的关键码的问题了。

删除终端节点中关键码:

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

(2)被删关键码所在结点中关键码个数n=[m/2]-1说明删去该关键字后该结点将不满足B-树的定义,需要调整。

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

(3)被删关键码所在结点和其相邻的左右兄弟节点中的关键码个数均等于[m/2]-1,左右兄弟都不够借。

需把要删除关键字的结点与其左(或右)兄弟结点以及双亲结点中分割二者的关键字合并成一个结点,即在删除关键字后,该结点中剩余的关键字加指针,加上双亲结点中的关键字Ki一起合并到Ai(即双亲结点指向该删除关键字结点的左(右)兄弟结点的指针)所指的兄弟结点中去。如果因此使双亲结点中关键字个数小于[m/2]-1,则对此双亲结点做同样处理。以致于可能直到对根结点做这样的处理而使整个树减少一层。

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

《树形索引(B-树查找、插入、删除)》

a被删关键字Ki所在结点的关键字数目不小于ceil(m/2),则只需从结点中删除Ki和相应指针Ai,树的其它部分不变

《树形索引(B-树查找、插入、删除)》

    b、被删关键字Ki所在结点的关键字数目等于ceil(m/2)-1,则需调整。调整过程如上面所述。

《树形索引(B-树查找、插入、删除)》

    c、被删关键字Ki所在结点和其相邻兄弟结点中的的关键字数目均等于[m/2]-1,假设该结点有右兄弟,且其右兄弟结点地址由其双亲结点指针Ai所指。则在删除关键字之后,它所在结点的剩余关键字和指针,加上双亲结点中的关键字Ki一起,合并到Ai所指兄弟结点中(若无右兄弟,则合并到左兄弟结点中)。如果因此使双亲结点中的关键字数目少于[m/2]-1,则依次类推.

《树形索引(B-树查找、插入、删除)》



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