您的位置:首页 > 理论基础 > 数据结构算法

数据结构与算法系列---B-树

2008-04-07 11:25 260 查看
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);//遍历结点


}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: