c 语言实现红黑树

rbtree
  1 /*----------------------------------------------------------- 
  2 RB-Tree的插入和删除操作的实现算法 
  3 参考资料: 
  4 1) <<Introduction to algorithm>> 
  5 2) [url]http://lxr.linux.no/linux/lib/rbtree.c[/url] 
  6 作者:[url]http://www.cppblog.com/converse/[/url] 
  7 您可以自由的传播,修改这份代码,转载处请注明原作者 
  8 红黑树的几个性质: 
  9 1) 每个结点只有红和黑两种颜色 
 10 2) 根结点是黑色的 
 11 3)空节点是黑色的(红黑树中,根节点的parent以及所有叶节点lchild、rchild都不指向NULL,而是指向一个定义好的
 12 空节点)。 
 13 4) 如果一个结点是红色的,那么它的左右两个子结点的颜色是黑色的 
 14 5) 对于每个结点而言,从这个结点到叶子结点的任何路径上的黑色结点 
 15 的数目相同
 16 -------------------------------------------------------------*/ 
 17 #include <stdio.h> 
 18 #include <stdlib.h> 
 19 #include <string.h> 
 20 typedef enum color_t 
 21 { 
 22     RED = 0, 
 23     BLACK = 1 
 24 }color_t; 
 25 typedef struct rb_node_t 
 26 { 
 27     struct rb_node_t *left, *right, *parent; 
 28     char key[21]; 
 29     color_t color; 
 30 }rb_node_t; 
 31 
 32 /* forward declaration */ 
 33 rb_node_t* rb_insert(char * key, rb_node_t* root); 
 34 rb_node_t* rb_search(char * key, rb_node_t* root); 
 35 rb_node_t* rb_erase(char * key, rb_node_t* root); 
 36 static rb_node_t* rb_new_node(char * key) 
 37 { 
 38     rb_node_t *node = (rb_node_t*)malloc(sizeof(struct rb_node_t)); 
 39     if (!node) 
 40     { 
 41         printf("malloc error!\n"); 
 42         exit(-1); 
 43     } 
 44     strcpy(node->key,key);
 45     return node; 
 46 }
 47 /*----------------------------------------------------------- 
 48   | node right 
 49   | / \ ==> / \ 
 50   | a right node y 
 51   | / \ / \ 
 52   | b y a b 
 53   -----------------------------------------------------------*/ 
 54 static rb_node_t* rb_rotate_left(rb_node_t* node, rb_node_t* root) 
 55 { 
 56     rb_node_t* right = node->right; 
 57     if ((node->right = right->left)) 
 58     { 
 59         right->left->parent = node; 
 60     } 
 61     right->left = node; 
 62     if ((right->parent = node->parent)) 
 63     { 
 64         if (node == node->parent->right) 
 65         { 
 66             node->parent->right = right; 
 67         } 
 68         else 
 69         { 
 70             node->parent->left = right; 
 71         } 
 72     } 
 73     else 
 74     { 
 75         root = right; 
 76     } 
 77     node->parent = right; 
 78     return root; 
 79 } 
 80 /*----------------------------------------------------------- 
 81   | node left 
 82   | / \ / \ 
 83   | left y ==> a node 
 84   | / \ / \ 
 85   | a b b y 
 86   -----------------------------------------------------------*/ 
 87 static rb_node_t* rb_rotate_right(rb_node_t* node, rb_node_t* root) 
 88 { 
 89     rb_node_t* left = node->left; 
 90     if ((node->left = left->right)) 
 91     { 
 92         left->right->parent = node; 
 93     } 
 94     left->right = node; 
 95     if ((left->parent = node->parent)) 
 96     { 
 97         if (node == node->parent->right) 
 98         { 
 99             node->parent->right = left; 
100         } 
101         else 
102         { 
103             node->parent->left = left; 
104         } 
105     } 
106     else 
107     { 
108         root = left; 
109     } 
110     node->parent = left; 
111     return root; 
112 }
113 static rb_node_t* rb_insert_rebalance(rb_node_t *node, rb_node_t *root) 
114 { 
115     rb_node_t *parent, *gparent, *uncle, *tmp; 
116     while ((parent = node->parent) && parent->color == RED) 
117     { 
118         gparent = parent->parent; 
119         if (parent == gparent->left) 
120         { 
121             uncle = gparent->right; 
122             if (uncle && uncle->color == RED) 
123             { 
124                 uncle->color = BLACK; 
125                 parent->color = BLACK; 
126                 gparent->color = RED; 
127                 node = gparent; 
128             } 
129             else 
130             { 
131                 if (parent->right == node) 
132                 { 
133                     root = rb_rotate_left(parent, root); 
134                     tmp = parent; 
135                     parent = node; 
136                     node = tmp; 
137                 } 
138                 parent->color = BLACK; 
139                 gparent->color = RED; 
140                 root = rb_rotate_right(gparent, root); 
141             } 
142         } 
143         else 
144         { 
145             uncle = gparent->left; 
146             if (uncle && uncle->color == RED) 
147             { 
148                 uncle->color = BLACK; 
149                 parent->color = BLACK; 
150                 gparent->color = RED; 
151                 node = gparent; 
152             } 
153             else 
154             { 
155                 if (parent->left == node) 
156                 { 
157                     root = rb_rotate_right(parent, root); 
158                     tmp = parent; 
159                     parent = node; 
160                     node = tmp; 
161                 } 
162                 parent->color = BLACK; 
163                 gparent->color = RED; 
164                 root = rb_rotate_left(gparent, root); 
165             } 
166         } 
167     } 
168     root->color = BLACK; 
169     return root; 
170 }
171 static rb_node_t* rb_erase_rebalance(rb_node_t *node, rb_node_t *parent, rb_node_t *root) 
172 { 
173     rb_node_t *other, *o_left, *o_right; 
174     while ((!node || node->color == BLACK) && node != root) 
175     { 
176         if (parent->left == node) 
177         { 
178             other = parent->right; 
179             if (other->color == RED) 
180             { 
181                 other->color = BLACK; 
182                 parent->color = RED; 
183                 root = rb_rotate_left(parent, root); 
184                 other = parent->right; 
185             } 
186             if ((!other->left || other->left->color == BLACK) && 
187                     (!other->right || other->right->color == BLACK)) 
188             { 
189                 other->color = RED; 
190                 node = parent; 
191                 parent = node->parent; 
192             } 
193             else 
194             { 
195                 if (!other->right || other->right->color == BLACK) 
196                 { 
197                     if ((o_left = other->left)) 
198                     { 
199                         o_left->color = BLACK; 
200                     } 
201                     other->color = RED; 
202                     root = rb_rotate_right(other, root); 
203                     other = parent->right; 
204                 } 
205                 other->color = parent->color; 
206                 parent->color = BLACK; 
207                 if (other->right) 
208                 { 
209                     other->right->color = BLACK; 
210                 } 
211                 root = rb_rotate_left(parent, root); 
212                 node = root; 
213                 break; 
214             } 
215         } 
216         else 
217         { 
218             other = parent->left; 
219             if (other->color == RED) 
220             { 
221                 other->color = BLACK; 
222                 parent->color = RED; 
223                 root = rb_rotate_right(parent, root); 
224                 other = parent->left; 
225             } 
226             if ((!other->left || other->left->color == BLACK) && 
227                     (!other->right || other->right->color == BLACK)) 
228             { 
229                 other->color = RED; 
230                 node = parent; 
231                 parent = node->parent; 
232             } 
233             else 
234             { 
235                 if (!other->left || other->left->color == BLACK) 
236                 { 
237                     if ((o_right = other->right)) 
238                     { 
239                         o_right->color = BLACK; 
240                     } 
241                     other->color = RED; 
242                     root = rb_rotate_left(other, root); 
243                     other = parent->left; 
244                 } 
245                 other->color = parent->color; 
246                 parent->color = BLACK; 
247                 if (other->left) 
248                 { 
249                     other->left->color = BLACK; 
250                 } 
251                 root = rb_rotate_right(parent, root); 
252                 node = root; 
253                 break; 
254             } 
255         } 
256     } 
257     if (node) 
258     { 
259         node->color = BLACK; 
260     } 
261     return root; 
262 }
263 static rb_node_t* rb_search_auxiliary(char * key, rb_node_t* root, rb_node_t** save) 
264 { 
265     rb_node_t *node = root, *parent = NULL; 
266     int ret; 
267     while (node) 
268     {   
269         parent = node; 
270         ret = strcmp(node->key,key); 
271         if (0 < ret) 
272         { 
273             node = node->left; 
274         } 
275         else if (0 > ret) 
276         { 
277             node = node->right; 
278         } 
279         else 
280         { 
281             return node; 
282         } 
283     } 
284     if (save) 
285     { 
286         *save = parent; 
287     } 
288     return NULL; 
289 }
290 rb_node_t* rb_insert(char * key,rb_node_t* root) 
291 { 
292     rb_node_t *parent = NULL, *node; 
293     parent = NULL; 
294     if ((node = rb_search_auxiliary(key, root, &parent))) 
295     { 
296         return root; 
297     } 
298     node = rb_new_node(key); 
299     node->parent = parent; 
300     node->left = node->right = NULL; 
301     node->color = RED; 
302     if (parent) 
303     { 
304         if (strcmp(parent->key,key) > 0) 
305         { 
306             parent->left = node; 
307         } 
308         else 
309         { 
310             parent->right = node; 
311         } 
312     } 
313     else 
314     { 
315         root = node; 
316     } 
317     return rb_insert_rebalance(node, root); 
318 }
319 rb_node_t* rb_search(char * key, rb_node_t* root) 
320 { 
321     return rb_search_auxiliary(key, root, NULL); 
322 }
323 rb_node_t* rb_erase(char * key, rb_node_t *root) 
324 { 
325     rb_node_t *child, *parent, *old, *left, *node; 
326     color_t color; 
327     if (!(node = rb_search_auxiliary(key, root, NULL))) 
328     { 
329         printf("key %d is not exist!\n"); 
330         return root; 
331     } 
332     old = node; 
333     if (node->left && node->right) 
334     { 
335         node = node->right; 
336         while ((left = node->left) != NULL) 
337         { 
338             node = left; 
339         } 
340         child = node->right; 
341         parent = node->parent; 
342         color = node->color; 
343         if (child) 
344         { 
345             child->parent = parent; 
346         } 
347         if (parent) 
348         { 
349             if (parent->left == node) 
350             { 
351                 parent->left = child; 
352             } 
353             else 
354             { 
355                 parent->right = child; 
356             } 
357         } 
358         else 
359         { 
360             root = child; 
361         } 
362         if (node->parent == old) 
363         { 
364             parent = node; 
365         } 
366         node->parent = old->parent; 
367         node->color = old->color; 
368         node->right = old->right; 
369         node->left = old->left; 
370         if (old->parent) 
371         { 
372             if (old->parent->left == old) 
373             { 
374                 old->parent->left = node; 
375             } 
376             else 
377             { 
378                 old->parent->right = node; 
379             } 
380         } 
381         else 
382         { 
383             root = node; 
384         } 
385         old->left->parent = node; 
386         if (old->right) 
387         { 
388             old->right->parent = node; 
389         } 
390     } 
391     else 
392     { 
393         if (!node->left) 
394         { 
395             child = node->right; 
396         } 
397         else if (!node->right) 
398         { 
399             child = node->left; 
400         } 
401         parent = node->parent; 
402         color = node->color; 
403         if (child) 
404         { 
405             child->parent = parent; 
406         } 
407         if (parent) 
408         { 
409             if (parent->left == node) 
410             { 
411                 parent->left = child; 
412             } 
413             else 
414             { 
415                 parent->right = child; 
416             } 
417         } 
418         else 
419         { 
420             root = child; 
421         } 
422     } 
423     free(old); 
424     if (color == BLACK) 
425     { 
426         root = rb_erase_rebalance(child, parent, root); 
427     } 
428     return root; 
429 } 

 

 

posted @ 2012-12-29 16:04  追心  阅读(289)  评论(0编辑  收藏  举报