`
canofy
  • 浏览: 829743 次
  • 性别: Icon_minigender_1
  • 来自: 北京、四川
社区版块
存档分类
最新评论

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()函数结束



分享到:
评论

相关推荐

    B+树的c语言代码实现

    与B树相比,B+树的所有叶子节点都位于同一层,且叶子节点之间通过指针相互连接,这使得B+树非常适合范围查询和顺序访问。 #### 三、代码结构分析 1. **文件头注释**: - 作者:bysvking - 时间:2012年5月 - ...

    b+b-树c语言版

    本压缩包“b+b-树c语言版”提供了C语言实现的B+树相关功能,包括创建、删除、查询和插入操作。以下是关于B+树及其C语言实现的详细知识。 **B+树简介** B+树(B Plus Tree)是一种自平衡的树,它的设计目的是为了...

    b+/-树的实现源代码

    **B+树与B-树概述** B+树和B-树是计算机科学中用于数据库和文件系统等数据存储的重要数据结构,它们主要用于高效地管理大量数据,特别是当数据需要在磁盘等慢速存储介质上进行操作时。这两种树都是自平衡的,能保持...

    B.rar_B+树_B+树 C++实现_B树_visual c

    - **BPlusTree.cpp**:可能包含了B+树的实现代码,包括节点类定义、插入、删除和查找函数等。 - **DemoB.cpp**:可能是演示如何使用B+树的示例代码,展示了如何创建、插入和查询数据。 - **BPlusTree.h**:头文件,...

    B+树作为数据库的索引

    提供的压缩包文件" B+树 "可能包含了B+树的C语言实现,用户可以下载后进行编译运行,以理解和实践B+树的构建和查询过程。这样的实践有助于加深对B+树原理的理解,以及如何将其应用于实际数据库索引中。 总结来说,B...

    B+树的实现算法c++版

    相比B树,B+树具有以下特点: 1. **所有数据都存储在叶子节点**:B+树的内部节点只用于索引,而数据实际存储在叶子节点中。 2. **叶子节点之间通过指针相连**:这使得按照关键字顺序遍历变得非常高效。 #### 二、B...

    B+Tree的一种实现方式

    描述中提到的"自己在别人代码的基础上改出来的代码"应该是一个B+树的实现。这个实现可能包含了创建B+树、插入键值对、删除键值对以及查找特定键值的功能。虽然具体代码没有给出,但通常B+树的实现会包括以下几个关键...

    b+数实现代码

    根据给定的信息,本文将详细解释B+树的原理、特点以及其实现代码中的关键部分。这不仅适用于那些对数据库索引技术感兴趣的学习者,也是希望深入理解B+树算法的专业人士的重要参考资料。 ### B+树简介 B+树是一种自...

    C语言开发 BTREE 数据文件索引程序库.rar_B+树索引_C璇█_C语言_搜索_查找

    这个名为"C语言开发 BTREE 数据文件索引程序库.rar"的压缩包内容似乎包含了一个C语言实现的B+树索引库,能够支持基本的查找、插入和删除操作。 B+树是一种自平衡的多路搜索树,它的特点在于所有叶子节点都在同一层...

    B树的C语言实现,代码比较条理

    标题"B树的C语言实现,代码比较条理"指出这是一个关于B树的数据结构实现项目,采用C语言编写,并且代码结构清晰、有条理性。这表明该实现可能易于理解,适合学习和研究B树的原理以及C语言编程。 描述中的"可以...

    用C语言实现的完整B树

    本主题将详细探讨如何用C语言实现一个完整的B树,并介绍相关接口的设计与实现。 B树的基本概念: 1. B树是一种多路搜索树,每个节点可以有多个子节点。通常,节点的孩子数范围是从2到M,其中M是一个固定的常数。 2....

    在Linux环境下,通过C语言编程实现四个程序,分别为:堆排序、用栈实现表达式求值、B+树和红黑树+源代码+文档说明+实验报告

    在Linux环境下,通过C语言编程实现四个程序,分别为:堆排序、用栈实现表达式求值、B+树和红黑树+源代码+文档说明+实验报告 - 小白不懂运行,下载完可以私聊问,可远程教学 该资源内项目源码是个人的课程设计,代码...

    B树+B树实现的图书管理系统(C语言)(广东工业大学课程设计2019).zip

    《基于B树的图书管理系统——C语言实现及广工课程设计解析》 在信息技术领域,数据结构是构建高效算法的基础,而B树作为一种自平衡的查找树,因其高效的查找、插入和删除性能,在数据库系统和文件系统中广泛应用。...

    高效B树算法原理与代码实现

    根据给定的信息,本文将详细解析B树的基本概念、特性以及与B+树的主要区别,并进一步探讨B树在实际中的应用及其代码实现。 ### B树基本概念 B树是一种自平衡的多路搜索树,其设计目的是为了减少或优化磁盘操作次数...

    cpp-QT实现B树可视化

    在本文中,我们将深入探讨如何使用C++与QT库来实现B树的可视化。B树( Balanced Tree)是一种自平衡的查找树数据结构,广泛应用于数据库和文件系统中,以保持数据的高效检索。QT是一个跨平台的C++图形用户界面应用...

    b_plus_tree.zip_b 树_b+tree_b_plus_tree_b树数据库_galles b plus tree

    在`b_plus_tree.c`这个源代码文件中,我们可以期待看到实现B+树基本操作的函数,如初始化、插入、删除和查找。这些操作是理解B+树工作原理的关键部分。 - **初始化:** 初始化B+树可能涉及到创建根节点,设置初始的...

    B-树的源代码实现

    数据结构课程设计是做了玩儿的。 C风格的B-树,支持宏定义N阶

    B树算法与实现(C语言描述).doc

    B树的实现通常使用C语言,以下是B树算法的实现代码: ```c typedef int typekey; typedef struct btnode { int d; /* 节点中键的数目 */ typekey k[2*M]; /* 键 */ char *v[2*M]; /* 值 */ struct btnode *p[2*...

    数据结构 哈夫曼树C语言源代码

    本文将对一份经典的哈夫曼树C语言实现代码进行详细的分析与解释。 #### 二、核心概念与术语 - **哈夫曼树**:一种特殊的二叉树,用于构建最优前缀码。 - **带权路径长度**:从根到叶子结点的路径上所有结点的权值之...

    B树的代码实现(C语言版本)

    btree.c

Global site tag (gtag.js) - Google Analytics