#include <stdio.h>
#include <stdlib.h>
#define t 3
typedef struct BNodeType
{
int n;
char key[2*t];
bool leaf;
BNodeType *c[2*t+1];
int height;
}BNode,*pBNode;
typedef struct
{
pBNode root;
}bTree,*pBTree;
typedef struct
{
pBNode x;
int i;
}sType,*pStype;
pBNode allocateNode()
{
pBNode node=(pBNode)malloc(sizeof(BNode));
node->n=0;
node->height=0;
return node;
}
void b_tree_create(pBTree T)
{
pBNode x=allocateNode();
x->leaf=true;
x->n=0;
x->height=0;
T->root=x;
}
void b_tree_split_child(pBNode x,int i)
{
pBNode z=allocateNode();
pBNode y=x->c[i];
z->leaf=y->leaf;
z->height=y->height;
z->n=t-1;
for(int j=1;j<=t-1;j++)
{
z->key[j]=y->key[j+t];
}
if(!y->leaf)
{
for(int j=1;j<=t;j++)
{
z->c[j]=y->c[j+t];
}
}
y->n=t-1;
for(int j=x->n+1;j>=i+1;j--)
{
x->c[j+1]=x->c[j];
}
x->c[i+1]=z;
for(int j=x->n;j>=i;j--)
{
x->key[j+1]=x->key[j];
}
x->key[i]=y->key[t];
x->n++;
}
void b_tree_insert_nonfull(pBNode x, char k)
{
int i=x->n;
if(x->leaf)
{
while(i>=1 && k<x->key[i])
{
x->key[i+1]=x->key[i];
i--;
}
x->key[i+1]=k;
x->n++;
}
else
{
while(i>=1 && k<x->key[i])
{
i--;
}
i++;
if(x->c[i]->n==2*t-1)
{
b_tree_split_child(x,i);
if(k>x->key[i])
i++;
}
b_tree_insert_nonfull(x->c[i],k);
}
}
void b_tree_insert(pBTree T,char k)
{
pBNode r=T->root;
if(r->n==2*t-1)
{
pBNode s=allocateNode();
T->root=s;
s->leaf=false;
s->n=0;
s->height=r->height+1;
s->c[1]=r;
b_tree_split_child(s,1);
b_tree_insert_nonfull(s,k);
}
else
b_tree_insert_nonfull(r,k);
}
pStype b_tree_search(pBNode x,char k)
{
int i=1;
while(i<=x->n && k>x->key[i])
i++;
if(k==x->key[i])
{
pStype s=(pStype)malloc(sizeof(sType));
s->x=x;
s->i=i;
return s;
}
else if(x->leaf)
return NULL;
else
return b_tree_search(x->c[i],k);
}
//这个前驱函数假设x为非叶节点,包含叶节点的前驱函数需要用到父节点,这里用不到所以没写
char preDecessor(pBNode x,int i)
{
pBNode y=x->c[i];
while(y && !y->leaf)
y=y->c[y->n+1];
return y->key[y->n];
}
//这个后继函数假设x为非叶节点,包含叶节点的后继函数需要用到父节点,这里用不到所以没写
char successor(pBNode x,int i)
{
pBNode y=x->c[i+1];
while(y && !y->leaf)
y=y->c[1];
return y->key[1];
}
void b_tree_delete(pBNode x,char k,pBTree T)
{
int i=1;
while(i<=x->n && k>x->key[i])
i++;
if(k==x->key[i])
{
//case 1
if(x->leaf)
{
for(int j=i;j<x->n;j++)
{
x->key[j]=x->key[j+1];
}
x->n--;
}
//case 2
else
{
//case 2.a
pBNode y=x->c[i],z=x->c[i+1];
if(y->n>=t)
{
char pre=preDecessor(x,i);
x->key[i]=pre;
b_tree_delete(x->c[i],pre,T);
}
//case 2.b
else if(z->n>=t)
{
char suc=successor(x,i);
x->key[i]=suc;
b_tree_delete(x->c[i+1],suc,T);
}
//case 2.c
else
{
//处理y中key数组
int j=y->n+1;
y->key[j]=x->key[i];
for(int m=1;m<=z->n;m++)
{
y->key[j+m]=z->key[m];
}
//处理y子节点
j=y->n+1;
for(int m=1;m<=z->n+1;m++)
{
y->c[j+m]=z->c[m];
}
//处理y中key的个数
y->n+=z->n+1;
//处理x中key数组
for(int m=i;m<x->n;m++)
x->key[m]=x->key[m+1];
//处理x子节点
for(int m=i+1;m<x->n+1;m++)
x->c[m]=x->c[m+1];
//处理x中key的个数
x->n--;
if(x->n==0)
{
free(x);
T->root=y;
}
free(z);
b_tree_delete(y,k,T);
}
}
}
//case 3
else
{
pBNode y=x->c[i];
if(y->n<t)
{
//case 3.a
if(i>1 && x->c[i-1] && x->c[i-1]->n>=t)
{
//z是y的左兄弟
pBNode z=x->c[i-1];
char lc=z->key[z->n];
char xc=x->key[i-1];
//处理x
x->key[i-1]=lc;
//处理y
for(int m=y->n;m>=1;m--)
{
y->key[m+1]=y->key[m];
}
y->key[1]=xc;
for(int m=y->n+1;m>=1;m--)
{
y->c[m+1]=y->c[m];
}
y->c[1]=z->c[z->n+1];
y->n++;
//处理z
z->n--;
}
else if(i<x->n+1 && x->c[i+1] && x->c[i+1]->n>=t)
{
//z是y的右兄弟
pBNode z=x->c[i+1],y=x->c[i];
char rc=z->key[1];
char xc=x->key[i];
//处理x
x->key[i]=rc;
//处理y
y->key[y->n+1]=xc;
y->c[y->n+2]=z->c[1];
y->n++;
//处理z
for(int m=1;m<z->n;m++)
{
z->key[m]=z->key[m+1];
}
for(int m=1;m<z->n+1;m++)
{
y->c[m]=y->c[m+1];
}
z->n--;
}
//case 3.b
else
{
if(i>1 && x->c[i-1] && x->c[i-1]->n<t)
{
//z是y的左兄弟
pBNode z=x->c[i-1];
//处理y中key数组
for(int m=y->n;m>=1;m--)
y->key[m+t]=y->key[m];
for(int m=1;m<=z->n;m++)
{
y->key[m]=z->key[m];
}
y->key[t]=x->key[i-1];
//处理y子节点
for(int m=y->n+1;m>=1;m--)
y->c[m+t]=y->c[m];
for(int m=1;m<=z->n+1;m++)
{
y->c[m]=z->c[m];
}
//处理y中key的个数
y->n+=z->n+1;
//处理x中key数组
for(int m=i-1;m<x->n;m++)
x->key[m]=x->key[m+1];
//处理x子节点
for(int m=i-1;m<x->n+1;m++)
x->c[m]=x->c[m+1];
//处理x中key的个数
x->n--;
if(x->n==0)
{
free(x);
T->root=y;
}
free(z);
}
else if(i<x->n+1 && x->c[i+1] && x->c[i+1]->n<t)
{
//z是y的右兄弟
pBNode z=x->c[i+1];
//处理y中key数组
y->key[t]=x->key[i];
for(int m=1;m<=z->n;m++)
{
y->key[m+t]=z->key[m];
}
//处理y子节点
for(int m=1;m<=z->n+1;m++)
{
y->c[m+t]=z->c[m];
}
//处理y中key的个数
y->n+=z->n+1;
//处理x中key数组
for(int m=i;m<x->n;m++)
x->key[m]=x->key[m+1];
//处理x子节点
for(int m=i+1;m<x->n+1;m++)
x->c[m]=x->c[m+1];
//处理x中key的个数
x->n--;
if(x->n==0)
{
free(x);
T->root=y;
}
free(z);
}
}
}
b_tree_delete(y,k,T);
}
}
void printNode(pBNode x)
{
for(int i=1;i<=x->n;i++)
{
printf("%c,%d ",x->key[i],x->height);
}
printf("\n");
}
pBTree initTree()
{
pBTree T=(pBTree)malloc(sizeof(bTree));
T->root=allocateNode();
pBNode x=T->root;
x->n=4;
x->height=1;
x->leaf=false;
x->key[1]='G';
x->key[2]='M';
x->key[3]='P';
x->key[4]='X';
pBNode c1=allocateNode();
c1->n=4;
c1->height=0;
c1->leaf=true;
c1->key[1]='A';
c1->key[2]='C';
c1->key[3]='D';
c1->key[4]='E';
pBNode c2=allocateNode();
c2->n=2;
c2->height=0;
c2->leaf=true;
c2->key[1]='J';
c2->key[2]='K';
pBNode c3=allocateNode();
c3->n=2;
c3->height=0;
c3->key[1]='N';
c3->key[2]='O';
pBNode c4=allocateNode();
c4->n=5;
c4->height=0;
c4->key[1]='R';
c4->key[2]='S';
c4->key[3]='T';
c4->key[4]='U';
c4->key[5]='V';
pBNode c5=allocateNode();
c5->n=2;
c5->height=0;
c5->key[1]='Y';
c5->key[2]='Z';
x->c[1]=c1;
x->c[2]=c2;
x->c[3]=c3;
x->c[4]=c4;
x->c[5]=c5;
return T;
}
void main()
{
pBTree T=initTree();
b_tree_insert(T,'B');
b_tree_insert(T,'Q');
b_tree_insert(T,'L');
b_tree_insert(T,'F');
b_tree_delete(T->root,'F',T);
b_tree_delete(T->root,'M',T);
b_tree_delete(T->root,'G',T);
//b_tree_delete(T->root,'D',T);
//b_tree_delete(T->root,'B',T);
pStype s;
s=b_tree_search(T->root,'P');
printNode(s->x);
s=b_tree_search(T->root,'C');
printNode(s->x);
s=b_tree_search(T->root,'E');
printNode(s->x);
getchar();
}
算法导论 B树(附带节点高度)
原文作者:B树
原文地址: https://blog.csdn.net/niewei1986/article/details/73935659
本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
原文地址: https://blog.csdn.net/niewei1986/article/details/73935659
本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。