查找算法--树表查找之B树

        前面介绍的BST(二叉排序树)和AVL(平衡二叉树)都是二叉树,用作内部查找的数据结构,即被查找的数据集不大,可以放在内存中。这篇博客将主要介绍B树,是非二叉树,用作外部查找的数据结构,其数据存放在外存中。 B-树又称为多路平衡查找树,是一种组织和维护外存文件系统非常有效的数据结构。具体讲解之前,有一点,强调一下:B-树,即为B树。因为B树的原英文名称为B-tree,而国内很多人喜欢把B-tree译作B-树,其实,这是个非常不好的直译,很容易让人产生误解。如人们可能会以为B-树是一种树,而B树又是一种一种树。而事实上是,B-tree就是指的B树。特此说明。

B-树

  B-树中所有结点的孩子结点最大值称为B-树的阶,通常用m表示,从查找效率来说,要求m>=3.

一棵m阶B-树应满足的特性为:

    1.树中每个结点最多含有m个孩子结点,即至多有m-1个关键字;

    2.除根结点外,其它每个结点至少有[m / 2]个孩子结点,即至少有[m/2]-1个关键字。[m/2]是取大于m/2的最小整数;

    3.若根结点不是叶子结点,则至少有两个孩子结点;

    4.每个结点的结构为:

   

其中n为结点关键字个数,除根节点外,其它结点的n>=[m/2]-1&&n<=m-1;关键字是升序排列,即k1<k2<k3....。Pi指针所指的结点关键字大于等于Ki,小于Ki+1;

扫描二维码关注公众号,回复: 854893 查看本文章

    5.所有叶子结点都在同一层上,即B-树是所有平衡因子均为0的多路查找树。

上面的特性看起来晕晕的,下面用一个实例来分析。

引用典型的3阶B-树如下



看根结点A,其结点结构应为



 

    阶是孩子结点的最大值,所以每个结点至多有3个孩子(分支),从结点结构来看,指针域比关键字多1,所以至多有3-1=2个关键字。

当阶树m=2时,就是二叉B树,即平衡二叉树

B-树的查找



 

来模拟下查找文件29的过程:

    (1) 根据根结点指针找到文件目录的根磁盘块1,将其中的信息导入内存。【磁盘IO操作1次】

    (2) 此时内存中有两个文件名17,35和三个存储其他磁盘页面地址的数据。根据算法我们发现17<29<35,因此我们找到指针p2。

    (3) 根据p2指针,我们定位到磁盘块3,并将其中的信息导入内存。【磁盘IO操作2次】

    (4) 此时内存中有两个文件名26,30和三个存储其他磁盘页面地址的数据。根据算法我们发现26<29<30,因此我们找到指针p2。

    (5) 根据p2指针,我们定位到磁盘块8,并将其中的信息导入内存。【磁盘IO操作3次】

    (6) 此时内存中有两个文件名28,29。根据算法我们查找到文件29,并定位了该文件内存的磁盘地址。


 B-树的插入

重点判断是否满足n<=m-1。

插入方法步骤:

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

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

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

例如:



 

B-树的删除

B-树特性,除根结点外,其它所有结点的关键字n>=[m/2]-1&&n<=m-1;

 

分三种情况删除:

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



 

  b.如果被删关键字所在结点的关键字个数n等于[m/2]-1,说明删去该关键字后该结点将不满足B-树的定义,需要调整。

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



 

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



 

猜你喜欢

转载自longpo.iteye.com/blog/2197517