B+树c实现代码

对c不懂,所以还看不太明白,B+树难点在于插入与删除操作

参考地址:http://www.leftworld.net/wenzhang/show/1996.html
          http://www.sqlite.com.cn/MySqlite/6/373.Html


这个结构一般用于数据库的索引,综合效率较高。
另外还有一种与此类似的树结构叫B+树,像 Berkerly DB , sqlite , mysql 数据库都使用了B+树算法处理索引。
这两种处理索引的数据结构的不同之处:
1。B树中同一键值不会出现多次,并且它有可能出现在叶结点,也有可能出现在非叶结点中。而B+树的键一定会出现在叶结点中,并且有可能在非叶结点中也有可能重复出现,以维持B+树的平衡。
2。因为B树键位置不定,且在整个树结构中只出现一次,虽然可以节省存储空间,但使得在插入、删除操作复杂度明显增加。B+树相比来说是一种较好的折中。
3。B树的查询效率与键在树中的位置有关,最大时间复杂度与B+树相同(在叶结点的时候),最小时间复杂度为1(在根结点的时候)。而B+树的时候复杂度对某建成的树是固定的。

如果想自己做个小型数据库,可以参考一下下面给出的B树算法的实现,可能会对你有所帮助。

结构体:
/* btrees.h */ 
/* 
* 平衡多路树的一种重要方案。 
* 在 1970 年由 R. Bayer 和 E. McCreight 发明。 
*/ 
#define M 1 
/* B 树的阶,即非根节点中键的最小数目。 
* 有些人把阶定义为非根节点中子树的最大数目。 
*/ 
typedef int typekey; 
typedef struct btnode { /* B-Tree 节点 */ 
int d; /* 节点中键的数目 */ 
typekey k[2*M]; /* 键 */ 
char *v[2*M]; /* 值 */ 
struct btnode *p[2*M+1]; /* 指向子树的指针 */ 
} node, *btree; 
/* 
* 每个键的左子树中的所有的键都小于这个键, 
* 每个键的右子树中的所有的键都大于等于这个键。 
* 叶子节点中的每个键都没有子树。 
*/ 

/* 当 M 等于 1 时也称为 2-3 树 
* +----+----+ 
* | k0 | k1 | 
* +-+----+----+--- 
* | p0 | p1 | p2 | 
* +----+----+----+ 
*/ 
extern int btree_disp; /* 查找时找到的键在节点中的位置 */ 
extern char * InsValue; /* 与要插的键相对应的值 */ 

extern btree search(typekey, btree); 
extern btree insert(typekey,btree); 
extern btree delete(typekey,btree); 
extern int height(btree); 
extern int count(btree); 
extern double payload(btree); 
extern btree deltree(btree); 
/* end of btrees.h */ 

/*******************************************************/ 



主要算法:

/*******************************************************/ 

/* btrees.c */ 
#include 
#include 
#include "btrees.h" 

btree search(typekey, btree); 
btree insert(typekey,btree); 
btree delete(typekey,btree); 
int height(btree); 
int count(btree); 
double payload(btree); 
btree deltree(btree); 

static void InternalInsert(typekey, btree); 
static void InsInNode(btree, int); 
static void SplitNode(btree, int); 
static btree NewRoot(btree); 

static void InternalDelete(typekey, btree); 
static void JoinNode(btree, int); 
static void MoveLeftNode(btree t, int); 
static void MoveRightNode(btree t, int); 
static void DelFromNode(btree t, int); 
static btree FreeRoot(btree); 

static btree delall(btree); 
static void Error(int,typekey); 

int btree_disp; /* 查找时找到的键在节点中的位置 */ 
char * InsValue = NULL; /* 与要插的键相对应的值 */ 
static int flag; /* 节点增减标志 */ 
static int btree_level = 0; /* 多路树的高度 */ 
static int btree_count = 0; /* 多路树的键总数 */ 
static int node_sum = 0; /* 多路树的节点总数 */ 
static int level; /* 当前访问的节点所处的高度 */ 
static btree NewTree; /* 在节点分割的时候指向新建的节点 */ 
static typekey InsKey; /* 要插入的键 */ 

btree search(typekey key, btree t) 
{ 
int i,j,m; 
level=btree_level-1; 
while (level >= 0){ 
for(i=0, j=t->d-1; i t->k[m])?(i=m+1):(j=m)); 
if (key == t->k){ 
btree_disp = i; 
return t; 
} 
if (key > t->k) /* i == t->d-1 时有可能出现 */ 
i++; 
t = t->p; 
level--; 
} 
return NULL; 
} 

