数据结构--B树

 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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值