- 论坛徽章:
- 0
|
一直没有找到实现的代码,前段时间写了一个,数据库里的索引就是用的整个东西实现的
- 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[i])
- 232 return 1;
- 233 }
- 234 for(i=1;i<=path[0];i++)
- 235 {
- 236 if(inode==path[i])
- 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[i])
- 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[i]=n->values[i];
- 264 tmppointers[i]=n->pointers[i];
- 265 }
- 266 tmpvalues[insertPos]=value;
- 267 tmppointers[insertPos]=pointer;
- 268 for(i=NODESIZE-1;i>=insertPos;i--)
- 269 {
- 270 tmpvalues[i+1]=n->values[i];
- 271 tmppointers[i+1]=n->pointers[i];
- 272 }
- 273 for(i=0;i<halfsize;i++)
- 274 {
- 275 n->values[i]=tmpvalues[i];
- 276 n->pointers[i]=tmppointers[i];
- 277 }
- 278 n->valuecount=halfsize;
- 279 for(i=halfsize;i<NODESIZE+1;i++)
- 280 {
- 281 newNode->values[i-halfsize]=tmpvalues[i];
- 282 newNode->pointers[i-halfsize]=tmppointers[i];
- 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[i])
- 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[i]=n->values[i-1];
- 325 n->pointers[i]=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
复制代码 |
|