1 /************************************************
 2  *作者:陈新
 3  *时间:2014 6.3
 4  *邮箱:cx2pirate@gmail.com
 5  * **********************************************/
 6 
 7 #ifndef _HEADER_BTREE_
 8 #define  _HEADER_BTREE_
 9 
10 #define N 5    //b-tree的度
11 #define TRUE 1
12 #define FALSE 0
13 
14 typedef int BOOL;
15 typedef int Key;
16 
17 typedef struct btree_node{                
18     int count;
19     BOOL is_leaf;
20     Key key[2 * N - 1];
21     struct btree_node *child[2 * N];
22 }btree_node,*btree_node_ptr;
23 
24 typedef struct btree_root{
25     struct btree_node *node;
26     int height;    
27 }btree_root,*btree_root_ptr;
28 
29 typedef struct btree_search_res{                    //查询结果
30     btree_node *node;
31     int pos;
32 }btree_search_res;
33 
34 
35 btree_root *btree_create();
36 btree_search_res btree_search(btree_node *node,Key key);
37 void btree_insert(btree_root *root,Key key);
38 void btree_delete(btree_root *root,Key key);
39 
40 
41 #endif
  1 #include "btree.h"
  2 #include <stdio.h>
  3 #include <stdlib.h>
  4 
  5 //分配一个btree_node节点
  6 btree_node *btree_node_alloc()
  7 {        
  8     btree_node *node = (btree_node *)malloc(sizeof(btree_node));
  9     if(node == NULL){
 10         return NULL;
 11     }
 12     for(int i =0;i < 2 * N - 1;i++){
 13         node ->key[i] = 0;
 14     }
 15     for(int i = 0;i < 2 * N;i++){
 16         node ->child[i] = NULL;
 17     }
 18     node ->count = 0;
 19     node ->is_leaf = true;
 20     return node;
 21 }
 22 
 23 void btree_node_free(btree_node *node)
 24 {
 25     free(node);
 26 }
 27 
 28 btree_root *btree_create()
 29 {
 30     btree_root *root = (btree_root *)malloc(sizeof(btree_root));
 31     root ->node = btree_node_alloc();
 32     return root;
 33 }
 34 
 35 int btree_split_child(btree_node *parent,int pos,btree_node *child)
 36 {
 37     btree_node *new_child = btree_node_alloc();
 38     if(new_child == NULL){
 39         return -1;
 40     }
 41     new_child ->is_leaf = child ->is_leaf;
 42     new_child ->count = N - 1;
 43 
 44     for(int i = 0;i < N - 1;i++){
 45         new_child ->key[i] = child ->key[i + N];
 46     }
 47     if(!child ->is_leaf){
 48         for(int i = 0;i < N;i++){
 49             new_child ->child[i] = child ->child[i + N];
 50         }
 51     }
 52     child ->count = N - 1;
 53 
 54     for(int i = parent ->count;i > pos;i--){
 55         parent ->child[i + 1] = parent ->child[i]; 
 56     }
 57     parent ->child[pos + 1] = new_child;
 58 
 59     for(int i = parent ->count - 1;i >= pos;i--){
 60         parent ->key[i + 1] = parent ->key[i];
 61     }
 62     parent ->key[pos] = child ->key[N - 1];
 63     parent ->count++;
 64 
 65     return 0;
 66 }
 67 
 68 void btree_insert_nonfull(btree_node *node,int key)
 69 {
 70     if(node ->is_leaf){                                //case1:插入叶子节点
 71         int pos = node ->count;
 72         while(pos >= 1 && key < node ->key[pos - 1]){
 73             node ->key[pos] = node ->key[pos - 1];
 74             pos--;
 75         }
 76         node ->key[pos] = key;
 77         node ->count++;
 78     }
 79     else{                                            //case2:递归插入
 80         int pos = node ->count;
 81         while(pos > 0 && key < node ->key[pos - 1]){
 82             pos--;
 83         }
 84         if(node ->child[pos] ->count == 2 * N - 1){
 85             btree_split_child(node,pos,node ->child[pos]);//分裂
 86             if(key > node ->key[pos]){                    //选择新节点还是还是老节点
 87                 pos++;
 88             }
 89         }
 90         btree_insert_nonfull(node ->child[pos],key);
 91     }
 92 }
 93 
 94 void btree_insert(btree_root *root,int key)
 95 {
 96     if(root ->node == NULL){
 97         return;
 98     }    
 99 
100     if(root ->node ->count == 2 * N - 1){        //分裂根节点
101         btree_node *old_root = root ->node;
102         root ->node = btree_node_alloc();
103         root ->node ->is_leaf = FALSE;
104         root ->node ->count = 0;
105         root ->node ->child[0] = old_root;
106         btree_split_child(root ->node,0,old_root);
107     }
108     btree_insert_nonfull(root ->node,key);
109 }
110 /***************************************************
111  *删除部分
112  *
113  * ************************************************/
114 Key btree_maximum(btree_node *node)
115 {
116     btree_node *p = node;
117     while(!p ->is_leaf){
118         p = p ->child[p ->count];
119     }
120     return p ->key[p ->count - 1];
121 }
122 
123 Key btree_minimum(btree_node *node)
124 {
125     btree_node *p = node;
126     while(!p ->is_leaf){
127         p = p ->child[0];
128     }
129     return p ->key[0];
130 }
131 
132 /*pos左右两个孩子都只有N - 1个关键字,
133  *把第pos个关键字,和两个孩子合并成一个
134  *新的节点
135  */
136 void btree_merge(btree_node *parent,int pos)
137 {
138     btree_node *left_child = parent ->child[pos];
139     btree_node *right_child = parent ->child[pos + 1];
140     
141     left_child ->key[N - 1] = parent ->key[pos];
142     //for(int i = 0;i < N;i++)                                        //bug report
143     for(int i = 0;i < N - 1;i++)                                    //竟然溢出覆盖了 ->child[0]
144     {    
145         left_child ->key[N + i] = right_child ->key[i];
146     }
147     if(!right_child ->is_leaf){
148         for(int i = 0;i < N;i++){
149             //left_child ->child[i] = right_child ->child[N + i];    //bug report
150             left_child ->child[N + i] = right_child ->child[i];
151         }
152     }
153     left_child ->count = 2 * N - 1;
154 
155     for(int i = pos + 1;i < parent ->count;i++){
156         parent ->key[i - 1] = parent ->key[i];
157         parent ->child[i] = parent ->child[i + 1];
158     }
159     parent ->count--;
160 
161     btree_node_free(right_child);
162 }
163 
164 void shift_right_to_left(btree_node *parent,int pos)
165 {
166     btree_node *child = parent ->child[pos];
167     btree_node *right_child = parent ->child[pos + 1];
168 
169     child ->key[N - 1] = parent ->key[pos];
170     parent ->key[pos] = right_child ->key[0];
171 
172     for(int i = 0;i < right_child ->count - 1;i++){
173         right_child ->key[i] = right_child ->key[i + 1];
174     }
175 
176     if(!right_child ->is_leaf){
177         child ->child[N] = right_child ->child[0];
178         for(int i = 0;i < right_child ->count;i++){
179             right_child ->child[i] = right_child ->child[i + 1];
180         }
181     }
182 
183     child ->count++;
184     right_child ->count--;
185 }
186 //
187 void shift_left_to_right(btree_node *parent,int pos)
188 {
189     btree_node *child = parent ->child[pos];
190     btree_node *left_child = parent ->child[pos - 1];
191 
192     //for(int i = 1;i <= child ->count;i++){                    //bug report
193     for(int i = child ->count;i > 0;i--){
194         child ->key[i] = child ->key[i - 1];
195     }
196     //child ->key[0] = parent ->key[pos];                        //bug report
197     //parent ->key[pos] = left_child ->key[left_child ->count - 1];
198     child ->key[0] = parent ->key[pos - 1];
199     parent ->key[pos - 1] = left_child ->key[left_child ->count - 1];
200 
201     if(!left_child ->is_leaf){
202         for(int i = child ->count + 1;i > 0;i--){
203             child ->child[i] = child ->child[i - 1];
204         }
205         child ->child[0] = left_child ->child[left_child ->count];
206     }
207 
208     child ->count++;
209     left_child ->count--;
210 }
211 
212 //node至少含有N个关键字的删除情况
213 void btree_delete_noback(btree_node *node,Key key)
214 {
215     int pos = 0;
216     while(pos < node ->count && node ->key[pos] < key){        //todo不存在的情况
217         pos++;
218     }
219     if(pos < node ->count && node ->key[pos] == key){        //case1 && case2
220         if(node ->is_leaf){                                    //case1
221             for(int i = pos;i < node ->count - 1;i++){
222                 node ->key[i] = node ->key[i + 1];
223             }
224             node ->count--;
225             return;
226         }
227 
228         if(node ->child[pos] ->count >= N){                        //case 2a
229             Key pre = btree_maximum(node ->child[pos]);
230             node ->key[pos] = pre;
231             btree_delete_noback(node ->child[pos],pre);
232         }
233         else if(node ->child[pos + 1] ->count >= N){            //case 2b
234             Key suc = btree_minimum(node ->child[pos + 1]);
235             node ->key[pos] = suc;
236             btree_delete_noback(node ->child[pos + 1],suc);
237         }
238         else{                                                    //case 2c
239             btree_merge(node,pos);
240             btree_delete_noback(node ->child[pos],key);
241         }
242     }
243     else{
244         if(node ->is_leaf){                                        //case1 特殊情况,不存在节点
245             return;
246         }
247         if(node ->child[pos] ->count == N - 1){
248             btree_node *next = node ->child[pos];
249             if(pos > 0 && node ->child[pos - 1] ->count >= N){                    //case 3a_1
250                 shift_left_to_right(node,pos);
251             }
252             else if(pos < node ->count && node ->child[pos + 1] ->count >= N){    //case 3a_2
253                 shift_right_to_left(node,pos);
254             }
255             else if(pos > 0){
256                 btree_merge(node,pos - 1);
257                 next = node ->child[pos - 1];
258             }
259             else{
260                 btree_merge(node,pos);
261             }
262             btree_delete_noback(next,key);                                        //next may be wrong
263         }
264     }
265 }
266 
267 //删除时需要更新root的情况,参考算法导论
268 //case 2c 和 case 3b
269 BOOL is_root_change(btree_root *root)
270 {
271     return root ->node ->count == 1 &&
272         root ->node ->child[0] ->count == N - 1 &&
273         root ->node ->child[1] ->count == N - 1;
274 }
275 
276 void btree_delete(btree_root *root,Key key)
277 {
278     if(is_root_change(root)){
279         btree_merge(root ->node,0);
280         btree_node *old_root = root ->node;
281         root ->node = root ->node ->child[0];
282         btree_node_free(old_root);
283     } 
284     btree_delete_noback(root ->node,key);
285 }
286 
287 
288 /****************************************************
289  *查找部分
290  *
291  * **************************************************/
292 //返回值...
293 btree_search_res btree_search(btree_node *node,int key)
294 {
295     int pos = 0;
296     while(pos < node ->count && key > node ->key[pos]){
297         pos++;
298     }
299     if(pos < node ->count && key == node ->key[pos]){
300         return btree_search_res{node,pos};                                 //return node and pos
301     }
302     if(node ->is_leaf){
303         return btree_search_res{NULL,-1};
304     }
305     return btree_search(node ->child[pos],key);
306 }

 

 posted on 2014-06-07 14:07  莫扎特的代码  阅读(190)  评论(0编辑  收藏  举报