B树实现

#include<stdio.h>
#include<stdlib.h>
#define M 3
//2-3b树的实现 3阶b树 
typedef struct btree{
	int count;//结点中元素个数 即关键字个数 
	int element[M-1];
	struct btree* next[M];
	bool isLeaf;//增加一个是否是叶子结点判断 
}*Btree; 

//打印
void print(Btree B){
	for(int i=0;i<B->count;i++){
		printf("%d ",B->element[i]);
	}
	printf("\n");
	for(int i=0;i<B->count+1;i++){
		if(B->next[i]!=NULL){
			print(B->next[i]);
		}
	}
} 

//插入
Btree insert(int X,Btree Root,Btree B){
	if(B==NULL){
		//B为空
		B=(Btree)malloc(sizeof(struct btree));
		B->element[0]=X;
		B->count=1;
		for(int i=0;i<B->count+1;i++){
			B->next[i]=NULL;
		}
		B->isLeaf=true;
		
		//print(Root); 
		return B;
	}else{
		//b不为空
		// 递归找出X的位置 然后回溯 
		Btree P=NULL;
		for(int i=0;i<B->count;i++){
			if(X<B->element[0]){
				//在最左边
				P=insert(X,Root,B->next[0]);
				break; 
			}else if(X>B->element[i]&&i+1<B->count&&X<=B->element[i+1]){
				//在i与i+1之间那个指针
				P=insert(X,Root,B->next[i+1]);
				break; 
			}else if(X>B->element[B->count-1]){
				//在最右边
				P=insert(X,Root,B->next[B->count]);
				break; 
			}
		}
		
		//开始回溯判断是否需要向上移
		if(P!=NULL&&B->count<(M-1)){
			//可以直接插入
			
			for(int i=0;i<B->count;i++){
				int flag=-1;
				//判断位置 
				if(P->element[P->count-1]<B->element[0]){
					flag=0;
				}else if(P->element[P->count-1]>B->element[i]&&i+1<B->count&&X<B->element[i+1]){
					flag=i+1;
				}else if(P->element[P->count-1]>B->element[B->count-1]){
					flag=B->count;
				}
				if(flag!=-1){
				
					for(int j=B->count;j>flag;j--){
						B->element[j]=B->element[j-1];
					} 
					B->element[flag]=P->element[P->count-1];
					B->count++; 
					P->count--;
					if(!P->isLeaf){
						//如果不是叶子 必须加一个指针去指向它
						for(int j=B->count;j>flag+1;j--){
							B->next[j]=B->next[j-1];
						}
						B->next[flag+1]=P;
					}else{
						//叶子 加入一个空指针
						B->next[B->count]=NULL; 
					} 
					break;
				}
			}
			//print(Root);
			if(B==Root){
				//如果是根,返回根
				return Root; 
				 
			}else{
				return NULL;
			}
			
		}else if(P!=NULL&&B->count==(M-1)){
				//已经满了 必须进行分裂 
				//分两种情况
				//1.B为根结点
				Btree Q=(Btree)malloc(sizeof(struct btree));
				Q->count=0;
				Q->isLeaf=false;
				
				//非根结点 
				
				//将该结点分成两个结点,找出中间的数据
				//先将中间元素替换出来
			//	if(P->element[count-1]==B->element[B->count/2]);
				int temp=-1;
				for(int i=0;i<B->count;i++){
				
					if(P->element[P->count-1]<=B->element[i]){
						//他的新位置就是 i
						//判断i是不是中间位置 
						if(i==B->count/2){
							//刚好为中间结点,直接返回去这个数值
							temp=P->element[P->count-1];
						}else if(i<B->count/2){
							//i在左部
							temp=B->element[B->count/2-1];
							for(int j=B->count/2-1;j>i;j--){
								B->element[j]=B->element[j-1];
							} 
							B->element[i]=P->element[P->count-1];
							
						}else if(i>B->count/2){
							//i在右部 
							temp=B->element[B->count/2];
							for(int j=B->count/2;j<i;j++){
								B->element[j]=B->element[j+1]; 
							}
							B->element[i]=P->element[P->count-1];
						} 
						
						break; 
					}else if(P->element[P->count-1]>B->element[B->count-1]){
						//大于最大的 在最右边 
						temp=B->element[B->count/2];
						for(int j=B->count/2;j<B->count-1;j++){
							B->element[j]=B->element[j+1];
						} 
						B->element[B->count-1]=P->element[P->count-1];
						break;
					}
				} 
				P->count--; 
		
				//新增的右部结点
				for(int j=B->count/2;j<B->count;j++){
					//将B结点的右部全部复制到Q中 
				 	Q->element[Q->count++]=B->element[j];
				 }
				 
				 if(!P->isLeaf){
				 	//非叶子结点,复制指针 
				 	Q->next[0]=P;
				 	for(int i=1;i<Q->count+1;i++){
				 		Q->next[i]=B->next[B->count/2+i];
				 	}
				 }else{
				 	//叶子结点,所有指针为空
					 for(int i=0;i<Q->count+1;i++){
					 	Q->next[i]=NULL;
					 } 
				 }
				  
				// Q->next[Q->count]=B->next[B->count];
				 //将该数值放在Q末尾
				 Q->element[Q->count++]=temp;
				 //b的数目减少一半
				 B->count-=B->count/2; 
				  
				
				if(B==Root){
					//为根时 必须形成新根 
					Btree newRoot=(Btree)malloc(sizeof(struct btree));
					newRoot->element[0]= Q->element[Q->count-1];
					newRoot->count=1;
					Q->count--;
					newRoot->next[0]=B;
					newRoot->next[1]=Q;
					newRoot->isLeaf=false;
					return newRoot;
				}
				
				return Q;
			} 
			if(B==Root){
				return B;	
			}else{
				return NULL;
			}
			
		} 
		
	
		
} 




int main(){
	Btree B=NULL;
	B=insert(22,B,B);
	printf("插入22:\n");
	print(B);
	B=insert(16,B,B);
	printf("插入16:\n");
	print(B);
	B=insert(41,B,B);
	printf("插入41\n");
	print(B);
	B=insert(58,B,B);
	printf("插入58\n");
	print(B);
	B=insert(8,B,B);
	printf("插入8\n");
	print(B);
	B=insert(11,B,B);
	printf("插入11\n");
	print(B);
	B=insert(12,B,B);
	printf("插入12\n");
	print(B);
	B=insert(16,B,B);
	printf("插入16\n");
	print(B);
	B=insert(17,B,B);
	printf("插入17\n");
	print(B);
	B=insert(22,B,B);
	printf("插入22\n");
	print(B);
	B=insert(23,B,B);
	printf("插入23\n");
	print(B);
	B=insert(31,B,B);
	printf("插入31\n");
	print(B);
	B=insert(41,B,B);
	printf("插入41\n");
	print(B);
	B=insert(52,B,B);
	printf("插入52\n");
	print(B);
	B=insert(58,B,B);
	printf("插入58\n");
	print(B);
	B=insert(59,B,B);
	printf("插入59\n");
	print(B);
	B=insert(61,B,B);
	printf("插入61\n");
	print(B);	
} 

点赞