btree insert(typekey key, btree t) 
{ 
level=btree_level; 
InternalInsert(key, t); 
if (flag == 1) /* 根节点满之后,它被分割成两个半满节点 */ 
t=NewRoot(t); /* 树的高度增加 */ 
return t; 
} 

void InternalInsert(typekey key, btree t) 
{ 
int i,j,m; 

level--; 
if (level < 0){ /* 到达了树的底部: 指出要做的插入 */ 
NewTree = NULL; /* 这个键没有对应的子树 */ 
InsKey = key; /* 导致底层的叶子节点增加键值+空子树对 */ 
btree_count++; 
flag = 1; /* 指示上层节点把返回的键插入其中 */ 
return; 
} 
for(i=0, j=t->d-1; i t->k[m])?(i=m+1):(j=m)); 
if (key == t->k) { 
Error(1,key); /* 键已经在树中 */ 
flag = 0; 
return; 
} 
if (key > t->k) /* i == t->d-1 时有可能出现 */ 
i++; 
InternalInsert(key, t->p); 

if (flag == 0) 
return; 
/* 有新键要插入到当前节点中 */ 
if (t->d < 2*M) {/* 当前节点未满 */ 
InsInNode(t, i); /* 把键值+子树对插入当前节点中 */ 
flag = 0; /* 指示上层节点没有需要插入的键值+子树,插入过程结束 */ 
} 
else /* 当前节点已满,则分割这个页面并把键值+子树对插入当前节点中 */ 
SplitNode(t, i); /* 继续指示上层节点把返回的键值+子树插入其中 */ 
} 

/* 
* 把一个键和对应的右子树插入一个节点中 
*/ 
void InsInNode(btree t, int d) 
{ 
int i; 
/* 把所有大于要插入的键值的键和对应的右子树右移 */ 
for(i = t->d; i > d; i--){ 
t->k = t->k[i-1]; 
t->v = t->v[i-1]; 
t->p[i+1] = t->p; 
} 
/* 插入键和右子树 */ 
t->k = InsKey; 
t->p[i+1] = NewTree; 
t->v = InsValue; 
t->d++; 
} 
/* 
* 前件是要插入一个键和对应的右子树,并且本节点已经满 
* 导致分割这个节点,插入键和对应的右子树, 
* 并向上层返回一个要插入键和对应的右子树 
*/ 
void SplitNode(btree t, int d) 
{ 
int i,j; 
btree temp; 
typekey temp_k; 
char *temp_v; 
/* 建立新节点 */ 
temp = (btree)malloc(sizeof(node)); 
/* 
* +---+--------+-----+-----+--------+-----+ 
* | 0 | ...... | M | M+1 | ...... |2*M-1| 
* +---+--------+-----+-----+--------+-----+ 
* |<- M+1 ->|<- M-1 ->| 
*/ 
if (d > M) { /* 要插入当前节点的右半部分 */ 
/* 把从 2*M-1 到 M+1 的 M-1 个键值+子树对转移到新节点中, 
* 并且为要插入的键值+子树空出位置 */ 
for(i=2*M-1,j=M-1; i>=d; i--,j--) { 
temp->k[j] = t->k; 
temp->v[j] = t->v; 
temp->p[j+1] = t->p[i+1]; 
} 
for(i=d-1,j=d-M-2; j>=0; i--,j--) { 
temp->k[j] = t->k; 
temp->v[j] = t->v; 
temp->p[j+1] = t->p[i+1]; 
} 
/* 把节点的最右子树转移成新节点的最左子树 */ 
temp->p[0] = t->p[M+1]; 
/* 在新节点中插入键和右子树 */ 
temp->k[d-M-1] = InsKey; 
temp->p[d-M] = NewTree; 
temp->v[d-M-1] = InsValue; 
/* 设置要插入上层节点的键和值 */ 
InsKey = t->k[M]; 
InsValue = t->v[M]; 

} 
else { /* d <= M */ 
/* 把从 2*M-1 到 M 的 M 个键值+子树对转移到新节点中 */ 
for(i=2*M-1,j=M-1; j>=0; i--,j--) { 
temp->k[j] = t->k; 
temp->v[j] = t->v; 
temp->p[j+1] = t->p[i+1]; 
} 
if (d == M) /* 要插入当前节点的正中间 */ 
/* 把要插入的子树作为新节点的最左子树 */ 
temp->p[0] = NewTree; 
/* 直接把要插入的键和值返回给上层节点 */ 
else { /* (d /* 把节点当前的最右子树转移成新节点的最左子树 */ 
temp->p[0] = t->p[M]; 
/* 保存要插入上层节点的键和值 */ 
temp_k = t->k[M-1]; 
temp_v = t->v[M-1]; 
/* 把所有大于要插入的键值的键和对应的右子树右移 */ 
for(i=M-1; i>d; i--) { 
t->k = t->k[i-1]; 
t->v = t->v[i-1]; 
t->p[i+1] = t->p; 
} 
/* 在节点中插入键和右子树 */ 
t->k[d] = InsKey; 
t->p[d+1] = NewTree; 
t->v[d] = InsValue; 
/* 设置要插入上层节点的键和值 */ 
InsKey = temp_k; 
InsValue = temp_v; 
} 
} 
t->d =M; 
temp->d = M; 
NewTree = temp; 
node_sum++; 
} 

