数据结构--B树

论坛 期权论坛 脚本     
匿名技术用户   2021-1-5 13:30   49   0

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.csdn.net/arrowcat/archive/2008/04/07/2256454.aspx

分享到 :
0 人收藏
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

积分:7942463
帖子:1588486
精华:0
期权论坛 期权论坛
发布
内容

下载期权论坛手机APP