算法导论 B树(附带节点高度)

#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树
    原文地址: https://blog.csdn.net/niewei1986/article/details/73935659
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