btree delete(typekey key, btree t) 
{ 
level=btree_level; 
InternalDelete(key, t); 
if (t->d == 0) 
/* 根节点的子节点合并导致根节点键的数目随之减少, 
* 当根节点中没有键的时候,只有它的最左子树可能非空 */ 
t=FreeRoot(t); 
return t; 
} 

void InternalDelete(typekey key, btree t) 
{ 
int i,j,m; 
btree l,r; 
int lvl; 

level--; 
if (level < 0) { 
Error(0,key); /* 在整个树中未找到要删除的键 */ 
flag = 0; 
return; 
} 
for(i=0, j=t->d-1; i t->k[m])?(i=m+1):(j=m)); 
if (key == t->k) { /* 找到要删除的键 */ 
if (t->v != NULL) 
free(t->v); /* 释放这个节点包含的值 */ 
if (level == 0) { /* 有子树为空则这个键位于叶子节点 */ 
DelFromNode(t,i); 
btree_count--; 
flag = 1; 
/* 指示上层节点本子树的键数量减少 */ 
return; 
} else { /* 这个键位于非叶节点 */ 
lvl = level-1; 
/* 找到前驱节点 */ 
r = t->p; 
while (lvl > 0) { 
r = r->p[r->d]; 
lvl--; 
} 
t->k=r->k[r->d-1]; 
t->v=r->v[r->d-1]; 
r->v[r->d-1]=NULL; 
key = r->k[r->d-1]; 
} 
} 
else if (key > t->k) /* i == t->d-1 时有可能出现 */ 
i++; 
InternalDelete(key,t->p); 
/* 调整平衡 */ 
if (flag == 0) 
return; 
if (t->p->d < M) { 
if (i == t->d) /* 在最右子树中发生了删除 */ 
i--; /* 调整最右键的左右子树平衡 */ 
l = t->p; 
r = t->p[i+1]; 
if (r->d > M) 
MoveLeftNode(t,i); 
else if(l->d > M) 
MoveRightNode(t,i); 
else { 
JoinNode(t,i); 
/* 继续指示上层节点本子树的键数量减少 */ 
return; 
} 
flag = 0; 
/* 指示上层节点本子树的键数量没有减少,删除过程结束 */ 
} 
} 

