花了蛮长时间实现的b树插入操作。有时间再实现其他操作。
#include <stdio.h> #include <stdlib.h> #define M 5 enum KeyStatus { Duplicate,SearchFailure,Success,InsertIt,LessKeys }; struct node { int n; /* n < M No. of keys in node will always less than order of B tree */ int keys[M-1]; /*array of keys*/ struct node *p[M]; /* (n+1 pointers will be in use) */ }*root=NULL; int pushIn(struct node* currentNode, int key , struct node* toInsertNode){ int i=0; for(i=currentNode->n -1;i>=-1;i--){ if(key < currentNode->keys[i]){ currentNode->keys[i+1]=currentNode->keys[i]; currentNode->p[i+2]=currentNode->p[i+1]; } else{ currentNode->keys[i+1]=key; currentNode->p[i+2]= toInsertNode; break; } } currentNode->n++; return 0; } int searchNode(struct node* currentNode, int key, int *downNodeIndex){ int i=0; for(i=currentNode->n -1;i>=0;i--){ if(key== currentNode->keys[i]){ return Success; }else if (key < currentNode->keys[i]){ if( i>0 ){ continue; }else { *downNodeIndex=0; } }else{ *downNodeIndex=i+1; break; } } return SearchFailure; } int splitNode(struct node* currentNode, int toInsertkey, struct node* toInsertNode, int *toLiftKey, struct node** toLiftNode ){ struct node* rightSplittedNode = calloc(sizeof(struct node),1); int i=0; int leftMedian=((M-1)/2 - 1); int rightMedian=(M-1)/2; if(toInsertkey > currentNode->keys[rightMedian]){ for(i=M-1;i>=rightMedian+2;i--){ pushIn(rightSplittedNode,currentNode->keys[i-1],currentNode->p[i]); currentNode->n--; } pushIn(rightSplittedNode,toInsertkey, toInsertNode); *toLiftKey=currentNode->keys[currentNode->n-1]; rightSplittedNode->p[0]=currentNode->p[currentNode->n]; *toLiftNode=rightSplittedNode; currentNode->n--; } else { for(i=M-1;i>=rightMedian+1;i--){ pushIn(rightSplittedNode,currentNode->keys[i-1],currentNode->p[i]); currentNode->n--; } pushIn(currentNode,toInsertkey, toInsertNode); *toLiftKey=currentNode->keys[currentNode->n-1]; rightSplittedNode->p[0]=currentNode->p[currentNode->n]; *toLiftNode=rightSplittedNode; currentNode->n--; } return 0; } int pushDown(struct node* currentNode, int toInsertKey, int* toLiftKey, struct node** toLiftNode){ int downNodeIndex; struct node* toInsertNode; int rc; if( NULL == currentNode){ *toLiftNode=NULL; (*toLiftKey)=toInsertKey; return InsertIt; } if( Success == searchNode(currentNode,toInsertKey, &downNodeIndex) ){ return Duplicate; } rc=pushDown(currentNode->p[downNodeIndex], toInsertKey, toLiftKey, toLiftNode); if(InsertIt !=rc){ return rc; } if( currentNode->n < M-1 ){ pushIn(currentNode,*toLiftKey,*toLiftNode); return Success; }else { toInsertKey=(*toLiftKey); toInsertNode=*toLiftNode; splitNode(currentNode,toInsertKey,toInsertNode,toLiftKey,toLiftNode); printf("toLiftNode %d ", toLiftNode); } return rc; } int insert(struct node * currentNode, int key){ struct node* toLiftNode; struct node* newRoot; int toLiftKey; int rc; toLiftNode=NULL; rc=pushDown(currentNode,key, &toLiftKey,&toLiftNode); if(InsertIt == rc ){ newRoot = calloc( sizeof(struct node),1); newRoot->n=1; newRoot->keys[0]=toLiftKey; newRoot->p[0]=root; newRoot->p[1]=toLiftNode; root=newRoot; rc=Success; } return rc; } void display(struct node *ptr, int blanks , int level) { if (ptr) { int i; printf("level:%d nodeAddr:%ld ",level, ptr); for(i=1; i<=blanks; i++) printf(" "); for (i=0; i < ptr->n; i++) printf("%d ",ptr->keys[i]); printf(" "); for (i=0; i <= ptr->n; i++) display(ptr->p[i], blanks+10,level+1); }/*End of if*/ }/*End of display()*/ int main(int argc, char const *argv[]) { insert(root,1*10); insert(root,2*10); insert(root,3*10); insert(root,4*10); display(root,0,0); insert(root,9); insert(root,5*10); insert(root,6*10); insert(root,7*10); display(root,0,0); insert(root,8*10); insert(root,8); insert(root,7); insert(root,6); insert(root,5); insert(root,4); insert(root,3); insert(root,2); insert(root,41); insert(root,42); insert(root,43); insert(root,44); display(root,0,0); return 0; }