B-树是一种平衡的多路查找树,它有较高的查找的效率,在文件系统中很有用.
一、B-树的定义
一棵"m 阶的B树"或为空树,或为具有以下特性的 m 叉查找树:
(1)树中每个结点至多有 m 棵子树;
(2)除根以外的所有非叶结点至少有 [m/2 ]棵子树,根结点若是非叶结点,则至少有两棵子树;
(3)所有的非叶结点中含有如下信息:
(n,A0,(K1,D1),A1,(K2,D2),……,An-1,(Kn,Dn),An)
其中:(Ki,Di)(i=1,…,n)为索引项,且 Ki<Ki+1(i=1,…,n-1);Ai(i=0,…,n) 为指向子树根结点的指针,且 Ai-1 所指子树中所有索引项的关键码小于 Ki(i=1,…,n),An 所指子树中索引项的关键码大于 Kn,n(m/2-1≤n≤m-1) 为结点中索引项的个数;
(4)所有叶结点都在同一层上,且不含任何信息。
下图为一棵4阶树:

二,B-树的实现
下面为c代码,参照了<<数据结构>>(严蔚敏)一书中的算法:
#include
<
stdio.h
>
#include
<
malloc.h
>

#define
FALSE 0
#define
TRUE 1
#define
m 3

typedef
int
KeyType;
typedef
struct
BTNode

...
{
int keynum;
struct BTNode *parent;
KeyType key[m+1];
struct BTNode *ptr[m+1];
}
BTNode,
*
BTree;
typedef
struct

...
{
BTNode *pt;
int i;
int tag;
}
Result;
//
设结点中的指针向量为空
void
SetNull(BTree
&
p)

...
{
int i=0;
while(i<=p->keynum)

...{
p->ptr[i]=NULL;
i++;
}
}
//
在结点中查找关键字
int
SearchNode(BTree p,KeyType k)

...
{
int i=1;
while(i<=p->keynum)

...{
if(k<p->key[i])
return i-1;
i++;
}
return i-1;
}
//
在B树中查找关键字k
Result SearchBTree(BTree t,KeyType k)

...
{
BTree p=t,q=NULL;
bool found=FALSE;
int i=0;
Result result;
while(p&&!found)

...{
i=SearchNode(p,k);
if(i>0&&p->key[i]==k)
found=TRUE;
else

...{
q=p;
p=p->ptr[i];
}
}
if(found)

...{
result.pt=p;
result.i=i;
result.tag=1;
}
else

...{
result.pt=q;
result.i=i;
result.tag=0;
}
return result;
}
//
在结点中插入新的关键字k和指针pt
void
InsertInNode(BTree
&
q,
int
i,KeyType k,BTree pt)

...
{
int j;
for(j=q->keynum;j>i;j--)
q->key[j+1]=q->key[j];
q->key[j+1]=k;
for(j=q->keynum;j>i;j--)
q->ptr[j+1]=q->ptr[j];
q->ptr[j+1]=pt;
if(pt)

...{
pt->parent=q;
}
q->keynum++;
}
//
分裂结点p
void
Split(BTree p,BTree
&
q)

...
{
int s=m%2==0?m/2-1:m/2,i,j=0;
p->keynum=s;
q=(BTree)malloc(sizeof(BTNode));
SetNull(q);

for(i=s+2;i<=m;i++)

...{
q->ptr[j]=p->ptr[i-1];
q->key[++j]=p->key[i];
}
q->ptr[j]=p->ptr[i-1];
q->keynum=j;
}
//
在q结点第i个位置插入关键字
void
InsertBTree(BTree
&
t,KeyType k,BTree q,
int
i)

...
{
BTree ap=NULL,root;
bool finish=FALSE;
int s;
KeyType x=k;
while(q&&!finish)

...{
InsertInNode(q,i,x,ap);
if(q->keynum<m)
finish=TRUE;
else

...{
s=m%2==0?m/2:m/2+1;
Split(q,ap);
x=q->key[s];
q=q->parent;
if(q)
i=SearchNode(q,x);
}
}
if(!finish)

...{
root=(BTree)malloc(sizeof(BTNode));
SetNull(root);
root->key[1]=x;
root->ptr[0]=t;
root->ptr[1]=ap;

root->keynum=1;
root->parent=NULL;
if(t)
t->parent=root;
if(ap)
ap->parent=root;
t=root;
}
}
//
在B树中插入一个关键字
void
InsertNode(BTree
&
t,KeyType key)

...
{
Result result;
result=SearchBTree(t,key);
if(!result.tag)

...{
InsertBTree(t,key,result.pt,result.i);
}
}
//
中序遍历B树
void
PrintBTree(BTree t)

...
{
if(t)

...{
int i=1;
while(i<=t->keynum)

...{
PrintBTree(t->ptr[i-1]);
printf("%d,",t->key[i]);
i++;
}
PrintBTree(t->ptr[i-1]);
}
}

int
main(
int
argc,
char
*
argv[])

...
{
BTree root=NULL;

int array[]=...{9,5,8,3,2,4,7};
for(int i=0;i<7;i++)
InsertNode(root,array[i]); //插入结点
printf("printing ... ");
PrintBTree(root);//遍历结点
}
原文:http://blog.youkuaiyun.com/arrowcat/archive/2008/04/07/2256454.aspx