Networking /C++/Linux

  C++博客 :: 首页 :: 联系 :: 聚合  :: 管理
  11 Posts :: 14 Stories :: 1 Comments :: 0 Trackbacks

常用链接

留言簿

我参与的团队

搜索

  •  

最新评论

阅读排行榜

评论排行榜

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

转自:http://bbs.chinaunix.net/viewthread.php?tid=1308846&extra=page%3D1%26amp%3Bfilter%3Ddigest


posted on 2011-12-03 19:45 likun 阅读(528) 评论(0)  编辑 收藏 引用 所属分类: C/C++Algorithms

只有注册用户登录后才能发表评论。
【推荐】超50万行VC++源码: 大型组态工控、电力仿真CAD与GIS源码库
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理