首页 > 学技术 > 技术网文 > C/C++ > 正文

[原创] 我写的一个btree实现的代码


来源 chinaunix.net kuqin整理

一直没有找到实现的代码,前段时间写了一个,数据库里的索引就是用的整个东西实现的



     1  /* btree implementation example ,any bug send mail to serenaiad@126.com
     2  
     3  You can modify,destribute this code , please reserve this note when destribute this code.
     4  */
     5  #include <stdio.h>
     6  #include <stdlib.h>
     7
     8
     9  #define NODESIZE       3                   //number of values  each node
    10  #define TOTALNODES     100                 //number of nodes
    11
    12
    13  typedef enum {
    14  inner,leaf
    15  } nodetype;
    16
    17  typedef struct{
    18  int nodeindex;
    19  int valueindex;
    20  int pointer;
    21  } valuelocation;
    22
    23  typedef struct{
    24  nodetype type;
    25  int valuecount;
    26  int values[NODESIZE];
    27  int pointers[NODESIZE+1];
    28  } node;
    29
    30  int freenode;               //the first free node
    31  int rootnode;               //root node
    32  node nodes[TOTALNODES];     //nodes array
    33
    34
    35  int CreateBtree();
    36  int LoadBtree();
    37  int WriteBtree();
    38  int InsertValue(int value,int pointer);
    39  int DeleteValue(int value);
    40  char *GetSysTime();
    41
    42
    43  /* find the node index for new value to insert  ,return  -1 if the btree is empty(no value in it) */
    44  int FindNewValueNode(int value,int path[]);
    45
    46  /* 一个中间节点中,要搜索指定的值,需要查找向那个指针所指向的节点去搜索,
    47  这里返回下一级节点指针在指针数组中的index                       */
    48  int FindValuePtIndex(int value,node* n);
    49
    50  /* 把一个节点,指针对插入到一个中间节点去
    51  index: 这个节点的index, value: 值, pointer 指针
    52  path: 从根节点到叶节点的全路径
    53  */
    54  void InsertPtToInnerNode(int index,int value,int pointer, int path[]);
    55
    56  void DeletePtInnerNode(int index,int minvalue,int pointer,int path[]);
    57  void PrintBtree();
    58  void PrintNode(int index);
    59
    60  /* 从空余节点中取一个全新的节点 */
    61  int GetFreeNode();
    62  int ReleaseNode(int index);
    63
    64  /* 查找某值,如果值存在,返回这个值所在节点的index , 如果不存在,返回 -1 */
    65  valuelocation FindValue(int value);
    66
    67  /* 当某个根节点的最小值改变了以后,他的某个父节点的值需要调整 
    68  path - access path ; indexstart - 从哪一级开始 ; val - 老值 ; newval - 新值 */
    69  void UpdateAncestorNodeMinValue(int path[],int posstart,int val,int newval);
    70  /* 经过一个节点可以访问到的最小值 */
    71  int MinValueThroughNode(int index);
    72  void Usage();
    73  void test();
    74  int FindNodeValueIndex(int value, node* n);
    75  void DeleteValueInLeafNode(node* n,int value);
    76  int GetPosInAccessPath(int index , int path[]);
    77  void DeletePointerInInnerNode(node* n,int index, int path[], int pointer,int minvalue);
    78  //验证一个节点的的值和指针是否正确 
    79  int VerifyNode(int index);
    80  int VerifyBtree();
    81
    82  int main(int argc, char* argv[])
    83  {
    84  valuelocation l;
    85          if(argc==1)
    86          {
    87                  Usage();
    88                  return 0;
    89          }
    90          if(strcmp(argv[1],"-create")==0)
    91                  CreateBtree();
    92          if(strcmp(argv[1],"-i")==0)
    93          {
    94                  LoadBtree();
    95                  if(InsertValue(atoi(argv[2]),atoi(argv[3]))!=0)
    96                          printf("Insert Value Failed.\n");
    97                  WriteBtree();
    98          }
    99          if(strcmp(argv[1],"-p")==0)
   100                  PrintBtree();
   101          if(strcmp(argv[1],"-pn")==0)
   102          {
   103                  LoadBtree();
   104                  PrintNode(atoi(argv[2]));
   105          }
   106          if(strcmp(argv[1],"-test")==0)
   107                  test();
   108          if(strcmp(argv[1],"-f")==0)
   109          {
   110                  LoadBtree();
   111                  l=FindValue(atoi(argv[2]));
   112                  if(l.nodeindex==-1 )
   113                          printf("Value %d not found.\n",atoi(argv[2]));
   114                  else
   115                          printf("Value %d found , pointer:%d\n",atoi(argv[2]),l.pointer);
   116          }
   117          if(strcmp(argv[1],"-d")==0)
   118          {
   119                  LoadBtree();
   120                  if(DeleteValue(atoi(argv[2]))!=0)
   121                          printf("delete value failed.\n");
   122                  WriteBtree();
   123          }
   124          if(strcmp(argv[1],"-verify")==0)
   125          {
   126                  LoadBtree();
   127                  VerifyBtree();
   128          }
   129          return 0;
   130  }
   131
   132  int CreateBtree()
   133  {
   134  FILE* f;
   135  node n;
   136  int itmp;
   137  int i;
   138          if((f=fopen("btree.dat","w"))==NULL)
   139          {
   140                  printf("Can't open file!\n");
   141                  return 1;
   142          }
   143          freenode=0;
   144          rootnode=-1;
   145          fwrite(&freenode,1,sizeof(int),f);
   146          fwrite(&rootnode,1,sizeof(int),f);
   147          for (i=0;i<TOTALNODES;i++)
   148          {
   149                  n.pointers[NODESIZE]=i+1;
   150                  if(i==(TOTALNODES-1))
   151                          n.pointers[NODESIZE]=-1;
   152                  fwrite(&n,1,sizeof(n),f);
   153          }
   154          fclose(f);
   155  }
   156
   157  void Usage()
   158  {
   159          printf("Usage: btree -create | -i value | -d value | -e value\n");
   160          printf("-create : create new btree file.\n");
   161          printf("-p : print btree.\n");
   162          printf("-pn nodeindex : print node nodeindex\n");
   163          printf("-i value : insert new value.\n");
   164          printf("-d value : delete a value.\n");
   165          printf("-f value : find if value exists.\n");
   166          printf("-verify : verify if the btree is correct.\n");
   167  }
   168
   169  int LoadBtree()
   170  {
   171  FILE* f;
   172          if((f=fopen("btree.dat","r"))==NULL)
   173          {
   174                  printf("Can't open file.\n");
   175                  return 1;
   176          }
   177          fread(&freenode,1,sizeof(int),f);
   178          fread(&rootnode,1,sizeof(int),f);
   179          fread(nodes,1,sizeof(node)*TOTALNODES,f);
   180          fclose(f);
   181          return 0;
   182  }
   183  int WriteBtree()
   184  {
   185  FILE* f;
   186          if((f=fopen("btree.dat","w"))==NULL)
   187          {
   188                  printf("Can't open file.\n");
   189                  return 1;
   190          }
   191          fwrite(&freenode,1,sizeof(int),f);
   192          fwrite(&rootnode,1,sizeof(int),f);
   193          fwrite(nodes,1,sizeof(node)*TOTALNODES,f);
   194          fclose(f);
   195          return 0;
   196  }
   197
   198  int InsertValue(int value,int pointer)
   199  {
   200  node* n;
   201  node* newNode;
   202  node* pn;
   203  int i,inode,insertPos,ni,pi;
   204  int tmpvalues[NODESIZE+1];
   205  int tmppointers[NODESIZE+1];
   206  int halfsize=(NODESIZE+1)/2;
   207  int path[101];
   208  int pathindex;
   209  int minval,newval;
   210  int pos;
   211
   212          insertPos=-1;
   213          inode=FindNewValueNode(value,path); //先找出需要往那个节点里插入值
   214
   215          if( inode==-1) // 如果这是btree中的第一个值
   216          {
   217                  ni=GetFreeNode();
   218                  n=nodes+ni;
   219                  rootnode=ni;
   220                  n->type=leaf;
   221                  n->valuecount=1;
   222                  n->values[0]=value;
   223                  n->pointers[0]=pointer;
   224                  n->pointers[NODESIZE]=-1;
   225          }
   226          else
   227          {
   228                  n=nodes+inode;
   229                  for(i=0;i<n->valuecount;i++)
   230                  {
   231                          if(value==n->values)
   232                                  return 1;
   233                  }
   234                  for(i=1;i<=path[0];i++)
   235                  {
   236                          if(inode==path)
   237                                  pathindex=i;
   238                  }
   239                  if (n->valuecount==NODESIZE) // the leaf node needs to split
   240                  {
   241                          ni=GetFreeNode();
   242                          newNode=nodes+ni;
   243                          newNode->type=leaf;
   244                          newNode->valuecount=NODESIZE+1-halfsize;
   245                          for(i=0;i<NODESIZE;i++)
   246                          {
   247                                  if(value< n->values)
   248                                  {
   249                                          insertPos=i;
   250                                          break;
   251                                  }
   252                          }
   253                          if(insertPos==-1)
   254                                  insertPos=NODESIZE;
   255                          if (insertPos==0)
   256                          {
   257                                  minval=n->values[0];
   258                                  newval=value;
   259                                  UpdateAncestorNodeMinValue(path,pathindex-1,minval,newval);
   260                          }
   261                          for(i=0;i<insertPos;i++)
   262                          {
   263                                  tmpvalues=n->values;
   264                                  tmppointers=n->pointers;
   265                          }
   266                          tmpvalues[insertPos]=value;
   267                          tmppointers[insertPos]=pointer;
   268                          for(i=NODESIZE-1;i>=insertPos;i--)
   269                          {
   270                                  tmpvalues[i+1]=n->values;
   271                                  tmppointers[i+1]=n->pointers;
   272                          }
   273                          for(i=0;i<halfsize;i++)
   274                          {
   275                                  n->values=tmpvalues;
   276                                  n->pointers=tmppointers;
   277                          }
   278                          n->valuecount=halfsize;
   279                          for(i=halfsize;i<NODESIZE+1;i++)
   280                          {
   281                                  newNode->values[i-halfsize]=tmpvalues;
   282                                  newNode->pointers[i-halfsize]=tmppointers;
   283                          }
   284                          newNode->pointers[NODESIZE]=n->pointers[NODESIZE];
   285                          n->pointers[NODESIZE]=ni;
   286                          if(inode==path[1]) // if the node is root node 
   287                          {
   288                                  pi=GetFreeNode();
   289                                  rootnode=pi;  // change new root node
   290                                  pn=nodes+pi;
   291                                  pn->type=inner;
   292                                  pn->valuecount=1;
   293                                  pn->values[0]=newNode->values[0];
   294                                  pn->pointers[0]=inode;
   295                                  pn->pointers[1]=ni;
   296                          }
   297                          else // 如果这个叶节点不是根节点,那么需要向它的父节点插入值和指针
   298                          {
   299                                  InsertPtToInnerNode(path[pathindex-1],newNode->values[0],ni,path);
   300                          }
   301
   302                  }
   303                  else  // the leaf node has enough space
   304                  {
   305                          for(i=0;i < n->valuecount;i++)
   306                          {
   307                                  if(value < n->values)
   308                                  {
   309                                          insertPos=i;
   310                                          break;
   311                                  }
   312                          }
   313                          if(insertPos==-1)
   314                          {
   315                                  insertPos=n->valuecount;
   316                          }
   317                          if(insertPos==0)
   318                          {
   319                                  minval=n->values[0];
   320                                  newval=value;
   321                          }
   322                          for(i=n->valuecount;i>insertPos;i--)
   323                          {
   324                                  n->values=n->values[i-1];
   325                                  n->pointers=n->pointers[i-1];
   326                          }
   327                          n->values[insertPos]=value;
   328                          n->pointers[insertPos]=pointer;
   329                          n->valuecount=n->valuecount+1;
   330                          if(insertPos==0)
   331                          {
   332                                  UpdateAncestorNodeMinValue(path,pathindex-1,minval,newval);
   333                          }
   334                  }
   335          }
   336          return 0;
   337  }
   338





 Serenaiad 回复于:2006-12-23 01:59:23


   339
   340  int FindNewValueNode(int value,int path[])
   341  {
   342  node* n;
   343  node* root;
   344  int i,ni;
   345          if (rootnode== -1 )
   346                  return -1;
   347          else
   348          {
   349                  path[0]=1;
   350                  path[1]=rootnode;
   351                  root=nodes+rootnode;
   352                  n=root;
   353                  ni=rootnode;
   354                  while(n->type==inner)
   355                  {
   356                          ni=n->pointers[FindValuePtIndex(value,n)];
   357                          n=nodes+ni;
   358                          path[0]=path[0]+1;
   359                          path[path[0]]=ni;
   360                  }
   361                  return ni;
   362          }
   363  }
   364
   365  int FindValuePtIndex(int value,node* n)
   366  {
   367  int count;
   368  int i;
   369          count=n->valuecount;
   370
   371          for(i=0;i<count;i++)
   372          {
   373                  if(value < n->values)
   374                          return i;
   375          }
   376          return count;
   377  }
   378
   379
   380  int GetFreeNode()
   381  {
   382  node* n;
   383  int i;
   384          n=nodes+freenode;
   385          i=freenode;
   386          freenode=n->pointers[NODESIZE];
   387          return i;
   388  }
   389
   390  void InsertPtToInnerNode(int index,int value,int pointer, int path[])
   391  {
   392  node* n;
   393  node* newnode;
   394  node* parentnode;
   395  int tmpvalues[NODESIZE+1];
   396  int tmppointers[NODESIZE+1+1];
   397  int halfsize;
   398  int i,j,insertpos,ni,pi; // ni-new node index, pi-parent node index
   399  int pathindex; 
   400  int valueinsert; //the value insert to parent node
   401
   402          n=nodes+index;
   403          insertpos=-1;
   404          halfsize=(NODESIZE+1)/2;
   405          if(n->valuecount==NODESIZE) // the node is full, need to split
   406          {
   407                  ni=GetFreeNode();
   408                  newnode=nodes+ni;
   409                  newnode->type=inner;
   410                  for(i=0;i<NODESIZE;i++)
   411                  {
   412                          if(value<n->values)
   413                          {
   414                                  insertpos=i;
   415                                  break;
   416                          }
   417                  }
   418                  if(insertpos==-1)
   419                          insertpos=NODESIZE;
   420
   421                  tmppointers[0]=n->pointers[0];
   422                  for(i=0;i<insertpos;i++)
   423                  {
   424                          tmpvalues=n->values;
   425                          tmppointers[i+1]=n->pointers[i+1];
   426                  }
   427                  tmpvalues[insertpos]=value;
   428                  tmppointers[insertpos+1]=pointer;
   429                  for(i=insertpos;i<NODESIZE;i++)
   430                  {
   431                          tmpvalues[i+1]=n->values;
   432                          tmppointers[i+1+1]=n->pointers[i+1];
   433                  }
   434
   435                  n->valuecount=halfsize;
   436                  for(i=0;i<halfsize;i++)
   437                  {
   438                          n->values=tmpvalues;
   439                          n->pointers[i+1]=tmppointers[i+1];
   440                  }
   441
   442                  for(i=halfsize;i<NODESIZE+1;i++)
   443                  {
   444                          newnode->values[i-halfsize]=tmpvalues;
   445                          newnode->pointers[i-halfsize]=tmppointers[i+1];
   446                  }
   447                  newnode->valuecount=NODESIZE+1-halfsize; //中间的那个值插入到上级节点
   448                  valueinsert=newnode->values[0];
   449                  for(i=1;i<newnode->valuecount;i++)
   450                  {
   451                          newnode->values[i-1]=newnode->values;
   452                  }
   453                  newnode->valuecount=newnode->valuecount-1;
   454
   455                  for(i=1 ;i<=path[0];i++)
   456                  {
   457                          if(index==path)
   458                                  pathindex=i;
   459                  }
   460                  if(pathindex==1) // if this inner node is root node 
   461                  {
   462                          pi=GetFreeNode();
   463                          rootnode=pi;
   464                          parentnode=nodes+pi;
   465                          parentnode->type=inner;
   466                          parentnode->valuecount=1;
   467                          parentnode->values[0]=valueinsert;
   468                          parentnode->pointers[0]=index;
   469                          parentnode->pointers[1]=ni;
   470                  }
   471                  else
   472                          InsertPtToInnerNode(path[pathindex-1],valueinsert,ni,path);
   473          }
   474          else // if the node doesn't need to split
   475          {
   476                  for(i=0;i< n->valuecount;i++)
   477                  {
   478                          if (value < n->values)
   479                          {
   480                                  insertpos=i;
   481                                  break;
   482                          }
   483                  }
   484                  if(insertpos==-1)
   485                          insertpos=n->valuecount;
   486
   487                  for(i=n->valuecount;i > insertpos;i--)
   488                  {
   489                          n->values=n->values[i-1];
   490                          n->pointers[i+1]=n->pointers;
   491                  }
   492                  n->values[insertpos]=value;
   493                  n->pointers[insertpos+1]=pointer;
   494                  n->valuecount=n->valuecount+1;
   495          }
   496  }
   497
   498  void PrintBtree()
   499  {
   500          LoadBtree();
   501          printf("BTree: Root:%d \n\n",rootnode);
   502          if(rootnode!=-1)
   503                  PrintNode(rootnode);
   504  }
   505




 Serenaiad 回复于:2006-12-23 02:00:33


   506  void PrintNode(int index)
   507  {
   508  node* n;
   509  int i;
   510          n=nodes+index;
   511          if(n->type==inner)
   512                  printf("NodeIndex:%d ValueCount:%d, type:InnerNode\n",index,n->valuecount);
   513          else
   514                  printf("NodeIndex:%d ValueCount:%d, type:LeafNode\n",index,n->valuecount);
   515          if (n->type==leaf)
   516                  printf("Values:   ");
   517          else
   518                  printf("Values:      ");
   519          for(i=0;i< n->valuecount;i++)
   520                  printf("  %4d  ",n->values);
   521          printf("\n");
   522          printf("Pointers: ");
   523          if(n->type==inner)
   524          {
   525                  for(i=0;i< n->valuecount+1;i++)
   526                          printf("  %4d  ",n->pointers);
   527          }
   528          else
   529          {
   530                  for(i=0;i< n->valuecount;i++)
   531                          printf("  %4d  ",n->pointers);
   532                  printf("next:%d",n->pointers[NODESIZE]);
   533          }
   534
   535          printf("\n\n");
   536          if( n->type == inner)
   537          {
   538                  for(i=0;i< n->valuecount+1 ;i++)
   539                          PrintNode(n->pointers);
   540          }
   541  }
   542
   543  void test()
   544  {
   545  int i,j;
   546  int ni;
   547  int minval;
   548  node* n;
   549  int values[100];
   550  valuelocation v;
   551  int valuecount;
   552  int index;
   553  int val;
   554          printf("RAND_MAX:%d\n",RAND_MAX);
   555
   556          LoadBtree();
   557          srand(atoi(GetSysTime()));
   558          //random();
   559          for(i=0;i<100;i++)
   560          {
   561
   562                  while(1)
   563                  {
   564
   565                          val=rand();
   566                          v=FindValue(val);
   567                          if(v.nodeindex==-1)
   568                          {
   569                                  InsertValue(val,val);
   570                                  break;
   571                          }
   572                  }
   573          }
   574          if(VerifyBtree()!=0)
   575                  return ;
   576          WriteBtree();
   577
   578
   579          minval=MinValueThroughNode(rootnode);
   580          v=FindValue(minval);
   581          ni=v.nodeindex;
   582          n=nodes+ni;
   583          i=0;
   584          printf("values: \n");
   585          while(n!=NULL)
   586          {
   587                  for(j=0;j<n->valuecount;j++)
   588                  {
   589                          values=n->values[j];
   590                          printf("value %d is %d\n",i,values);
   591                          i++;
   592                  }
   593
   594                  if(n->pointers[NODESIZE]==-1)
   595                          n=NULL;
   596                  else
   597                          n=nodes+n->pointers[NODESIZE];
   598          }
   599          printf("\n");
   600          //begin to delete
   601          valuecount=100;
   602          while(valuecount>10)
   603          {
   604                  i=random();
   605                  i=rand();
   606                  index=i/(RAND_MAX/valuecount);
   607                  if(index>valuecount-1)
   608                          continue;
   609                  v=FindValue(values[index]);
   610                  if(v.nodeindex==-1)
   611                  {
   612                          printf("value %d not in btree.\n",values[index]);
   613                          return ;
   614                  }
   615                  printf("Delete %d value:%d\n",index,values[index]);
   616                  if(DeleteValue(values[index])!=0)
   617                  {
   618                          printf("delete value failed\n");
   619                          return ;
   620                  }/*
   621                  v=FindValue(32085);
   622                  if(v.nodeindex==-1)
   623                  {
   624                          printf("value %d not in btree.\n",32085);
   625                          return ;
   626                  }*/
   627
   628                  for(i=index;i<valuecount-1;i++)
   629                          values=values[i+1];
   630                  if(VerifyBtree()!=0)
   631                          return;
   632                  WriteBtree();
   633                  valuecount--;
   634
   635          }
   636          WriteBtree();
   637  }
   638
   639  valuelocation FindValue(int value)
   640  {
   641  int i,vi;
   642  node* n;
   643  int path[101];
   644  valuelocation v;
   645          v.nodeindex=-1;
   646          vi=FindNewValueNode(value,path);
   647          if(vi==-1)
   648          {
   649                  return v;
   650          }
   651          else
   652          {
   653                  n=nodes+vi;
   654                  for(i=0;i<n->valuecount;i++)
   655                  {
   656                          if(n->values==value)
   657                          {
   658                                  v.nodeindex=vi;
   659                                  v.valueindex=i;
   660                                  v.pointer=n->pointers;
   661                                  return v;
   662                          }
   663                  }
   664                  return v;
   665          }
   666  }
   667
   668  int DeleteValue(int value)
   669  {
   670  int i,j,ni,pi,bi; //ni - node index;  pi - parent node index ; bi - borther node index
   671  int vi ; // vi - value index int he pointers array
   672  int halfsize=(NODESIZE+1)/2;
   673  int minval,pminval,nminval;
   674  int newval;
   675  int valuepos;
   676
   677  node* n;
   678  node* pn; // parent node
   679  node* prenode=NULL; // previous brother node 
   680  node* nextnode=NULL; //next brother node
   681
   682  // 本节点和前一个兄弟节点还是和后一个兄弟节点发生关系(借值或合并) P ,N
   683  char  NodeProc; // P - previous node N- next node
   684  char  MethodProc; // M-merge B-borrow
   685  int path[101];
   686  valuelocation v;
   687
   688          ni=FindNewValueNode(value,path);
   689          if( ni==-1)
   690          {
   691                  return 1;
   692          }
   693          else
   694          {
   695                  n=nodes+ni;
   696                  valuepos=-1;
   697                  for(i=0;i<n->valuecount;i++)
   698                  {
   699                          if(value==n->values)
   700                          {
   701                                  valuepos=i;
   702                                  break;
   703                          }
   704                  }
   705                  if(valuepos==-1)
   706                          return 1;
   707                  if(n->valuecount > halfsize) // the node have enough value
   708                  {
   709                          if(value==n->values[0]) // 如果删掉的这个值是这个节点的最小值,那么需要update 他的某个父节点的值
   710                          {
   711                                  minval=n->values[0];
   712                                  newval=n->values[1];
   713                                  if(path[0]!=1) // if this node is not root node
   714                                          UpdateAncestorNodeMinValue(path,path[0]-1,minval,newval);
   715                          }
   716                          DeleteValueInLeafNode(n,value);
   717                          return 0;
   718                  }
   719                  else// if the node doesn't have enough values;
   720                  {
   721                          vi=FindNodeValueIndex(value,n);
   722                          if(path[0]==1) // this leaf node is root node
   723                          {
   724                                  DeleteValueInLeafNode(n,value);
   725                                  if(n->valuecount==0)
   726                                  {
   727                                          ReleaseNode(ni);
   728                                          rootnode=-1;
   729                                  }
   730                                  return 0;
   731                          }
   732                          else  // if the node is not root node
   733                          {
   734
   735                                  pi=path[path[0]-1];
   736                                  pn=nodes+pi; // get parent node
   737                                  for(i=0 ;i<NODESIZE+1;i++)
   738                                  {
   739                                          if(pn->pointers==ni)
   740                                          {
   741                                                  if(i!=0)
   742                                                  {
   743                                                          bi=pn->pointers[i-1];
   744                                                          prenode=nodes+pn->pointers[i-1];
   745                                                  }
   746                                                  if(i!=NODESIZE)
   747                                                  {
   748                                                          bi=pn->pointers[i+1];
   749                                                          nextnode=nodes+pn->pointers[i+1];
   750                                                  }
   751                                                  break;
   752                                          }
   753                                  }
   754                                  if(prenode!=NULL)
   755                                  {
   756                                          NodeProc='P';
   757                                          if(prenode->valuecount > halfsize)
   758                                                  MethodProc='B';
   759                                          else
   760                                                  MethodProc='M';
   761                                  }
   762                                  else
   763                                  {
   764                                          NodeProc='N';
   765                                          if(nextnode->valuecount > halfsize)
   766                                                  MethodProc='B';
   767                                          else
   768                                                  MethodProc='M';
   769                                  }
   770                                  //printf("NodeProc: %c ,MethodProc:%c\n",NodeProc,MethodProc);
   771                                  if(MethodProc=='B') //如果需要借值
   772                                  {
   773                                          if(NodeProc=='P') //如果从前一个节点借
   774                                          {
   775                                                  if(value==n->values[0])
   776                                                  {
   777                                                          minval=value;
   778                                                          newval=n->values[1];
   779                                                          UpdateAncestorNodeMinValue(path,path[0]-1,minval,newval);
   780                                                  }
   781                                                  DeleteValueInLeafNode(n,value);
   782
   783                                                  for(i=n->valuecount ; i>=1 ;i--)
   784                                                  {
   785                                                          n->values=n->values[i-1];
   786                                                          n->pointers=n->pointers[i-1];
   787                                                  }
   788                                                  minval=n->values[0];
   789                                                  newval=prenode->values[prenode->valuecount-1];
   790                                                  n->values[0]=prenode->values[prenode->valuecount-1];
   791                                                  n->pointers[0]=prenode->pointers[prenode->valuecount-1];
   792                                                  n->valuecount=n->valuecount+1;
   793                                                  UpdateAncestorNodeMinValue(path,path[0]-1,minval,newval);
   794                                                  prenode->valuecount=prenode->valuecount-1;
   795                                          }
   796                                          else  //如果需要从后一个节点借
   797                                          {
   798                                                  if(value==n->values[0]) //如果这个删除的最小值
   799                                                  {
   800                                                          newval=n->values[1];
   801                                                          UpdateAncestorNodeMinValue(path,path[0]-1,value,newval);
   802                                                  }
   803                                                  DeleteValueInLeafNode(n,value);
   804
   805                                                  //处理下一个节点
   806                                                  minval=nextnode->values[0];
   807                                                  newval=nextnode->values[1];
   808                                                  n->values[n->valuecount]=nextnode->values[0];
   809                                                  n->pointers[n->valuecount]=nextnode->pointers[0];
   810                                                  n->valuecount=n->valuecount+1;
   811                                                  DeleteValueInLeafNode(nextnode,minval);
   812                                                  UpdateAncestorNodeMinValue(path,path[0]-1,minval,newval);// 下一个节点的最小值也改变了,所以需要也update 父节点
   813                                          }
   814                                          return 0;
   815                                  }
   816                                  else //如果合并节点
   817                                  {
   818                                          if(NodeProc=='P') // 如果和前一个节点合并
   819                                          {
   820                                                  if(value==n->values[0])
   821                                                  {
   822                                                          newval=n->values[1];
&nbs