B+樹C語言實現
阿新 • • 發佈:2018-12-23
B+樹C語言版本,編譯通過,測試正確
插入部分實現,其中刪除和插入類似
#include<stdlib.h> #include<stdio.h> #include<stdbool.h> #include<string.h> #define M 2 //The minimum degree of this B+ tree #define KeyNumMax 2*M-1//Maximum Key Number #define KeyNumMin M-1//Minimum Key Number // typedef int KeyType; typedef struct Node* Position; typedef struct rNode* Search_Insert_Position_Result; typedef struct List_Node* Path_List; //data struct typedef struct Node{ bool IsLeaf; int KeyNum; KeyType Key[KeyNumMax]; Position PtrChild[KeyNumMax]; Position Next_Leaf_Node; }Node; typedef struct rNode{ Position Insert_Position; int Key_Position; }rNode; typedef struct List_Node{ Path_List Pre_List_Node; Path_List Next_List_Node; Position Path_List_Tree_Node; int The_Ith_Child_of_Parent; }List_Node; //global variable Position ROOT; Path_List Path_List_Header; Path_List Path_List_Tail; //Make Node Position Make_New_Node() { Position New_Node=(Position)malloc(sizeof(Node)); New_Node->IsLeaf=false; New_Node->KeyNum=0; New_Node->Next_Leaf_Node=NULL; return New_Node; } //Search the Leaf Node to Insert Search_Insert_Position_Result BPT_Search(Position Current_Node,KeyType Key,int Index) { int i=0; Path_List Path_List_Node=(Path_List)malloc(sizeof(List_Node)); Path_List_Node->Path_List_Tree_Node=Current_Node; Path_List_Tail->Pre_List_Node->Next_List_Node=Path_List_Node; Path_List_Node->Pre_List_Node=Path_List_Tail->Pre_List_Node; Path_List_Node->Next_List_Node=Path_List_Tail; Path_List_Tail->Pre_List_Node=Path_List_Node; Path_List_Node->The_Ith_Child_of_Parent=Index; //printf("%d\n",Path_List_Tail->Pre_List_Node->Path_List_Tree_Node->KeyNum); //if(Path_List_Tail->Pre_List_Node->Pre_List_Node==Path_List_Header) // puts("here"); Search_Insert_Position_Result Insert_Node_Position=(Search_Insert_Position_Result)malloc(sizeof(rNode)); if(Current_Node->IsLeaf==true) { while(Key>Current_Node->Key[i]&&i<Current_Node->KeyNum) i++; Insert_Node_Position->Insert_Position=Current_Node; Insert_Node_Position->Key_Position=i; return Insert_Node_Position; } else { while(i<Current_Node->KeyNum&&Key>Current_Node->Key[i]) { i++; } if(i==Current_Node->KeyNum) i--; Search_Insert_Position_Result Insert_Position_1=BPT_Search(Current_Node->PtrChild[i],Key,i); return Insert_Position_1; } } //function of Node Splict,case 1:leaf node; case 2:internal node; Position BplusTree_Node_Split(Position Current_Node) { int i=0; Position New_Node=Make_New_Node(); New_Node->IsLeaf=Current_Node->IsLeaf; if(Current_Node->IsLeaf==true){ New_Node->Next_Leaf_Node=Current_Node->Next_Leaf_Node; Current_Node->Next_Leaf_Node=New_Node; for(i=0;i<M-1;i++) New_Node->Key[i]=Current_Node->Key[i+M]; Current_Node->KeyNum=M; New_Node->KeyNum=M-1; } else{ for(i=0;i<M-1;i++) { New_Node->Key[i]=Current_Node->Key[i+M]; New_Node->PtrChild[i]=Current_Node->PtrChild[i+M]; } Current_Node->KeyNum=M; New_Node->KeyNum=M-1; } return New_Node; } //Insert Non_Full leaf node int BplusTree_Node_Insert_Non_Full(Position Current_Node,KeyType Key) { int i=0; int Index_Old=Current_Node->Key[Current_Node->KeyNum-1]; while(i<Current_Node->KeyNum&&Key>Current_Node->Key[i]) { i++; } if(i==Current_Node->KeyNum){ Current_Node->Key[Current_Node->KeyNum]=Key; } else{ int j; for(j=Current_Node->KeyNum;j>i;j--) Current_Node->Key[j]=Current_Node->Key[j-1]; Current_Node->Key[i]=Key; } Current_Node->KeyNum++; return Index_Old; } //Insert internal node void BplusTree_Internal_Node_Insert(Position Current_Node,KeyType Key,Path_List N) { int i=0; int j=0; int k=0; ////////////////////////////////////// if(Current_Node->KeyNum==KeyNumMax){ Position New_Node=BplusTree_Node_Split(Current_Node); while(i<M&&Key>Current_Node->Key[i]) i++; if(i==M){ while(k<New_Node->KeyNum&&Key>New_Node->Key[k]) k++; for(j=M-1;j>k;j--){ New_Node->Key[j]=New_Node->Key[j-1]; New_Node->PtrChild[j]=New_Node->PtrChild[j-1]; }/////////////////////////////////////////////////////////////////////////////////// New_Node->Key[k]=Key; New_Node->PtrChild[k]=N->Next_List_Node->Path_List_Tree_Node; New_Node->KeyNum++; N->Pre_List_Node->Path_List_Tree_Node->PtrChild[N->The_Ith_Child_of_Parent]=New_Node; if(k==M-1){ Path_List New_N=Path_List_Header->Next_List_Node; while(New_N->Path_List_Tree_Node!=Current_Node){///////////////////////////////////////////// for(k=0;k<New_N->Path_List_Tree_Node->KeyNum;k++) { if(New_N->Path_List_Tree_Node->Key[k]==New_Node->Key[M-2]) New_N->Path_List_Tree_Node->Key[k]=Key; } New_N=New_N->Next_List_Node; } } //printf("%d%d\n",N->Pre_List_Node->Path_List_Tree_Node->Key[0],N->Pre_List_Node->Path_List_Tree_Node->Key[1]); //BplusTree_Internal_Node_Insert(N->Pre_List_Node->Path_List_Tree_Node,Current_Node->Key[M-1],N->Pre_List_Node); } else{ for(j=M;j>i;j--){ Current_Node->Key[j]=Current_Node->Key[j-1]; Current_Node->PtrChild[j]=Current_Node->PtrChild[j-1]; } Current_Node->Key[i]=Key; Current_Node->PtrChild[i]=N->Next_List_Node->Path_List_Tree_Node; Current_Node->KeyNum++; N->Pre_List_Node->Path_List_Tree_Node->PtrChild[N->The_Ith_Child_of_Parent]=New_Node; //if(N->Pre_List_Node->Path_List_Tree_Node==ROOT){ //New_Node////////////////////////////////////////////////////////// //} //BplusTree_Internal_Node_Insert(N->Pre_List_Node->Path_List_Tree_Node,Current_Node->Key[M],N->Pre_List_Node); } } else{ //printf("%d\n",Key); while(i<Current_Node->KeyNum&&Key>Current_Node->Key[i]) i++; //printf("%d\n",i); //printf("%d\n",Current_Node->PtrChild[0]->KeyNum); for(j=Current_Node->KeyNum;j>i;j--){ Current_Node->Key[j]=Current_Node->Key[j-1]; Current_Node->PtrChild[j]=Current_Node->PtrChild[j-1]; } //printf("%d\n",Current_Node->Key[1]); Current_Node->Key[i]=Key; Current_Node->PtrChild[i]=N->Next_List_Node->Path_List_Tree_Node; Current_Node->KeyNum++; } } //Insert leaf node Position Bplus_Tree_Insert(Position P,KeyType Key) { Path_List_Header->Pre_List_Node=Path_List_Tail; Path_List_Header->Next_List_Node=Path_List_Tail; Path_List_Tail->Pre_List_Node=Path_List_Header; Path_List_Tail->Next_List_Node=Path_List_Header; int i=0; if(P==NULL) { P=Make_New_Node(); P->Key[0]=Key; P->KeyNum=1; P->IsLeaf=true; return P; } int Index_Old; Path_List N; Search_Insert_Position_Result Insert_Node_Position=BPT_Search(P,Key,0); Position Current_Node=Insert_Node_Position->Insert_Position; //printf("%d\n",Current_Node->Key[0]); if(Current_Node->KeyNum==KeyNumMax) { Position New_Node=BplusTree_Node_Split(Current_Node); if(Path_List_Tail->Pre_List_Node->Pre_List_Node!=Path_List_Header) Path_List_Tail->Pre_List_Node->Pre_List_Node->Path_List_Tree_Node->PtrChild[Path_List_Tail->Pre_List_Node->The_Ith_Child_of_Parent]=New_Node; if(Insert_Node_Position->Key_Position>M){ Index_Old=BplusTree_Node_Insert_Non_Full(New_Node,Key); if(Current_Node==ROOT){ Position New_Root=Make_New_Node(); New_Root->Key[0]=Index_Old>Key?Index_Old:Key; New_Root->PtrChild[0]=New_Node; New_Root->KeyNum++; P=New_Root; } else if(Index_Old<Key){ N=Path_List_Header->Next_List_Node; while(N->Path_List_Tree_Node->IsLeaf!=true){ for(i=0;i<N->Path_List_Tree_Node->KeyNum;i++) { if(N->Path_List_Tree_Node->Key[i]==Index_Old) N->Path_List_Tree_Node->Key[i]=Key; } N=N->Next_List_Node; } } N=Path_List_Tail->Pre_List_Node->Pre_List_Node; if(N==Path_List_Header) BplusTree_Internal_Node_Insert(P,Current_Node->Key[M-1],N); else{ while(N->Path_List_Tree_Node->KeyNum==KeyNumMax&&N->Path_List_Tree_Node!=P) { //BplusTree_Internal_Node_Insert(N->Path_List_Tree_Node,Current_Node->Key[M-1],N);/////////// BplusTree_Internal_Node_Insert(N->Path_List_Tree_Node,N->Next_List_Node->Path_List_Tree_Node->Key[M-1],N); N=N->Pre_List_Node; } if(N->Path_List_Tree_Node==P&&N->Path_List_Tree_Node->KeyNum==KeyNumMax){ Position New_Root_1=Make_New_Node(); New_Node=BplusTree_Node_Split(N->Path_List_Tree_Node); New_Root_1->PtrChild[0]=N->Path_List_Tree_Node; New_Root_1->PtrChild[1]=New_Node; New_Root_1->Key[0]=N->Path_List_Tree_Node->Key[M-1]; New_Root_1->Key[1]=New_Node->Key[M-2]; //printf("%d%d\n",New_Root_1->Key[0],New_Root_1->Key[1]); P=New_Root_1; New_Node->KeyNum=M-1; N->Path_List_Tree_Node->KeyNum=M; P->KeyNum=2; Path_List_Header->Next_List_Node->Path_List_Tree_Node=New_Node; //return P; } //printf("%d\n",Current_Node->Key[M-1]); BplusTree_Internal_Node_Insert(N->Path_List_Tree_Node,N->Next_List_Node->Path_List_Tree_Node->Key[M-1],N); } return P; } else{ Index_Old=BplusTree_Node_Insert_Non_Full(Current_Node,Key); if(Current_Node==ROOT){ Position New_Root=Make_New_Node(); New_Root->Key[0]=New_Node->Key[M-2]; New_Root->PtrChild[0]=New_Node; New_Root->KeyNum++; P=New_Root; } /*else if(Index_Old<Key){ N=Path_List_Header->Next_List_Node; while(N->Path_List_Tree_Node->IsLeaf!=true){//???????????????????????? for(i=0;i<N->Path_List_Tree_Node->KeyNum;i++) { if(N->Path_List_Tree_Node->Key[i]==Index_Old) N->Path_List_Tree_Node->Key[i]=Key; } N=N->Next_List_Node; } }*/ N=Path_List_Tail->Pre_List_Node->Pre_List_Node; if(N==Path_List_Header) BplusTree_Internal_Node_Insert(P,Current_Node->Key[M-1],N); else{ while(N->Path_List_Tree_Node->KeyNum==KeyNumMax&&N->Path_List_Tree_Node!=P) { //BplusTree_Internal_Node_Insert(N->Path_List_Tree_Node,Current_Node->Key[M-1],N);/////////// BplusTree_Internal_Node_Insert(N->Path_List_Tree_Node,N->Next_List_Node->Path_List_Tree_Node->Key[M],N); N=N->Pre_List_Node; } if(N->Path_List_Tree_Node==P&&N->Path_List_Tree_Node->KeyNum==KeyNumMax){ Position New_Root_1=Make_New_Node(); New_Node=BplusTree_Node_Split(N->Path_List_Tree_Node); New_Root_1->PtrChild[0]=N->Path_List_Tree_Node; New_Root_1->PtrChild[1]=New_Node; New_Root_1->Key[0]=N->Path_List_Tree_Node->Key[M-1]; New_Root_1->Key[1]=New_Node->Key[M-2]; //printf("%d%d\n",New_Root_1->Key[0],New_Root_1->Key[1]); P=New_Root_1; New_Node->KeyNum=M-1; N->Path_List_Tree_Node->KeyNum=M; P->KeyNum=2; Path_List_Header->Next_List_Node->Path_List_Tree_Node=New_Node; //return P; } // printf("%d\n",N->Next_List_Node->Path_List_Tree_Node->KeyNum); BplusTree_Internal_Node_Insert(N->Path_List_Tree_Node,N->Next_List_Node->Path_List_Tree_Node->Key[N->Next_List_Node->Path_List_Tree_Node->KeyNum-1],N); } return P; } } else{ Index_Old=BplusTree_Node_Insert_Non_Full(Current_Node,Key); if(Index_Old<Key){ N=Path_List_Header->Next_List_Node; while(N->Path_List_Tree_Node->IsLeaf!=true){ for(i=0;i<N->Path_List_Tree_Node->KeyNum;i++) { if(N->Path_List_Tree_Node->Key[i]==Index_Old) N->Path_List_Tree_Node->Key[i]=Key; } N=N->Next_List_Node; } return P; } } return P; } //bfs tree walk void Bplus_Tree_Walk(Position ROOT) { int i; int QueueNumber=0; Position Queue[100]; Position CurrentNode; Queue[QueueNumber]=ROOT; QueueNumber++; Queue[QueueNumber]=NULL; QueueNumber++; while(QueueNumber>0) { CurrentNode=Queue[0]; QueueNumber--; i=0; while(i<QueueNumber){ Queue[i]=Queue[i+1]; i++; } i=0; if(CurrentNode==NULL) { printf("\n"); } else { i=0; while(i<CurrentNode->KeyNum) { printf("|"); printf("%d",CurrentNode->Key[i]); i++; } if(CurrentNode!=NULL&&CurrentNode->IsLeaf==false){ i=0; while(i<CurrentNode->KeyNum) { Queue[QueueNumber]=CurrentNode->PtrChild[i]; QueueNumber++; i++; } Queue[QueueNumber]=NULL; QueueNumber++; } printf("| "); } } } int main() { freopen("Bplus_Tree.out","w",stdout); ROOT=NULL; Path_List_Header=(Path_List)malloc(sizeof(List_Node)); Path_List_Tail=(Path_List)malloc(sizeof(List_Node)); Path_List_Header->Path_List_Tree_Node=NULL; Path_List_Tail->Path_List_Tree_Node=NULL; if(Path_List_Header->Next_List_Node==Path_List_Tail) puts("Head to tail"); if(Path_List_Tail->Pre_List_Node==Path_List_Header) puts("Tail to head"); ROOT=Bplus_Tree_Insert(ROOT,1); ROOT=Bplus_Tree_Insert(ROOT,2); ROOT=Bplus_Tree_Insert(ROOT,3); ROOT=Bplus_Tree_Insert(ROOT,4); ROOT=Bplus_Tree_Insert(ROOT,5); ROOT=Bplus_Tree_Insert(ROOT,6); ROOT=Bplus_Tree_Insert(ROOT,7); ROOT=Bplus_Tree_Insert(ROOT,8); ROOT=Bplus_Tree_Insert(ROOT,9); ROOT=Bplus_Tree_Insert(ROOT,10); ROOT=Bplus_Tree_Insert(ROOT,11); ROOT=Bplus_Tree_Insert(ROOT,18); ROOT=Bplus_Tree_Insert(ROOT,19); ROOT=Bplus_Tree_Insert(ROOT,12); ROOT=Bplus_Tree_Insert(ROOT,13); ROOT=Bplus_Tree_Insert(ROOT,14); ROOT=Bplus_Tree_Insert(ROOT,15); ROOT=Bplus_Tree_Insert(ROOT,16); ROOT=Bplus_Tree_Insert(ROOT,17); ROOT=Bplus_Tree_Insert(ROOT,30); ROOT=Bplus_Tree_Insert(ROOT,25); ROOT=Bplus_Tree_Insert(ROOT,28); Bplus_Tree_Walk(ROOT); return 0; }