b树的实现

Posted 友哥

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了b树的实现相关的知识,希望对你有一定的参考价值。

花了蛮长时间实现的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\n", 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("\n");
        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;
}

 

以上是关于b树的实现的主要内容,如果未能解决你的问题,请参考以下文章

B-树的java实现

二叉排序树的实现

代码的鲁棒性:树的子结构

数据结构——树的简单操作集合

b树的实现

读书笔记-MySQL运维内参08-索引实现原理1