B树数据结构的实现
来源:互联网 发布:网络歌曲2006 编辑:程序博客网 时间:2024/06/09 19:45
B树其实就是多路平衡树,主要用于外存储的一种数据结构。
B树的代码实现,主要参考《算法导论》,在看之前,自己尝试写了三遍,都不理想。
主要在于结点的插入和删除操作,如何不需要任何回溯。
给出代码如下:
#include "BTree.h"
#include <stdlib.h>
#include <stdio.h>
#define DEBUG_TREE
#ifdef DEBUG_TREE
#define Debug(x...) printf(x)
#else
#define Debug(x...)
#endif
/*
#ifndef TRUE
#define TRUE 1
#define FALSE 0
#endif
*/
#define M 2 /*M为B树的最小度数,每个非根的结点至少有t-1个关键字,每个非根的内结点至少有t个子女。每个结点至多有2t-1个关键字,一个内结点至多有2t个子女(t>=1)*/
struct BTreeNode
{
int num;//当前节点中键的数目
int leaf;//如果该结点是叶子,leaf为TRUE;如果该结点为内结点,为FALSE
void *key[2*M-1];//键
struct BTreeNode *p[2*M];//指向子结点的指针
};
void print_int( BTree Tree )
{
int i;
for( i =0; i < Tree->num; i++)
{
printf("%d ",(int )Tree->key[i]);
}
}
BTree Create( void )
{
BTree x;
x = (BTree *)malloc(sizeof(struct BTreeNode));
x->leaf = 1;//TRUE;
x->num = 0;
return x;
}
BTree Search( BTree x, void *k)
{
int i = 0;
}
BTree Split_Child( BTree x, int i, BTree y)
{
int j;
BTree z;
z = (BTree *)malloc(sizeof(struct BTreeNode));
z->leaf = y->leaf;
z->num = M-1;
for( j = 0; j < M-1; j++)
z->key[j] = y->key[j+M];
if( !(y->leaf) )
for( j = 0; j < M; j++)
z->p[j] = y->p[j+M];
y->num = M-1;
for( j = x->num; j > i; j--)
x->p[j+1] = x->p[j];
x->p[i+1] = z;
for( j = x->num-1; j > i-1; j--)
x->key[j+1] = x->key[j];
x->key[i] = y->key[M-1];
x->num += 1;
return x;
}
BTree Insert( BTree T, void *key)
{
if( T->num == 2*M-1 )
{
BTree s;
s = (BTree *)malloc(sizeof(struct BTreeNode));
s->leaf = 0;//FALSE;
s->num = 0;
s->p[0] = T;
s = Split_Child(s,0,T);
s = Insert_Nonfull(s,key);
return s;
}
else
{
T = Insert_Nonfull(T,key);
return T;
}
}
BTree Insert_Nonfull( BTree x, void *key)
{
int i;
i = x->num;
if( x->leaf )
{
while( i >= 1 && key < x->key[i-1] )
{
x->key[i] = x->key[i-1];
i--;
}
x->key[i] = key;
x->num += 1;
}
else
{
while( i >= 1 && key < x->key[i-1])
{
i--;
}
if( x->p[i]->num == 2*M-1 )
{
Split_Child(x,i,x->p[i]);
if( key > x->key[i] )
i += 1;
}
Insert_Nonfull(x->p[i],key);
}
return x;
}
//合并
BTree Merge_Child( BTree x, int i, BTree y, BTree z )
{
int j;
y->num = 2*M - 1;
for( j = M; j < 2*M - 1; j++)
{
y->key[j] = z->key[j-M];
}
y->key[M-1] = x->key[i];
if( !( y->leaf ) )
{
for( j = M; j <= 2*M - 1; j++)
{
y->p[j] = z->p[j-M];
}
}
for( j = i + 1; j < x->num; j++)
{
x->key[j-1] = x->key[j];
x->p[j] = x->p[j+1];
}
x->num -= 1;
}
//查找前驱
BTree Search_PreDecessor( BTree y)
{
int i;
BTree x;
x = (BTree *)malloc(sizeof(struct BTreeNode));
x = y;
i = x->num;
while( !(x->leaf) )
{
x = x->p[i];
i = x->num;
}
return x->key[i-1];
}
//查找后继
BTree Search_Successor( BTree z)
{
BTree x;
x = (BTree *)malloc(sizeof(struct BTreeNode));
x = z;
while( !(x->leaf) )
{
x = x->p[0];
}
return x->key[0];
}
//转移到右边的子结点
BTree Shift_To_Right_Child( BTree x, int i, BTree y, BTree z )
{
int j;
z->num += 1;
j = z->num - 1;
while( j > 0 )
{
z->key[j] = z->key[j-1];
j -= 1;
}
z->key[0] = x->key[i];
x->key[i] = y->key[y->num-1];
if( !(z->leaf) )
{
j = z->num;
while( j > 0 )
{
z->p[j] = z->p[j-1];
j -= 1;
}
z->p[0] = y->p[y->num];
}
y->num -= 1;
}
//转移到左边的子结点
BTree Shift_To_Left_Child( BTree x, int i, BTree y, BTree z )
{
int j;
y->num += 1;
y->key[y->num-1] = x->key[i];
x->key[i] = z->key[0];
j = 1;
while( j < z->num )
{
z->key[j-1] = z->key[j];
j += 1;
}
if( !(z->leaf) )
{
y->p[y->num] = z->p[0];
j = 1;
while( j <= z->num )
{
z->p[j-1] = z->p[j];
j += 1;
}
}
z->num -= 1;
}
BTree Delete_Nonone( BTree x, void *key)
{
int i,j;
i = 1;
int prev,next;
BTree y,z,p;
y = (BTree *)malloc(sizeof(struct BTreeNode));
z = (BTree *)malloc(sizeof(struct BTreeNode));
p = (BTree *)malloc(sizeof(struct BTreeNode));
if( x->leaf ) //如果在叶子结点,直接删除
{
while( i <= x->num && key > x->key[i-1] )
i++;
if( key == x->key[i-1] )
{
for( j = i; j < x->num; j++)
{
x->key[j-1] = x->key[j];
}
x->num -= 1;
}
else
perror("wrong\n");
}
else //在内结点中
{
while( i <= x->num && key > x->key[i-1] )
i++;
y = x->p[i-1];
if( i <= x->num )
z = x->p[i];
if( key == x->key[i-1] )
{
if( y->num > (M-1) )
{
prev = Search_PreDecessor(y);
Delete_Nonone(y,prev);
x->key[i-1] = prev;
}
else if( z->num > (M-1) )
{
next = Search_Successor(z);
Delete_Nonone(z,next);
x->key[i-1] = next;
}
else
{
Merge_Child(x,i-1,y,z);
//Delete_Nonode(y,key);
}
}
else
{
if( i > 1 )
p = x->p[i-2];
if( y->num == M-1 )
{
if( i > 1 && p->num > M-1 )
Shift_To_Right_Child(x,i-2,p,y);
else if( i <= x->num && z->num > M-1 )
Shift_To_Left_Child(x,i-1,y,z);
else if( i > 1 )
{
Merge_Child(x,i-2,p,y);
y = p;
}
else
{
Merge_Child(x,i-1,y,z);
}
Delete_Nonone(y,key);
}
else
{
Delete_Nonone(y,key);
}
}
}
}
BTree Delete( BTree x, void *key )
{
BTree y,z;
y = (BTree *)malloc(sizeof(struct BTreeNode));
z = (BTree *)malloc(sizeof(struct BTreeNode));
if( x->num == 1 )
{
y = x->p[0];
z = x->p[1];
if( y->num == M-1 && z->num == M-1 )
{
Merge_Child(x,0,y,z);
Delete_Nonone(y,key);
return y;
}
else
{
Delete_Nonone(x,key);
return x;
}
}
else
{
Delete_Nonone(x,key);
return x;
}
}
int Tree_node_pre_order( BTree Tree, TreePrintData Tree_Print_Data )
{
int i;
Tree_Print_Data(Tree);
printf("\n");
for( i = 0; i <= Tree->num; i++)
{
if( NULL != Tree->p[i] )
{
Tree_node_pre_order(Tree->p[i],Tree_Print_Data);
//if( i == Tree->num)
// printf(" end");
}
}
printf("\n");
return 1;
}
- B树数据结构的实现
- 数据结构-B树实现
- 【数据结构】平衡搜索树之---B树的算法实现
- mysql索引的实现数据结构(B-树)
- 数据结构与算法——B树的C++实现
- 数据结构实验B树的C++代码实现
- 【数据结构】B-/B+树的分析
- 【数据结构】B树的详解
- 【数据结构】B树的特性
- 数据结构 B+树c代码实现
- B+树的实现
- B+树的实现
- B树的实现
- B树的实现
- b树的实现
- B树的实现
- B树的实现
- 数据结构:神奇的B树实现解析(有图有代码有真相!!!)
- 第六章堆排序之“堆排序HEAPSORT”
- 第二部分 核心动画基础---第三章 基础动画
- javaMail发送邮件(文本)
- B树
- Hibernate对象三种状态
- B树数据结构的实现
- 讣告:传智播客创始人张孝祥老师年前意外辞世
- 程序从VC6移植到VS2005环境下的常见问题(一)
- 程序从VC6移植到VS2005环境下的常见问题(二)
- 笔试题目之字符串中将大写字母移动至末尾
- 泛型剖析
- vi有用的命令
- 张老师,您走好!
- Cascaded Light Propagation Volumes for Real-Time Indirect Illumination