分享

B+ 树算法与源码(C语言描述)

 MikeDoc 2011-06-20

B+树可以看作是B树的变形,对于存放在外存贮器上的字典,B+树比B树更为常用。

  一个m阶的B+树满足下列条件∶

  (1) 每个结点至多有m棵子树。

  (2) 除根结点外,其它每个分支至少有m/2棵子树。

  (3) 非叶结点的根结点至少有两棵子树。

  (4) 有n棵子树的结点有n个关键码,叶结点中至少包含n/2个关键码。

  (5) 叶结点都在同一层中,其中存放数据文件中记录的关键码及指向该记录的指针,或存放数据文件分块后每块的最大关键码及指向该块的指针。叶结点按关键码值大小顺序链接。可以把每个叶结点看成是一个基本索引块(直接指向数据文件中的记录)。

  (6) 所有分支结点可看成是索引的索引。使结点中仅包含它的各个子结点中最大(或最小)关键码的分界值及指向子结点的指针。

/*=========================== BinTreeh.h =========================*/

#include <stdio.h>
/*=========================== data struct =====================*/

typedef char ElementType;
typedef struct Node{
ElementType data;
struct Node *LChild; /* 左子树 */
struct Node *RChild; /* 右子树*/
} TreeNode;
/*=============================== function prounce ===============*/

int CreateBinTree( TreeNode **rootp,ElementType **lp );
void FreeTree( TreeNode *rootp );

int DelTree( TreeNode *rootp,ElementType e );
int Insert( TreeNode *rootp,ElementType Curr,ElementType e,int CurrPos );

TreeNode *FindNode( TreeNode *rootp,ElementType e );
TreeNode *FindParent( TreeNode *rootp,ElementType e );

void Leaf( TreeNode *rootp,int *np );
int Depth( TreeNode *rootp );

void PreOrder( TreeNode *rootp );
void MidOrder( TreeNode *rootp );
void BackOrder( TreeNode *rootp );
/*================================ function body ================*/

/*------------------------------------   建树 -------------------------*/
int CreateBinTree( TreeNode **rootp,ElementType **lp )
{
ElementType CurrElement;

if(*lp==NULL) return 0; /*    字符串不存在,返回 0 */
if(**lp==0) return 1; /*    字符串为空,返回1      */
CurrElement=*(*lp);
(*lp)++;
if(CurrElement=='.') { (*rootp)=NULL; return 1; }
if(!((*rootp)=(TreeNode *) malloc(sizeof(TreeNode))) ) return 0;
(*rootp)->data=CurrElement;
if(!CreateBinTree(&(*rootp)->LChild,lp)) return 0;
return CreateBinTree(&(*rootp)->RChild,lp);
}
/*-------------------------------------------------------   前序遍历子树--------*/
void PreOrder( TreeNode *rootp )
{
if(rootp==NULL) return;
printf(" %c",rootp->data); /*    打印父节点            */
if(rootp->LChild!=NULL) PreOrder(rootp->LChild); /*   打印左子树节点*/
if(rootp->RChild!=NULL) PreOrder(rootp->RChild); /*   打印右子树节点 */
return;
}
/*--------------------------------------------------------   中序遍历子树 --------*/
void MidOrder( TreeNode *rootp )
{
if(rootp==NULL) return;
if(rootp->LChild!=NULL) MidOrder(rootp->LChild);
printf(" %c",rootp->data);
if(rootp->RChild!=NULL) MidOrder(rootp->RChild);
return;
}
/*------------------------------------------------------ 后序遍历子树--------*/
void BackOrder( TreeNode *rootp )
{
if(rootp==NULL) return;
if(rootp->LChild!=NULL) BackOrder(rootp->LChild);
if(rootp->RChild!=NULL) BackOrder(rootp->RChild);
printf(" %c",rootp->data);
return;
}
/*-------------------------------------------------------   查找节点--------*/
TreeNode *FindNode( TreeNode *rootp,ElementType e )
{
TreeNode *temp;

if(rootp==NULL) return NULL; /*    根节点为空,没有找到(空树) */
if(rootp->data==e) return rootp;
if(temp=FindNode(rootp->LChild,e)) return temp;
return FindNode(rootp->RChild,e);
}
/*-------------------------------------------------------    释放树所占内存空间   --------*/
void FreeTree( TreeNode *rootp )
{
if(!rootp) return;
FreeTree(rootp->LChild);
FreeTree(rootp->RChild);
free(rootp);
}
/*-----------------------------------------------------   查询父节点--------*/
TreeNode *FindParent( TreeNode *rootp,ElementType e )
{
TreeNode *temp;

if((rootp==NULL)||(rootp->LChild==NULL && rootp->RChild==NULL)) return NULL;
if((rootp->LChild && rootp->LChild->data==e)
||(rootp->RChild && rootp->RChild->data==e)) return rootp;
temp=FindParent(rootp->LChild,e);
if(temp) return temp;
return FindParent(rootp->RChild,e);
}
/*--------------------------------------------------------    删除树节点   --------*/
int DelTree( TreeNode *rootp,ElementType e )
{
TreeNode *temp;

temp=FindParent(rootp,e);
if(!temp) return 0;
if(temp->LChild &&(temp->LChild->data==e))
{ FreeTree(temp->LChild);
temp->LChild=NULL;
}
else
{ FreeTree(temp->RChild);
temp->RChild=NULL;
}
return 1;
}
/*--------------------------------------------------------   插入节点--------*/
int Insert( TreeNode *rootp,ElementType Curr,ElementType e,int CurrPos )
{
TreeNode *parent,*new,*temp;

if(!(parent=FindParent(rootp,Curr))) return 0;
if(!(new=(TreeNode *) malloc(sizeof(TreeNode)))) return 0;
new->data=e;
if(parent->LChild->data==Curr) { temp=parent->LChild; parent->LChild=new; }
temp=parent->RChild;
parent->RChild=new;

if(CurrPos==0) new->LChild=temp; new->RChild=NULL;
if(CurrPos==1) new->RChild=temp; new->LChild=NULL;

return 1;
}
/*-----------------------------------------------------------    计算叶子节点 --------*/
void Leaf( TreeNode *rootp,int *np )
{
if(rootp==NULL) return ;
if(rootp->LChild==NULL && rootp->RChild==NULL) { (*np)++; return; }
Leaf(rootp->LChild,np);
Leaf(rootp->RChild,np);
}
/*----------------------------------------------------------   计算树高--------*/
int Depth( TreeNode *rootp )
{
int ld,rd; /* ld:左子树深度*/
             /* rd: 右子树深度*/
if(rootp==NULL) return 0;
ld=Depth(rootp->LChild);
rd=Depth(rootp->RChild);
if(ld>rd) return ld+1;
else return rd+1;
}
/*=========================== The end of BinTreeh.h ======================*/

RE:如有注释错误请指正,算法很奇妙,希望共同探讨,共同进步……

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多