/* 
* 合并一个节点的某个键对应的两个子树 
*/ 
void JoinNode(btree t, int d) 
{ 
btree l,r; 
int i,j; 
l = t->p[d]; 
r = t->p[d+1]; 

/* 把这个键下移到它的左子树 */ 
l->k[l->d] = t->k[d]; 
l->v[l->d] = t->v[d]; 
/* 把右子树中的所有键值和子树转移到左子树 */ 
for (j=r->d-1,i=l->d+r->d; j >= 0 ; j--,i--) { 
l->k = r->k[j]; 
l->v = r->v[j]; 
l->p = r->p[j]; 
} 
l->p[l->d+r->d+1] = r->p[r->d]; 
l->d += r->d+1; 
/* 释放右子树的节点 */ 
free(r); 
/* 把这个键右边的键和对应的右子树左移 */ 
for (i=d; i < t->d-1; i++) { 
t->k = t->k[i+1]; 
t->v = t->v[i+1]; 
t->p[i+1] = t->p[i+2]; 
} 
t->d--; 
node_sum--; 
} 
/* 
* 从一个键的右子树向左子树转移一些键,使两个子树平衡 
*/ 
void MoveLeftNode(btree t, int d) 
{ 
btree l,r; 
int m; /* 应转移的键的数目 */ 
int i,j; 
l = t->p[d]; 
r = t->p[d+1]; 
m = (r->d - l->d)/2; 

/* 把这个键下移到它的左子树 */ 
l->k[l->d] = t->k[d]; 
l->v[l->d] = t->v[d]; 
/* 把右子树的最左子树转移成左子树的最右子树 
* 从右子树向左子树移动 m-1 个键+子树对 */ 
for (j=m-2,i=l->d+m-1; j >= 0; j--,i--) { 
l->k = r->k[j]; 
l->v = r->v[j]; 
l->p = r->p[j]; 
} 
l->p[l->d+m] = r->p[m-1]; 
/* 把右子树的最左键提升到这个键的位置上 */ 
t->k[d] = r->k[m-1]; 
t->v[d] = r->v[m-1]; 
/* 把右子树中的所有键值和子树左移 m 个位置 */ 
r->p[0] = r->p[m]; 
for (i=0; id-m; i++) { 
r->k = r->k[i+m]; 
r->v = r->v[i+m]; 
r->p = r->p[i+m]; 
} 
r->p[r->d-m] = r->p[r->d]; 
l->d+=m; 
r->d-=m; 
} 
/* 
* 从一个键的左子树向右子树转移一些键,使两个子树平衡 
*/ 
void MoveRightNode(btree t, int d) 
{ 
btree l,r; 
int m; /* 应转移的键的数目 */ 
int i,j; 
l = t->p[d]; 
r = t->p[d+1]; 

m = (l->d - r->d)/2; 
/* 把右子树中的所有键值和子树右移 m 个位置 */ 
r->p[r->d+m]=r->p[r->d]; 
for (i=r->d-1; i>=0; i--) { 
r->k[i+m] = r->k; 
r->v[i+m] = r->v; 
r->p[i+m] = r->p; 
} 
/* 把这个键下移到它的右子树 */ 
r->k[m-1] = t->k[d]; 
r->v[m-1] = t->v[d]; 
/* 把左子树的最右子树转移成右子树的最左子树 */ 
r->p[m-1] = l->p[l->d]; 
/* 从左子树向右子树移动 m-1 个键+子树对 */ 
for (i=l->d-1,j=m-2; j>=0; j--,i--) { 
r->k[j] = l->k; 
r->v[j] = l->v; 
r->p[j] = l->p; 
} 
/* 把左子树的最右键提升到这个键的位置上 */ 
t->k[d] = l->k; 
t->v[d] = l->v; 
l->d-=m; 
r->d+=m; 
} 
/* 
* 把一个键和对应的右子树从一个节点中删除 
*/ 
void DelFromNode(btree t, int d) 
{ 
int i; 
/* 把所有大于要删除的键值的键左移 */ 
for(i=d; i < t->d-1; i++) { 
t->k = t->k[i+1]; 
t->v = t->v[i+1]; 
} 
t->d--; 
} 
/* 
* 建立有两个子树和一个键的根节点 
*/ 
btree NewRoot(btree t) 
{ 
btree temp; 
temp = (btree)malloc(sizeof(node)); 
temp->d = 1; 
temp->p[0] = t; 
temp->p[1] = NewTree; 
temp->k[0] = InsKey; 
temp->v[0] = InsValue; 
btree_level++; 
node_sum++; 
return(temp); 
} 
/* 
* 释放根节点,并返回它的最左子树 
*/ 
btree FreeRoot(btree t) 
{ 
btree temp; 
temp = t->p[0]; 
free(t); 
btree_level--; 
node_sum--; 
return temp; 
} 

void Error(int f,typekey key) 
{ 
if (f) 
printf("Btrees error: Insert %d! ",key); 
else 
printf("Btrees error: delete %d! ",key); 
} 

int height(btree t) 
{ 
return btree_level; 
} 

int count(btree t) 
{ 
return btree_count; 
} 
double payload(btree t) 
{ 
if (node_sum==0) 
return 1; 
return (double)btree_count/(node_sum*(2*M)); 
} 
btree deltree (btree t) 
{ 
level=btree_level; 
btree_level = 0; 
return delall(t); 

} 
btree delall(btree t) 
{ 
int i; 
level--; 
if (level >= 0) { 
for (i=0; i < t->d; i++) 
if (t->v != NULL) 
free(t->v); 
if (level > 0) 
for (i=0; i<= t->d ; i++) 
t->p=delall(t->p); 
free(t); 
} 
return NULL; 
} 

