B树

  B树是为磁盘或其他存取的辅助存储设备而设计的一种平衡搜索树,与红黑树的不同之处在于B树的结点可以有很多孩子。

主要内容:

一 B树的定义

二 B树上的基本操作

三 从B树中删除关键字

 

一 B树的定义

1. 一棵B树T是具有一下性质的有根树:

(1) 每个结点x有以下属性:

  a. x.n,当前存储在结点x中的关键字个数

  b. x.n个关键字本身x.key1,x.key2,...,x.keyx.n,以非降序存放,即x.key1 <= x.key2 <= ... <= x.keyx.n

  c. x.leaf,一个布尔值,如果x是叶结点,则为TRUE,如果x是内部结点,则为FALSE

(2) 每个内部结点x还包含x.n + 1个指向其孩子的指针x.c1,x.c2,...,x.cx.n+1,叶结点的ci属性没有定义

(3) 关键字x.keyi 对存储在各子树中的关键字范围加以分割,如果ki 为任意一个存储在以x.ci为根的子树中的关键字,那么有

  k1 <= x.key1 <= k2 <= x.key2 <= ... <= x.keyx.n <= kx.n+1

(4) 每个叶结点具有相同的深度,即树的高度h

(5) 最小度数:每个结点所包含的关键字个数有上界和下界,用一个被称为B树的最小度数的固定整数t >= 2来表示这些界:

  a. 除了根结点以外的每个结点必须至少有t - 1个关键字。即除了根结点以外的每个内部结点至少有t个孩子。如果树非空,根结点至少有一个关键字。

  b. 每个结点至多包含2t - 1个关键字,2t个孩子,一个结点恰好有2n - 1个关键字时是满的

 

2. 如果n >= 1,那么对任意一棵包含n个关键字,高度为h,最小度数t >= 2的B树T,有

 

二 B树上的基本操作

1. B树的根结点始终在主存中,无需进行DISK-READ,只要修改的时候进行DISK-WRITE

2. 任何被当作参数的结点在被传递之前,需要做一次DISK-READ

3. 搜索:输入指向某子树根结点x的指针即要搜索的关键字k,B-TREE-SEARCH返回的是由结点y和使得y.keyi = k 的下标 i 组成的有序对(y,i),否则返回NIL

 递归过程中形成了一条从跟向下的简单路径,该过程访问的磁盘页面数为,n为所含关键字的个数。在每个结点搜索所有关键字需要O(t),总的CPU时间为

4. 构建一棵B树时,先用B-TREE-CREATE来创建一个空的结点,然后用B-TREE-INSERT来添加关键字。

  ALLOCATE-NODE用来在O(1)创建一个新的结点。

5. 为了进行插入操作,这里引入过程B-TREE-SPLIT-CHILD,将一个满的结点(有2t - 1 个关键字)按其中间关键字分裂为2个各含t - 1 个关键字的结点,并将中间关键字提升到其父结点。输入一个非满的内部结点x和一个使x.ci为满的子结点的下标 i 。

  下图为一个分裂的过程图解:

6. 以沿树单程下行方式插入关键字:

  2~9行如果根为满即进行分裂,树的高度增加1,然后可以进行对一个非满结点的插入B-TREE-INSERT-NONFULL

  NONFULL插入保证参数x为非满结点,2~8行判断如果已经是叶结点即可进行简单插入,否则可能要递归向下插入。13~14行判断向下插入时子结点是否为满,如果满就需要对该子结点进行分裂,保证下次调用NONFULL插入的是一个非满的结点。

  B-TREE-INSERT需要O(h)次磁盘存取,总CPU时间为

 

三 从B树中删除关键字

1. 从内部结点删除一个关键字时,要重新安排这个结点的孩子。

2. 当要删除关键字的路径上结点(非根)有最少关键字个数时,也可能要向上回溯。

3. 过程B-TREE-DELETE从以x为根的子树中删除关键字k,调用时要保证x中关键字个数至少为t

4. 过程:

(1)如果关键字在结点x中并且x是叶结点,可以简单删除(调用时已经保证x最少关键字个数为t)

(2)关键字k在x中,并且x是内部结点:

a. 看结点x中前于k的子结点y,如果y至少包含 t 个关键字,则找出k在以y为根的子树中的前驱k',递归删除k',并在x中用k'代替k

b. a中的y少于t个关键字,可以检查结点x中后于k的子结点z,如果z有至少t个关键字则可以按照a的方式完成

c. 否则y和z中都只有t - 1个关键字,则将k和z的全部合并进y,这样x就失去了k和指向z的指针,并且y包含2t - 1个关键字,释放z并从y中递归删除k

(3)关键字k不在内部结点x中,则要确定包含k的子树x.ci。如果x.ci包含至少t个关键字,可以降至x.ci中递归删除k。否则,执行一下2种情况来保证降至一个至少包含t个关键字的结点。

a. 如果x.ci只有t - 1个关键字,但是它的一个相邻的兄弟有至少t个关键字,则将它兄弟的一个关键字升至x,将x中一个关键字降到x.ci,并将兄弟的相应指针移动到x.ci,使得x.ci增加一个关键字。

b. x.ci以及所有兄弟都只有t - 1个关键字,则将x.ci和一个兄弟进行合并,并将x中的一个关键字降至新形成的结点成为中间关键字。

  

该过程需要O(h)次磁盘操作,CPU时间为

 

posted @ 2014-04-11 10:19  Jolin123  阅读(439)  评论(0编辑  收藏  举报