B树算法与实现C语言描述Word格式.docx
- 文档编号:22282747
- 上传时间:2023-02-03
- 格式:DOCX
- 页数:14
- 大小:19.15KB
B树算法与实现C语言描述Word格式.docx
《B树算法与实现C语言描述Word格式.docx》由会员分享,可在线阅读,更多相关《B树算法与实现C语言描述Word格式.docx(14页珍藏版)》请在冰豆网上搜索。
*每个键的右子树中的所有的键都大于等于这个键。
*叶子节点中的每个键都没有子树。
/*当M等于1时也称为2-3树
*
+----+----+
|k0|k1|
+-+----+----+---
|p0|p1|p2|
+----+----+----+
externintbtree_disp;
/*查找时找到的键在节点中的位置*/
externchar*InsValue;
/*与要插的键相对应的值*/
externbtreesearch(typekey,btree);
externbtreeinsert(typekey,btree);
externbtreedelete(typekey,btree);
externintheight(btree);
externintcount(btree);
externdoublepayload(btree);
externbtreedeltree(btree);
/*endofbtrees.h*/
/*******************************************************/
/*btrees.c*/
#include<
stdlib.h>
stdio.h>
#include"
btrees.h"
btreesearch(typekey,btree);
btreeinsert(typekey,btree);
btreedelete(typekey,btree);
intheight(btree);
intcount(btree);
doublepayload(btree);
btreedeltree(btree);
staticvoidInternalInsert(typekey,btree);
staticvoidInsInNode(btree,int);
staticvoidSplitNode(btree,int);
staticbtreeNewRoot(btree);
staticvoidInternalDelete(typekey,btree);
staticvoidJoinNode(btree,int);
staticvoidMoveLeftNode(btreet,int);
staticvoidMoveRightNode(btreet,int);
staticvoidDelFromNode(btreet,int);
staticbtreeFreeRoot(btree);
staticbtreedelall(btree);
staticvoidError(int,typekey);
intbtree_disp;
char*InsValue=NULL;
staticintflag;
/*节点增减标志*/
staticintbtree_level=0;
/*多路树的高度*/
staticintbtree_count=0;
/*多路树的键总数*/
staticintnode_sum=0;
/*多路树的节点总数*/
staticintlevel;
/*当前访问的节点所处的高度*/
staticbtreeNewTree;
/*在节点分割的时候指向新建的节点*/
statictypekeyInsKey;
/*要插入的键*/
btreesearch(typekeykey,btreet)
{
inti,j,m;
level=btree_level-1;
while(level>
=0){
for(i=0,j=t->
d-1;
i<
j;
m=(j+i)/2,(key>
t->
k[m])?
(i=m+1):
(j=m));
if(key==t->
k[i]){
btree_disp=i;
returnt;
}
if(key>
k[i])/*i==t->
d-1时有可能出现*/
i++;
t=t->
p[i];
level--;
returnNULL;
btreeinsert(typekeykey,btreet)
level=btree_level;
InternalInsert(key,t);
if(flag==1)
/*根节点满之后,它被分割成两个半满节点*/
t=NewRoot(t);
/*树的高度增加*/
voidInternalInsert(typekeykey,btreet)
if(level<
0){/*到达了树的底部:
指出要做的插入*/
NewTree=NULL;
/*这个键没有对应的子树*/
InsKey=key;
/*导致底层的叶子节点增加键值+空子树对*/
btree_count++;
flag=1;
/*指示上层节点把返回的键插入其中*/
return;
k[i]){
Error(1,key);
/*键已经在树中*/
flag=0;
k[i])/*i==t->
InternalInsert(key,t->
p[i]);
if(flag==0)
/*有新键要插入到当前节点中*/
if(t->
d<
2*M){/*当前节点未满*/
InsInNode(t,i);
/*把键值+子树对插入当前节点中*/
/*指示上层节点没有需要插入的键值+子树,插入过程结束*/
else/*当前节点已满,则分割这个页面并把键值+子树对插入当前节点中*/
SplitNode(t,i);
/*继续指示上层节点把返回的键值+子树插入其中*/
*把一个键和对应的右子树插入一个节点中
voidInsInNode(btreet,intd)
inti;
/*把所有大于要插入的键值的键和对应的右子树右移*/
for(i=t->
d;
i>
d;
i--){
t->
k[i]=t->
k[i-1];
v[i]=t->
v[i-1];
p[i+1]=t->
/*插入键和右子树*/
k[i]=InsKey;
p[i+1]=NewTree;
v[i]=InsValue;
d++;
*前件是要插入一个键和对应的右子树,并且本节点已经满
*导致分割这个节点,插入键和对应的右子树,
*并向上层返回一个要插入键和对应的右子树
voidSplitNode(btreet,intd)
{
inti,j;
btreetemp;
typekeytemp_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[i];
v[j]=t->
v[i];
p[j+1]=t->
p[i+1];
for(i=d-1,j=d-M-2;
j>
=0;
/*把节点的最右子树转移成新节点的最左子树*/
p[0]=t->
p[M+1];
/*在新节点中插入键和右子树*/
k[d-M-1]=InsKey;
p[d-M]=NewTree;
v[d-M-1]=InsValue;
/*设置要插入上层节点的键和值*/
InsKey=t->
k[M];
InsValue=t->
v[M];
else{/*d<
=M*/
/*把从2*M-1到M的M个键值+子树对转移到新节点中*/
if(d==M)/*要插入当前节点的正中间*/
/*把要插入的子树作为新节点的最左子树*/
p[0]=NewTree;
/*直接把要插入的键和值返回给上层节点*/
else{/*(d<
M)要插入当前节点的左半部分*/
/*把节点当前的最右子树转移成新节点的最左子树*/
p[M];
/*保存要插入上层节点的键和值*/
temp_k=t->
k[M-1];
temp_v=t->
v[M-1];
for(i=M-1;
i--){
/*在节点中插入键和右子树*/
k[d]=InsKey;
p[d+1]=NewTree;
v[d]=InsValue;
InsKey=temp_k;
InsValue=temp_v;
d=M;
d=M;
NewTree=temp;
node_sum++;
btreedelete(typekeykey,btreet)
InternalDelete(key,t);
d==0)
/*根节点的子节点合并导致根节点键的数目随之减少,
*当根节点中没有键的时候,只有它的最左子树可能非空*/
t=FreeRoot(t);
voidInternalDelete(typekeykey,btreet)
btreel,r;
intlvl;
0){
Error(0,key);
/*在整个树中未找到要删除的键*/
k[i]){/*找到要删除的键*/
v[i]!
=NULL)
free(t->
v[i]);
/*释放这个节点包含的值*/
if(level==0){/*有子树为空则这个键位于叶子节点*/
DelFromNode(t,i);
btree_count--;
/*指示上层节点本子树的键数量减少*/
}else{/*这个键位于非叶节点*/
lvl=level-1;
/*找到前驱节点*/
r=t->
while(lvl>
0)
r=r->
p[r->
d];
lvl--;
k[i]=r->
k[r->
d-1];
v[i]=r->
v[r->
r->
d-1]=NULL;
key=r->
elseif(key>
InternalDelete(key,t->
/*调整平衡*/
p[i]->
M){
if(i==t->
d)/*在最右子树中发生了删除*/
i--;
/*调整最右键的左右子树平衡*/
l=t->
p[i];
if(r->
d>
M)
MoveLeftNode(t,i);
elseif(l->
MoveRightNode(t,i);
else{
JoinNode(t,i);
/*继续指示上层节点本子树的键数量减少*/
/*指示上层节点本子树的键数量没有减少,删除过程结束*/
*合并一个节点的某个键对应的两个子树
voidJoinNode(btreet,intd)
p[d];
p[d+1];
/*把这个键下移到它的左子树*/
l->
k[l->
d]=t->
k[d];
v[l->
v[d];
/*把右子树中的所有键值和子树转移到左子树*/
for(j=r->
d-1,i=l->
d+r->
j>
=0;
j--,i--){
k[i]=r->
k[j];
v[i]=r->
v[j];
p[i]=r->
p[j];
p[l->
d+1]=r->
d+=r->
d+1;
/*释放右子树的节点*/
free(r);
/*把这个键右边的键和对应的右子树左移*/
for(i=d;
i<
i++){
k[i+1];
v[i+1];
p[i+2];
d--;
node_sum--;
*从一个键的右子树向左子树转移一些键,使两个子树平衡
voidMoveLeftNode(btreet,intd)
intm;
/*应转移的键的数目*/
m=(r->
d-l->
d)/2;
/*把右子树的最左子树转移成左子树的最右子树
*从右子树向左子树移动m-1个键+子树对*/
for(j=m-2,i=l->
d+m-1;
=0;
k[i]=
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 算法 实现 语言 描述