/* end of btrees.c */ 


另外网上的版本
参考地址:http://www.39g.com/html/kaifa/274/2008/11/046394910835.htm
#ifndef BTREE_H
#define BTREE_H

#include
#include
const int maxValue=10000;

/////////////////////////////////////////////////
//BTreeNodeB树的结点的定义
/////////////////////////////////////////////////
template
struct BTreeNode
{
        int n;                      //结点中关键码的个数
        BTreeNode* parent;       //当前结点的父结点的指针
       
        T* key;                     //m+1个元素存放关键码,其中key[0]和key[m]没有用
        BTreeNode**              //子树指针的结点数组(一共有m棵子树),m+1个元素
                subTree;                //最后一个元素subTree[m]在插入溢出的时候使用
        int** recptr;               //每个索引项中指向数据区相应记录起始地址的指针数组
    BTreeNode(int m)            //构造函数
        {
                n=0;                    //关键码个数初始化为0
                parent=NULL;            //父结点指针初始化为空
                key=new T[m+1];         //开辟关键码数组的空间
                subTree=new             //开辟子树的指针数组的内存空间
                        BTreeNode*[m+1]; //从p0,p1,p2,...p(m-1)共m棵子树
                for(int i=0;i<=m;i++)   
                        subTree中
        {
                for(int i=1;i<=n;i++)   //寻找插入关键码的位置
                {
                        if(x
                key中
                        subTree[j+1]=subTree[j];
                subTree<<" ";
        };
};
/////////////////////////////////BTree定义结束

/////////////////////////////////////////////////
//Triple结构 返回搜索结果用的三元组
/////////////////////////////////////////////////
template
struct Triple
{
        BTreeNode* r;            //结点指针
        int i;                      //关键码在当前结点中的序号
        int tag;                    //tag=0:搜索成功,tag=1:搜索失败
};
////////////////////////////////Triple结构结束

/////////////////////////////////////////////////
//BTree  B树的定义;
//m阶B树的根至少有两个子树,
//其他的结点至少应该有int(m/2)+1个子树
//所有的失败结点都在一个层次上
/////////////////////////////////////////////////
template
class BTree
{
private:
        BTreeNode* root;         //树根结点指针
        int m;                      //即B树的阶数
public:
        BTree(int x)                //空构造函数,构造一棵空x路的搜索树
        {root=NULL;m=x;};
        BTree(int x,BTreeNode* r)
        {root=r;m=x;};              //用指定的树根来初始化当前的m路搜索树
        void Insert(                //在树指定父结点的情况下插入一个结点
                BTreeNode* pa,       //指定要出入的位置的父结点
                BTreeNode* subTree,  //要插入的结点的指针
                int i);                 //表示插入到pa的第i个子树的位置
       
        Triple                   //搜索指定关键码x对应的结点
                Search(const T& x);
        void RootFirst(             //递归:以先根的方式遍历当前的搜索树
                BTreeNode* subTree);      
        void RootFirst()            //调用上面的递归函数
        {RootFirst(root);};
        bool Insert(const T& x);    //B树的插入操作
        void Display(
                BTreeNode* p,int i); //递归:以缩进的格式显示当前的B树
        void Display()              //调用上面的递归函数
        {cout<<"*****当前B树的缩进结构显示*****:"<
        Display(root,1);};
};
//////////////////////////////////////B树声明结束

/////////////////////////////////////////////////
//RootFirst()公有成员函数
//以先根的方式递归遍历当前B树
/////////////////////////////////////////////////
template
void BTree::RootFirst(BTreeNode* st)
{
        if(st!=NULL)
        {
            int n=st->n;
            cout<<"当前结点有"<
                    <<"个关键码:"<
            for(int k=1;k<=n;k++)       //输出当前结点的所有的关键码
                    cout<key[k]<<" ";
            cout<<
            for(int i=0;i<=n;i++)       //递归输出所有的子树
                RootFirst(st->subTree==x)      //如果找到
                        {
                                result.r=ptr;       //当前查找驻留的结点指针
                                result.i=i;         //查找成功的关键码
                                result.tag=1;       //是否查找成功
                                return result;
                        };
                        if(ptr->key;      //从失配的关键码左边的子树继续查找
        };
        /*如果查找失败*/
        result.r=pre;
        result.i=i;                     //可以在i-1和i之间进行插入
        result.tag=0;                   //查找失败

        return result;
};
/////////////////////////////////Search()函数结束

/////////////////////////////////////////////////
//Insert()公有成员函数  B树的插入操作
//把指定的关键码插入到B树中,使得仍然满足B树的要求
//首先对B树进行搜索,如果关键码已经存在则插入失败,
//否则执行插入,并按B树要求进行调整
//一般来说,执行插入的肯定是在叶子结点上进行
//但是如果查找成功的话,可能在非叶子结点上就结束了
/////////////////////////////////////////////////
template
bool BTree::Insert(const T& x)
{
        /*如果当前的B树是空的,就新建之*/
        if(root==NULL)                  //如果当前的B树是空的
        {
                root=new BTreeNode(m);   //新建一个结点
                root->Insert(x,NULL);            //把关键码插入到key[]数组第一个位置
                return true;
        };

    /*如果当前的B树不空,就搜索该树*/
        Triple Tp;                   //查找结果三元组
        Tp=Search(x);
        int IsIn=Tp.tag;
        if(IsIn==1)                     //关键码已经存在
        {
                cout<<"关键码已存在!"<
                return false;               //插入失败
        };

        /*插入关键码直到结点关键码不溢出为止*/
        BTreeNode* ptr=Tp.r;         //查找失败而驻留的结点
        int loc=Tp.i-1;                 //在k[loc]后进行插入
        int pkey=x;
        BTreeNode* p=NULL;           //随关键一起要插入的右子树的根结点
    do
        {
                ptr->Insert(pkey,p);        //把关键码和相关的新分裂的右结点插入当前结点
                if(ptr->n>m-1)              //如果关键码溢出,则需要进行调整
                {
                        /*以下处理结点的分裂*/
                        int k=ptr->key[m/2+1];  //提取出要上提的关键码
                        BTreeNode* right     //建立分裂后右边的结点
                                =new BTreeNode(m);
                        right->n=ptr->n-m/2-1;  //右结点的关键码个数
                        for(int i=m/2+2;i<=ptr->n;i++)
                                right->key //把右半边的关键码复制进入右结点
                                =ptr->key     
                                =ptr->subTree=k;     //插入新关键码
                                newp->subTree[0]    //新关键码左边的子树
                                        =ptr;
                                newp->subTree[1]    //新关键码右边的子树
                                        =right;
                                newp->n=1;          //新关键码个数为1
                                ptr->parent=newp;   //设置父结点指针
                            right->parent=newp;
                                root=newp;
                                return true;        //插入成功并结束
                        }
                        else                    //如果有父结点存在
                                ptr=ptr->parent;    //把上提的关键码继续插入父结点
                }
                else                        //不溢出则插入成功
                        return true;
        }while(ptr!=NULL);

        return true;
};
/////////////////////////Insert()公有成员函数结束

/////////////////////////////////////////////////
//Display()公有成员函数  
//递归:显示当前B树的缩进格式
/////////////////////////////////////////////////
template
void BTree::Display(BTreeNode* p,int i)
{
        if(p!=NULL)
        {
                for(int j=0;j
                        cout<<" ";          //控制缩进的格数
                cout<<"当前结点是:关键码个数"<n<<" "
                        <<"关键码的内容是";
                for(int k=1;k<=p->n;k++)//显示当前结点所有关键码
                        cout<key[k]<<" ";
            cout<
                for(k=0;k<=p->n;k++)    //递归显示子树,递归向后缩进
                        Display(p->subTree[k],i+5);
        };
};
////////////////////////////////Display()函数结束

#endif

#include"BTree.h"

/////////////////////////////////////////////////
//main()函数  测试B树的程序
/////////////////////////////////////////////////
int main()
{
        BTree BT(3);
        BT.Insert(53);      //依此在B树中插入关键码
        BT.Insert(75);
        BT.Insert(139);
        BT.Insert(49);
        BT.Insert(145);
        BT.Insert(36);
        BT.Insert(101);
        BT.Insert(150);
        BT.Insert(170);
        BT.Insert(25);
        BT.Insert(13);     

        BT.Display();      //显示当前B树的内容
        return 0;
};
///////////////////////////////////main()函数结束



你可能感兴趣的:(数据结构,C++,c,C#,J#)