B树

定义:

(1)每个结点有以下域:

a、n(x):当前存储在结点x中的关键字数

b、n(x)个关键字本身,以非降序存放,因此key(x)[1]<=key(x)[2]<=...<=key(x)[n(x)]

c、leaf(x),是个布尔值,如果x是叶子的话,则他为true,如果x为一个内结点,则为false

(2)每个内结点x还包含n(x)+1个指向其子女的指针c(x)[1],c(x)[2],...,c(x)[n(x)+1],叶结点没有子女,故他们的c域无定义

(3)各关键字key(x)[i]对存储在各子树中的关键字范围加以分隔,如果k[i]为存储在c(x)[i]为根的子树中的关键字,则k[1]<=key(x)[1]<=k[2]<=key(x)[2]<=...<=key(x)[n(x)]<=k[n(x)+1]

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

(5)每一个结点能包含的关键字数有一个上界和下界。这些界可以使用一个称作B树的最小度数的固定整数t>=2来表示

a、每个非根结点必须至少有t-1个关键字。每个非根的内结点至少有t个子女。如果树是非空的,则根结点至少包含一个关键字

b、每个结点至多包含2t-1个关键字,所以一个内结点至多有2t个子女。我们说一个结点是满的,如果它恰好有2t-1个关键字

搜索B树

search
 1 B-TREE-SEARCH(x,k)
2 i=1
3 while(i<=n(x)&&k>key(x)[i])
4 ++i;
5 if(i<=n(x)&&key(x)[i]==k)
6 return x&&i
7 if(leaf(x))
8 return
9 else
10 DISK-READ(c(x)[i])
11 B-TREE-SEARCH(c(x)[i],k)
12

创建一棵空的B树

create
1 B-TREE-CREATE(T)
2 x=ALLOCATE-NODE()
3 leaf(x)=true
4 n(x)=0
5 DISK-WRITE(x)
6 root(T)=x

B树中结点的分裂

split
 1 //y=c(x)[i]是个满子结点
2 B-TREE-SPLIT-CHILD(x,i,y)
3 z=ALLOCATE-NODE()
4 leaf(z)=leaf(y)
5 n(z)=t-1
6 for(j=1;j<=t-1;++j)
7 key(z)[j]=key(y)[j+t]
8 if(!leaf(z))
9 for(j=1;j<=t;++j)
10 c(z)[j]=c(y)[j+t]
11 n(y)=t-1
12 for(j=n(x)+1;j>=i+1;--j)
13 c(x)[j+1]=c(x)[j]
14 c(x)[i+1]=z
15 for(j=n(x);j>=i;--j)
16 key(x)[j+1]=key(x)[j]
17 key(x)[i]=key(y)[t]
18 n(x)=n(x)+1
19 DISK-WRITE(y)
20 DISK-WRITE(z)
21 DISK-WRITE(x)

对B树用单程下行遍历树方式插入关键字

insert
 1 B-TREE-INSERT(T,k)
2 r=root(T)
3 if(n(r)==2t-1)
4 s=ALLOCATE-NODE()
5 root(T)=s
6 leaf(s)=false
7 n(s)=0
8 c(s)[1]=r
9 B-TREE-SPLIT-CHILD(s,1,r)
10 B-TREE-INSERT-NONFULL(s,k)
11 else
12 B-TREE-INSERT-NONFULL(r,k)
insert nonfull
 1 B-TREE-INSERT-NONFULL(x,k)
2 i=n(x)
3 if(leaf(x))
4 while(i>=1&&k<key(x)[i])
5 key(x)[i+1]=key(x)[i]
6 --i
7 key(x)[i+1]=k
8 n(x)++
9 DISK-WRITE(x)
10 else
11 while(i>=1&&k<key(x)[i])
12 --i
13 ++i
14 DISK-READ(c(x)[i])
15 if(n(c(x)[i])==2t-1)
16 B-TREE-SPLIT-CHILD(x,i,c(x)[i])
17 if(k>key(x)[i])
18 i++
19 B-TREE-INSERT-NONFULL(c(x)[i],k)
20
21





posted @ 2012-02-16 22:03  Cavia  阅读(378)  评论(0编辑  收藏  举报