c语言b树的实现

关于b树的实现,有一篇博文讲的很清楚

http://blog.youkuaiyun.com/v_JULY_v/article/details/6530142

我自己也实现了一个,

头文件btree.h

 1 #ifndef _BTREE_H_
 2 #define _BTREE_H_
 3 
 4 #define T 100
 5 #define BTREE_OK 0
 6 #define BTREE_ERR -1
 7 
 8 typedef struct btree_node
 9 {
10      int key_num;
11      int key[2 * T - 1];
12      int seek[2 * T];
13      int self;
14      int parent;
15 }btree_node;
16 
17 typedef struct btree
18 {
19      struct btree_node *root;
20      FILE *fp;
21 }btree;
22 int btree_insert(btree *tree, int key);
23 int btree_split(btree *tree, btree_node *node);
24 btree_node *btree_search(btree *tree, int key);
25 btree *btree_create(const char *file);
26 int btree_delete(btree *tree, int key);
27 int btree_merge(btree *tree, btree_node *left, btree_node *right, btree_node *parent);
28 #endif

 

实现文件btree.c

  1 #include <stdio.h>
  2 #include <stdlib.h>
  3 #include <string.h>
  4 #include "btree.h"
  5 
  6 static int btree_read_disk(btree *tree, int seek, btree_node *node)
  7 {
  8      if(fseek(tree->fp, seek, SEEK_SET) == -1)
  9           return BTREE_ERR;
 10      char *read_buf = calloc(1, sizeof(btree_node));
 11      if(fread(read_buf, sizeof(btree_node), 1, tree->fp) == -1)
 12           return BTREE_ERR;
 13      memcpy(node, read_buf, sizeof(btree_node));
 14      return BTREE_OK;
 15 }
 16 
 17 static int btree_write_disk(btree *tree, int seek, btree_node *node)
 18 {
 19      if(fseek(tree->fp, seek, SEEK_SET) == -1)
 20           return BTREE_ERR;
 21      if(fwrite((void *)node, sizeof(btree_node), 1, tree->fp) == -1)
 22           return BTREE_ERR;
 23      return BTREE_OK;
 24 }
 25 
 26 static int btree_key_index(btree_node *node, int key)
 27 {
 28      int low = 0;
 29      int high = node->key_num - 1;
 30      int middle = (low + high) / 2;
 31      while(low <= high)
 32      {
 33           if(node->key[middle] == key)
 34                return middle;
 35           else if(node->key[middle] > key)
 36                high = middle - 1;
 37           else
 38                low = middle + 1;
 39           middle = (low + high) / 2;
 40      }
 41      return high + 1;
 42 }
 43 
 44 static int btree_end_seek_of_file(btree *tree)
 45 {
 46      if(fseek(tree->fp, 0, SEEK_END) == -1)
 47           return BTREE_ERR;
 48      return ftell(tree->fp);
 49 }
 50 
 51 static void btree_view(btree *tree, btree_node *node)
 52 {
 53      int i;
 54      for(i = 0; i < node->key_num; i++)
 55           printf("key:%d, self:%d, parent:%d, seek[0]:%d\n", node->key[i], node->self, node->parent, node->seek[0]);
 56      if(node->seek[0] != -1)
 57      {
 58           btree_node *child = calloc(1, sizeof(btree_node));
 59           if(child == NULL)
 60                return;
 61           for(i = 0; i < node->key_num + 1; i++)
 62           {
 63                if(btree_read_disk(tree, node->seek[i], child) == BTREE_ERR)
 64                     return;
 65                btree_view(tree, child);
 66           }
 67      }
 68 }
 69 
 70 static btree_node *btree_node_create()
 71 {
 72      btree_node *node = malloc(sizeof(btree_node));
 73      node->self = -1;
 74      node->parent = -1;
 75      int i;
 76      for(i = 0; i < 2 * T - 1; i++)
 77           node->key[i] = 0;
 78      for(i = 0; i < 2 * T; i++)
 79           node->seek[i] = -1;
 80      node->key_num = 0;
 81      return node;
 82 }
 83 
 84 static int btree_successor(btree *tree, btree_node *node, btree_node *successor, int index)
 85 {
 86      if(node->seek[0] == -1)
 87           return BTREE_ERR;
 88      if(btree_read_disk(tree, node->seek[index], successor) == BTREE_ERR)
 89           return BTREE_ERR;
 90      while(successor->seek[0] != -1)
 91           if(btree_read_disk(tree, successor->seek[0], successor) == BTREE_ERR)
 92                return BTREE_ERR;
 93      return BTREE_OK;
 94 }
 95 
 96 btree *btree_create(const char *file)
 97 {
 98      FILE *fp = fopen(file, "w+");
 99      if(fp == NULL)
100           return NULL;
101      btree *tree = calloc(1, sizeof(btree));
102      if(tree == NULL)
103           return NULL;
104      tree->fp = fp;
105      tree->root = btree_node_create();
106      tree->root->self = 0;
107      if(btree_write_disk(tree, tree->root->self, tree->root) == BTREE_ERR)
108           return NULL;
109      return tree;
110 }
111 
112 btree_node *btree_search(btree *tree, int key)
113 {
114      btree_node *node = calloc(1, sizeof(btree_node));
115      if(node == NULL)
116           return NULL;
117      *node = *tree->root;
118      int key_index = btree_key_index(node, key);
119      while(node->seek[0] != -1 && node->key[key_index] != key)
120      {
121           if(btree_read_disk(tree, node->seek[key_index], node) == BTREE_ERR)
122                return NULL;
123           key_index = btree_key_index(node, key);
124      }
125      if(node->key[key_index] == key)
126           return node;
127      return NULL;
128 }
129 
130 int main(int argc, char *argv[])
131 {
132      int i;
133      btree *tree = btree_create("source");
134      for(i = 0; i < 100000; i++)
135           btree_insert(tree, i);
136      for(i = 0; i < 100000; i++)
137           btree_delete(tree, i);
138      return 0;
139 }
140 
141 int btree_insert(btree *tree, int key)
142 {
143      btree_node *node = calloc(1, sizeof(btree_node));
144      if(node == NULL)
145           return BTREE_ERR;
146      *node = *tree->root;
147      if(btree_split(tree, node) == BTREE_ERR)
148           return BTREE_ERR;
149      int key_index = btree_key_index(node, key);
150      while(node->seek[0] != -1)
151      {
152           if(btree_read_disk(tree, node->seek[key_index], node) == BTREE_ERR)
153                return BTREE_ERR;
154           if(btree_split(tree, node) == BTREE_ERR)
155                return BTREE_ERR;
156           key_index = btree_key_index(node, key);
157      }
158      int i;
159      for(i = node->key_num; i > key_index; i--)
160           node->key[i] = node->key[i - 1];
161      node->key[key_index] = key;
162      node->key_num++;
163      if(btree_write_disk(tree, node->self, node) == BTREE_ERR)
164           return BTREE_ERR;
165      if(tree->root->self == node->self)
166           *tree->root = *node;
167      return BTREE_OK;
168 }
169 
170 int btree_split(btree *tree, btree_node *node)
171 {
172      if(node->key_num < 2 * T - 1)
173           return BTREE_OK;
174      btree_node *brother = btree_node_create();
175      brother->self = btree_end_seek_of_file(tree);
176      int save_key = node->key[T - 1];
177      int i;
178      for(i = T; i < node->key_num; i++)
179           brother->key[i - T] = node->key[i];
180      if(node->seek[0] != -1)
181           for(i = T; i < node->key_num + 1; i++)
182           {
183                brother->seek[i - T] = node->seek[i];
184                btree_node *child = calloc(1, sizeof(btree_node));
185                if(child == NULL)
186                     return BTREE_ERR;
187                if(btree_read_disk(tree, node->seek[i], child) == BTREE_ERR)
188                     return BTREE_ERR;
189                child->parent = brother->self;
190                if(btree_write_disk(tree, child->self, child) == BTREE_ERR)
191                     return BTREE_ERR;
192           }
193      node->key_num = brother->key_num = T - 1;
194      btree_node *parent = calloc(1, sizeof(btree_node));
195      if(parent == NULL)
196           return BTREE_ERR;
197      if(node->parent == -1)
198      {
199           parent = btree_node_create();
200           tree->root = parent;
201           parent->self = brother->self + sizeof(btree_node);
202           node->parent = parent->self;
203      }
204      else
205           if(btree_read_disk(tree, node->parent, parent) == BTREE_ERR)
206                return BTREE_ERR;
207      int key_index = btree_key_index(parent, node->key[0]);
208      for(i = parent->key_num; i > key_index; i--)
209           parent->key[i] = parent->key[i - 1];
210      parent->key[i] = save_key;
211      for(i = parent->key_num + 1; i > key_index + 1; i--)
212           parent->seek[i] = parent->seek[i - 1];
213      parent->seek[key_index] = node->self;
214      parent->seek[key_index + 1] = brother->self;
215      parent->key_num++;
216      brother->parent = node->parent;
217 
218      btree_write_disk(tree, parent->self, parent);
219      btree_write_disk(tree, brother->self, brother);
220      btree_write_disk(tree, node->self, node);
221      if(btree_read_disk(tree, tree->root->self, tree->root) == BTREE_ERR)
222           return BTREE_ERR;
223      *node = *parent;
224      return BTREE_OK;
225 }
226 
227 int btree_delete(btree *tree, int key)
228 {
229      btree_node *node = btree_search(tree, key);
230      if(node == NULL)
231           return BTREE_ERR;
232      int key_index = btree_key_index(node, key);
233      if(node->seek[0] != -1)
234      {
235           btree_node *successor = btree_node_create();
236           if(btree_successor(tree, node, successor, key_index + 1) == BTREE_ERR)
237                return BTREE_ERR;
238           node->key[key_index] = successor->key[0];
239           if(btree_write_disk(tree, node->self, node) == BTREE_ERR)
240                return BTREE_ERR;
241           if(node->self == tree->root->self)
242                *tree->root = *node;
243           node = successor;
244           key_index = 0;
245      }
246      int i;
247      for(i = key_index; i < node->key_num - 1; i++)
248           node->key[i] = node->key[i + 1];
249      node->key_num--;
250      btree_write_disk(tree, node->self, node);
251      while(node->key_num < T - 1 && node->self != tree->root->self)
252      {
253           btree_node *parent = btree_node_create();
254           if(btree_read_disk(tree, node->parent, parent) == BTREE_ERR)
255                return BTREE_ERR;
256           key_index = btree_key_index(parent, node->key[0]);
257           if(parent->key_num == key_index + 1 && parent->key[key_index] == node->key[0])
258                key_index++;
259           btree_node *brother = btree_node_create();
260           if(key_index == parent->key_num)
261           {
262                if(btree_read_disk(tree, parent->seek[key_index - 1], brother) == BTREE_ERR)
263                     return BTREE_ERR;
264                if(brother->key_num > T - 1)
265                {
266                     for(i = node->key_num; i > 0; i--)
267                          node->key[i] = node->key[i - 1];
268                     for(i = node->key_num + 1; i > 0; i--)
269                          node->seek[i] = node->seek[i - 1];
270                     node->key[0] = parent->key[parent->key_num - 1];
271                     node->seek[0] = brother->seek[brother->key_num];
272                     if(node->seek[0] != -1)
273                     {
274                          btree_node *child = btree_node_create();
275                          if(btree_read_disk(tree, brother->seek[brother->key_num], child) == BTREE_ERR)
276                               return BTREE_ERR;
277                          child->parent = node->self;
278                          if(btree_write_disk(tree, child->self, child) ==  BTREE_ERR)
279                          return BTREE_ERR;
280                     }
281                     node->key_num++;
282                     parent->key[parent->key_num - 1] = brother->key[brother->key_num - 1];
283                     brother->key_num--;
284                }
285                else
286                     btree_merge(tree, brother, node, parent);
287           }
288           else
289           {
290                if(btree_read_disk(tree, parent->seek[key_index + 1], brother) == BTREE_ERR)
291                     return BTREE_ERR;
292                if(brother->key_num > T - 1)
293                {
294                     node->key[node->key_num] = parent->key[key_index];
295                     parent->key[key_index] = brother->key[0];
296                     node->key_num++;
297                     for(i = 0; i < brother->key_num - 1; i++)
298                          brother->key[i] = brother->key[i + 1];
299                     node->seek[node->key_num] = brother->seek[0];
300                     if(node->seek[node->key_num] != -1)
301                     {
302                          btree_node *child = btree_node_create();
303                          if(btree_read_disk(tree, brother->seek[0], child) == BTREE_ERR)
304                               return BTREE_ERR;
305                          child->parent = node->self;
306                          if(btree_write_disk(tree, child->self, child) == BTREE_ERR)
307                          return BTREE_ERR;
308                     }
309                     for(i = 0; i < brother->key_num; i++)
310                          brother->seek[i] = brother->seek[i + 1];
311                     brother->key_num--;
312                }
313                else
314                     btree_merge(tree, node, brother, parent);
315           }
316           btree_write_disk(tree, parent->self, parent);
317           btree_write_disk(tree, node->self, node);
318           btree_write_disk(tree, brother->self, brother);
319           if(tree->root->self == parent->self)
320                *tree->root = *parent;
321           *node = *parent;
322      }
323      if(tree->root->self == node->self)
324           *tree->root = *node;
325      return BTREE_OK;
326 }
327 
328 int btree_merge(btree *tree, btree_node *left, btree_node *right, btree_node *parent)
329 {
330      int key_index = btree_key_index(parent, left->key[0]);
331      int save_key = parent->key[key_index];
332      int i;
333      for(i = key_index; i < parent->key_num - 1; i++)
334           parent->key[i] = parent->key[i + 1];
335      for(i = key_index + 1; i < parent->key_num + 1; i++)
336           parent->seek[i] = parent->seek[i + 1];
337      parent->key_num--;
338 
339      left->key[left->key_num] = save_key;
340      left->key_num++;
341      for(i = 0; i < right->key_num; i++)
342           left->key[i + left->key_num] = right->key[i];
343      if(right->seek[0] != -1)
344           for(i = 0; i < right->key_num + 1; i++)
345           {
346                left->seek[i + left->key_num] = right->seek[i];
347                btree_node *child = calloc(1, sizeof(btree_node));
348                if(child == NULL)
349                     return BTREE_ERR;
350                if(btree_read_disk(tree, right->seek[i], child) == BTREE_ERR)
351                     return BTREE_ERR;
352                child->parent = left->self;
353                if(btree_write_disk(tree, child->self, child) == BTREE_ERR)
354                     return BTREE_ERR;
355                free(child);
356           }
357      left->key_num += right->key_num;
358      if(tree->root->self == parent->self && parent->key_num == 0)
359      {
360           left->parent = -1;
361           *tree->root = *left;
362      }
363      btree_write_disk(tree, parent->self, parent);
364      btree_write_disk(tree, left->self, left);
365      btree_write_disk(tree, right->self, right);
366      return BTREE_OK;
367 }

 

转载于:https://www.cnblogs.com/LyleMalik/archive/2012/12/14/2818040.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值