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 }