手寫C語言紅黑樹


主要實現如下功能

1.紅黑樹的前中后順遍歷

2.紅黑樹的創建

3.紅黑樹的銷毀

4.查找"紅黑樹"中鍵值為key的節點(遞歸)

5.查找"紅黑樹"中鍵值為key的節點(非遞歸)

6.返回最小結點的值(將值保存到val中)

7.返回最大結點的值(將值保存到val中)

8.打印紅黑樹

9.將結點插入到紅黑樹中

10.刪除結點

 

頭文件

 1 #ifndef _RBTREE_H_
 2 #define _RBTREE_H_
 3 
 4 #define RED        0    // 紅色節點
 5 #define BLACK    1    // 黑色節點
 6 
 7 typedef int Type;
 8 
 9 // 紅黑樹的節點
10 typedef struct RBTreeNode {
11     unsigned char color;        // 顏色(RED 或 BLACK)
12     Type   key;                    // 關鍵字(鍵值)
13     struct RBTreeNode* left;    // 左孩子
14     struct RBTreeNode* right;    // 右孩子
15     struct RBTreeNode* parent;    // 父結點
16 }Node, * RBTree;
17 
18 // 紅黑樹的根
19 typedef struct rb_root {
20     Node* node;
21 }RBRoot;
22 
23 // 創建紅黑樹,返回"紅黑樹的根"
24 RBRoot* create_rbtree();
25 
26 // 將結點插入到紅黑樹中。插入成功,返回0;失敗返回-1。
27 int insert_rbtree(RBRoot* root, Type key);
28 
29 // 刪除結點(key為節點的值)
30 void delete_rbtree(RBRoot* root, Type key);
31 
32 
33 // 前序遍歷"紅黑樹"
34 void preorder_rbtree(RBRoot* root);
35 // 中序遍歷"紅黑樹"
36 void inorder_rbtree(RBRoot* root);
37 // 后序遍歷"紅黑樹"
38 void postorder_rbtree(RBRoot* root);
39 
40 // 銷毀紅黑樹
41 void destroy_rbtree(RBRoot* root);
42 
43 // (遞歸實現)查找"紅黑樹"中鍵值為key的節點。找到的話,返回0;否則,返回-1。
44 int rbtree_search(RBRoot* root, Type key);
45 // (非遞歸實現)查找"紅黑樹"中鍵值為key的節點。找到的話,返回0;否則,返回-1。
46 int iterative_rbtree_search(RBRoot* root, Type key);
47 
48 // 返回最小結點的值(將值保存到val中)。找到的話,返回0;否則返回-1。
49 int rbtree_minimum(RBRoot* root, int* val);
50 // 返回最大結點的值(將值保存到val中)。找到的話,返回0;否則返回-1。
51 int rbtree_maximum(RBRoot* root, int* val);
52 
53 // 打印紅黑樹
54 void print_rbtree(RBRoot* root);
55 
56 #endif
rbtree.h

頭文件實現

  1 #include <stdio.h>
  2 #include <stdlib.h>
  3 #include "rbtree.h"
  4 
  5 #define rb_parent(r)   ((r)->parent)
  6 #define rb_color(r) ((r)->color)
  7 #define rb_is_red(r)   ((r)->color==RED)
  8 #define rb_is_black(r)  ((r)->color==BLACK)
  9 #define rb_set_black(r)  do { (r)->color = BLACK; } while (0)
 10 #define rb_set_red(r)  do { (r)->color = RED; } while (0)
 11 #define rb_set_parent(r,p)  do { (r)->parent = (p); } while (0)
 12 #define rb_set_color(r,c)  do { (r)->color = (c); } while (0)
 13 
 14 /*
 15  * 創建紅黑樹,返回"紅黑樹的根"!
 16  */
 17 RBRoot* create_rbtree()
 18 {
 19     RBRoot* root = (RBRoot*)malloc(sizeof(RBRoot));
 20     root->node = NULL;
 21 
 22     return root;
 23 }
 24 
 25 /*
 26  * 前序遍歷"紅黑樹"
 27  */
 28 static void preorder(RBTree tree)
 29 {
 30     if (tree != NULL)
 31     {
 32         printf("%d ", tree->key);
 33         preorder(tree->left);
 34         preorder(tree->right);
 35     }
 36 }
 37 void preorder_rbtree(RBRoot* root)
 38 {
 39     if (root)
 40         preorder(root->node);
 41 }
 42 
 43 /*
 44  * 中序遍歷"紅黑樹"
 45  */
 46 static void inorder(RBTree tree)
 47 {
 48     if (tree != NULL)
 49     {
 50         inorder(tree->left);
 51         printf("%d ", tree->key);
 52         inorder(tree->right);
 53     }
 54 }
 55 
 56 void inorder_rbtree(RBRoot* root)
 57 {
 58     if (root)
 59         inorder(root->node);
 60 }
 61 
 62 /*
 63  * 后序遍歷"紅黑樹"
 64  */
 65 static void postorder(RBTree tree)
 66 {
 67     if (tree != NULL)
 68     {
 69         postorder(tree->left);
 70         postorder(tree->right);
 71         printf("%d ", tree->key);
 72     }
 73 }
 74 
 75 void postorder_rbtree(RBRoot* root)
 76 {
 77     if (root)
 78         postorder(root->node);
 79 }
 80 
 81 /*
 82  * (遞歸實現)查找"紅黑樹x"中鍵值為key的節點
 83  */
 84 static Node* search(RBTree x, Type key)
 85 {
 86     if (x == NULL || x->key == key)
 87         return x;
 88 
 89     if (key < x->key)
 90         return search(x->left, key);
 91     else
 92         return search(x->right, key);
 93 }
 94 
 95 int rbtree_search(RBRoot* root, Type key)
 96 {
 97     if (root)
 98         return search(root->node, key) ? 0 : -1;
 99 }
100 
101 /*
102  * (非遞歸實現)查找"紅黑樹x"中鍵值為key的節點
103  */
104 static Node* iterative_search(RBTree x, Type key)
105 {
106     while ((x != NULL) && (x->key != key))
107     {
108         if (key < x->key)
109             x = x->left;
110         else
111             x = x->right;
112     }
113 
114     return x;
115 }
116 
117 int iterative_rbtree_search(RBRoot* root, Type key)
118 {
119     if (root)
120         return iterative_search(root->node, key) ? 0 : -1;
121 }
122 
123 /*
124  * 查找最小結點(非遞歸):返回tree為根結點的紅黑樹的左子樹葉結點。
125  */
126 static Node* minimum(RBTree tree)
127 {
128     if (tree == NULL)
129         return NULL;
130 
131     while (tree->left != NULL)
132         tree = tree->left;
133     return tree;
134 }
135 
136 int rbtree_minimum(RBRoot* root, int* val)
137 {
138     Node* node = NULL;
139 
140     if (root)
141         node = minimum(root->node);
142 
143     if (node == NULL)
144         return -1;
145 
146     *val = node->key;
147     return 0;
148 }
149 
150 /*
151  * 查找最大結點:返回tree為根結點的紅黑樹的右子樹最大結點。
152  */
153 static Node* maximum(RBTree tree)
154 {
155     if (tree == NULL)
156         return NULL;
157 
158     while (tree->right != NULL)
159         tree = tree->right;
160     return tree;
161 }
162 
163 int rbtree_maximum(RBRoot* root, int* val)
164 {
165     Node* node = NULL;
166 
167     if (root)
168         node = maximum(root->node);
169 
170     if (node == NULL)
171         return -1;
172 
173     *val = node->key;
174     return 0;
175 }
176 
177 /*
178  * 找結點(x)的后繼結點。即,查找"紅黑樹中數據值大於該結點"的"最小結點"。
179  */
180 static Node* rbtree_successor(RBTree x)
181 {
182     // 如果x存在右孩子,則"x的后繼結點"為 "以其右孩子為根的子樹的最小結點"。
183     if (x->right != NULL)
184         return minimum(x->right);
185 
186     // 如果x沒有右孩子。則x有以下兩種可能:
187     // (01) x是"一個左孩子",則"x的后繼結點"為 "它的父結點"。
188     // (02) x是"一個右孩子",則查找"x的最低的父結點,並且該父結點要具有左孩子",找到的這個"最低的父結點"就是"x的后繼結點"。
189     Node* y = x->parent;
190     while ((y != NULL) && (x == y->right))
191     {
192         x = y;
193         y = y->parent;
194     }
195 
196     return y;
197 }
198 
199 /*
200  * 找結點(x)的前驅結點。即,查找"紅黑樹中數據值小於該結點"的"最大結點"。
201  */
202 static Node* rbtree_predecessor(RBTree x)
203 {
204     // 如果x存在左孩子,則"x的前驅結點"為 "以其左孩子為根的子樹的最大結點"。
205     if (x->left != NULL)
206         return maximum(x->left);
207 
208     // 如果x沒有左孩子。則x有以下兩種可能:
209     // (01) x是"一個右孩子",則"x的前驅結點"為 "它的父結點"。
210     // (01) x是"一個左孩子",則查找"x的最低的父結點,並且該父結點要具有右孩子",找到的這個"最低的父結點"就是"x的前驅結點"。
211     Node* y = x->parent;
212     while ((y != NULL) && (x == y->left))
213     {
214         x = y;
215         y = y->parent;
216     }
217 
218     return y;
219 }
220 
221 /*
222  * 對紅黑樹的節點(x)進行左旋轉
223  *
224  * 左旋示意圖(對節點x進行左旋):
225  *      px                              px
226  *     /                               /
227  *    x                               y
228  *   /  \      --(左旋)-->           / \                #
229  *  lx   y                          x  ry
230  *     /   \                       /  \
231  *    ly   ry                     lx  ly
232  *
233  *
234  */
235 static void rbtree_left_rotate(RBRoot* root, Node* x)
236 {
237     // 設置x的右孩子為y
238     Node* y = x->right;
239 
240     // 將 “y的左孩子” 設為 “x的右孩子”;
241     // 如果y的左孩子非空,將 “x” 設為 “y的左孩子的父親”
242     x->right = y->left;
243     if (y->left != NULL)
244         y->left->parent = x;
245 
246     // 將 “x的父親” 設為 “y的父親”
247     y->parent = x->parent;
248 
249     if (x->parent == NULL)
250     {
251         root->node = y;            // 如果 “x的父親” 是空節點,則將y設為根節點
252     }
253     else
254     {
255         if (x->parent->left == x)
256             x->parent->left = y;    // 如果 x是它父節點的左孩子,則將y設為“x的父節點的左孩子”
257         else
258             x->parent->right = y;    // 如果 x是它父節點的左孩子,則將y設為“x的父節點的左孩子”
259     }
260 
261     // 將 “x” 設為 “y的左孩子”
262     y->left = x;
263     // 將 “x的父節點” 設為 “y”
264     x->parent = y;
265 }
266 
267 /*
268  * 對紅黑樹的節點(y)進行右旋轉
269  *
270  * 右旋示意圖(對節點y進行左旋):
271  *            py                               py
272  *           /                                /
273  *          y                                x
274  *         /  \      --(右旋)-->            /  \                     #
275  *        x   ry                           lx   y
276  *       / \                                   / \                   #
277  *      lx  rx                                rx  ry
278  *
279  */
280 static void rbtree_right_rotate(RBRoot* root, Node* y)
281 {
282     // 設置x是當前節點的左孩子。
283     Node* x = y->left;
284 
285     // 將 “x的右孩子” 設為 “y的左孩子”;
286     // 如果"x的右孩子"不為空的話,將 “y” 設為 “x的右孩子的父親”
287     y->left = x->right;
288     if (x->right != NULL)
289         x->right->parent = y;
290 
291     // 將 “y的父親” 設為 “x的父親”
292     x->parent = y->parent;
293 
294     if (y->parent == NULL)
295     {
296         //tree = x;            // 如果 “y的父親” 是空節點,則將x設為根節點
297         root->node = x;            // 如果 “y的父親” 是空節點,則將x設為根節點
298     }
299     else
300     {
301         if (y == y->parent->right)
302             y->parent->right = x;    // 如果 y是它父節點的右孩子,則將x設為“y的父節點的右孩子”
303         else
304             y->parent->left = x;    // (y是它父節點的左孩子) 將x設為“x的父節點的左孩子”
305     }
306 
307     // 將 “y” 設為 “x的右孩子”
308     x->right = y;
309 
310     // 將 “y的父節點” 設為 “x”
311     y->parent = x;
312 }
313 
314 /*
315  * 紅黑樹插入修正函數
316  *
317  * 在向紅黑樹中插入節點之后(失去平衡),再調用該函數;
318  * 目的是將它重新塑造成一顆紅黑樹。
319  *
320  * 參數說明:
321  *     root 紅黑樹的根
322  *     node 插入的結點
323  */
324 static void rbtree_insert_fixup(RBRoot* root, Node* node)
325 {
326     Node* parent, * gparent;
327 
328     // 若“父節點存在,並且父節點的顏色是紅色”
329     while ((parent = rb_parent(node)) && rb_is_red(parent))
330     {
331         gparent = rb_parent(parent);
332 
333         //若“父節點”是“祖父節點的左孩子”
334         if (parent == gparent->left)
335         {
336             // Case 1條件:叔叔節點是紅色
337             {
338                 Node* uncle = gparent->right;
339                 if (uncle && rb_is_red(uncle))
340                 {
341                     rb_set_black(uncle);
342                     rb_set_black(parent);
343                     rb_set_red(gparent);
344                     node = gparent;
345                     continue;
346                 }
347             }
348 
349             // Case 2條件:叔叔是黑色,且當前節點是右孩子
350             if (parent->right == node)
351             {
352                 Node* tmp;
353                 rbtree_left_rotate(root, parent);
354                 tmp = parent;
355                 parent = node;
356                 node = tmp;
357             }
358 
359             // Case 3條件:叔叔是黑色,且當前節點是左孩子。
360             rb_set_black(parent);
361             rb_set_red(gparent);
362             rbtree_right_rotate(root, gparent);
363         }
364         else//若“z的父節點”是“z的祖父節點的右孩子”
365         {
366             // Case 1條件:叔叔節點是紅色
367             {
368                 Node* uncle = gparent->left;
369                 if (uncle && rb_is_red(uncle))
370                 {
371                     rb_set_black(uncle);
372                     rb_set_black(parent);
373                     rb_set_red(gparent);
374                     node = gparent;
375                     continue;
376                 }
377             }
378 
379             // Case 2條件:叔叔是黑色,且當前節點是左孩子
380             if (parent->left == node)
381             {
382                 Node* tmp;
383                 rbtree_right_rotate(root, parent);
384                 tmp = parent;
385                 parent = node;
386                 node = tmp;
387             }
388 
389             // Case 3條件:叔叔是黑色,且當前節點是右孩子。
390             rb_set_black(parent);
391             rb_set_red(gparent);
392             rbtree_left_rotate(root, gparent);
393         }
394     }
395 
396     // 將根節點設為黑色
397     rb_set_black(root->node);
398 }
399 
400 /*
401  * 添加節點:將節點(node)插入到紅黑樹中
402  *
403  * 參數說明:
404  *     root 紅黑樹的根
405  *     node 插入的結點        // 對應《算法導論》中的z
406  */
407 static void rbtree_insert(RBRoot* root, Node* node)
408 {
409     Node* y = NULL;
410     Node* x = root->node;
411 
412     // 1. 將紅黑樹當作一顆二叉查找樹,將節點添加到二叉查找樹中。
413     while (x != NULL)
414     {
415         y = x;
416         if (node->key < x->key)
417             x = x->left;
418         else
419             x = x->right;
420     }
421     rb_parent(node) = y;
422 
423     if (y != NULL)
424     {
425         if (node->key < y->key)
426             y->left = node;                // 情況2:若“node所包含的值” < “y所包含的值”,則將node設為“y的左孩子”
427         else
428             y->right = node;            // 情況3:(“node所包含的值” >= “y所包含的值”)將node設為“y的右孩子” 
429     }
430     else
431     {
432         root->node = node;                // 情況1:若y是空節點,則將node設為根
433     }
434 
435     // 2. 設置節點的顏色為紅色
436     node->color = RED;
437 
438     // 3. 將它重新修正為一顆二叉查找樹
439     rbtree_insert_fixup(root, node);
440 }
441 
442 /*
443  * 創建結點
444  *
445  * 參數說明:
446  *     key 是鍵值。
447  *     parent 是父結點。
448  *     left 是左孩子。
449  *     right 是右孩子。
450  */
451 static Node* create_rbtree_node(Type key, Node* parent, Node* left, Node* right)
452 {
453     Node* p;
454 
455     if ((p = (Node*)malloc(sizeof(Node))) == NULL)
456         return NULL;
457     p->key = key;
458     p->left = left;
459     p->right = right;
460     p->parent = parent;
461     p->color = BLACK; // 默認為黑色
462 
463     return p;
464 }
465 
466 /*
467  * 新建結點(節點鍵值為key),並將其插入到紅黑樹中
468  *
469  * 參數說明:
470  *     root 紅黑樹的根
471  *     key 插入結點的鍵值
472  * 返回值:
473  *     0,插入成功
474  *     -1,插入失敗
475  */
476 int insert_rbtree(RBRoot* root, Type key)
477 {
478     Node* node;    // 新建結點
479 
480     // 不允許插入相同鍵值的節點。
481     // (若想允許插入相同鍵值的節點,注釋掉下面兩句話即可!)
482     if (search(root->node, key) != NULL)
483         return -1;
484 
485     // 如果新建結點失敗,則返回。
486     if ((node = create_rbtree_node(key, NULL, NULL, NULL)) == NULL)
487         return -1;
488 
489     rbtree_insert(root, node);
490 
491     return 0;
492 }
493 
494 /*
495  * 紅黑樹刪除修正函數
496  *
497  * 在從紅黑樹中刪除插入節點之后(紅黑樹失去平衡),再調用該函數;
498  * 目的是將它重新塑造成一顆紅黑樹。
499  *
500  * 參數說明:
501  *     root 紅黑樹的根
502  *     node 待修正的節點
503  */
504 static void rbtree_delete_fixup(RBRoot* root, Node* node, Node* parent)
505 {
506     Node* other;
507 
508     while ((!node || rb_is_black(node)) && node != root->node)
509     {
510         if (parent->left == node)
511         {
512             other = parent->right;
513             if (rb_is_red(other))
514             {
515                 // Case 1: x的兄弟w是紅色的  
516                 rb_set_black(other);
517                 rb_set_red(parent);
518                 rbtree_left_rotate(root, parent);
519                 other = parent->right;
520             }
521             if ((!other->left || rb_is_black(other->left)) &&
522                 (!other->right || rb_is_black(other->right)))
523             {
524                 // Case 2: x的兄弟w是黑色,且w的倆個孩子也都是黑色的  
525                 rb_set_red(other);
526                 node = parent;
527                 parent = rb_parent(node);
528             }
529             else
530             {
531                 if (!other->right || rb_is_black(other->right))
532                 {
533                     // Case 3: x的兄弟w是黑色的,並且w的左孩子是紅色,右孩子為黑色。  
534                     rb_set_black(other->left);
535                     rb_set_red(other);
536                     rbtree_right_rotate(root, other);
537                     other = parent->right;
538                 }
539                 // Case 4: x的兄弟w是黑色的;並且w的右孩子是紅色的,左孩子任意顏色。
540                 rb_set_color(other, rb_color(parent));
541                 rb_set_black(parent);
542                 rb_set_black(other->right);
543                 rbtree_left_rotate(root, parent);
544                 node = root->node;
545                 break;
546             }
547         }
548         else
549         {
550             other = parent->left;
551             if (rb_is_red(other))
552             {
553                 // Case 1: x的兄弟w是紅色的  
554                 rb_set_black(other);
555                 rb_set_red(parent);
556                 rbtree_right_rotate(root, parent);
557                 other = parent->left;
558             }
559             if ((!other->left || rb_is_black(other->left)) &&
560                 (!other->right || rb_is_black(other->right)))
561             {
562                 // Case 2: x的兄弟w是黑色,且w的倆個孩子也都是黑色的  
563                 rb_set_red(other);
564                 node = parent;
565                 parent = rb_parent(node);
566             }
567             else
568             {
569                 if (!other->left || rb_is_black(other->left))
570                 {
571                     // Case 3: x的兄弟w是黑色的,並且w的左孩子是紅色,右孩子為黑色。  
572                     rb_set_black(other->right);
573                     rb_set_red(other);
574                     rbtree_left_rotate(root, other);
575                     other = parent->left;
576                 }
577                 // Case 4: x的兄弟w是黑色的;並且w的右孩子是紅色的,左孩子任意顏色。
578                 rb_set_color(other, rb_color(parent));
579                 rb_set_black(parent);
580                 rb_set_black(other->left);
581                 rbtree_right_rotate(root, parent);
582                 node = root->node;
583                 break;
584             }
585         }
586     }
587     if (node)
588         rb_set_black(node);
589 }
590 
591 /*
592  * 刪除結點
593  *
594  * 參數說明:
595  *     tree 紅黑樹的根結點
596  *     node 刪除的結點
597  */
598 void rbtree_delete(RBRoot* root, Node* node)
599 {
600     Node* child, * parent;
601     int color;
602 
603     // 被刪除節點的"左右孩子都不為空"的情況。
604     if ((node->left != NULL) && (node->right != NULL))
605     {
606         // 被刪節點的后繼節點。(稱為"取代節點")
607         // 用它來取代"被刪節點"的位置,然后再將"被刪節點"去掉。
608         Node* replace = node;
609 
610         // 獲取后繼節點
611         replace = replace->right;
612         while (replace->left != NULL)
613             replace = replace->left;
614 
615         // "node節點"不是根節點(只有根節點不存在父節點)
616         if (rb_parent(node))
617         {
618             if (rb_parent(node)->left == node)
619                 rb_parent(node)->left = replace;
620             else
621                 rb_parent(node)->right = replace;
622         }
623         else
624             // "node節點"是根節點,更新根節點。
625             root->node = replace;
626 
627         // child是"取代節點"的右孩子,也是需要"調整的節點"。
628         // "取代節點"肯定不存在左孩子!因為它是一個后繼節點。
629         child = replace->right;
630         parent = rb_parent(replace);
631         // 保存"取代節點"的顏色
632         color = rb_color(replace);
633 
634         // "被刪除節點"是"它的后繼節點的父節點"
635         if (parent == node)
636         {
637             parent = replace;
638         }
639         else
640         {
641             // child不為空
642             if (child)
643                 rb_set_parent(child, parent);
644             parent->left = child;
645 
646             replace->right = node->right;
647             rb_set_parent(node->right, replace);
648         }
649 
650         replace->parent = node->parent;
651         replace->color = node->color;
652         replace->left = node->left;
653         node->left->parent = replace;
654 
655         if (color == BLACK)
656             rbtree_delete_fixup(root, child, parent);
657         free(node);
658 
659         return;
660     }
661 
662     if (node->left != NULL)
663         child = node->left;
664     else
665         child = node->right;
666 
667     parent = node->parent;
668     // 保存"取代節點"的顏色
669     color = node->color;
670 
671     if (child)
672         child->parent = parent;
673 
674     // "node節點"不是根節點
675     if (parent)
676     {
677         if (parent->left == node)
678             parent->left = child;
679         else
680             parent->right = child;
681     }
682     else
683         root->node = child;
684 
685     if (color == BLACK)
686         rbtree_delete_fixup(root, child, parent);
687     free(node);
688 }
689 
690 /*
691  * 刪除鍵值為key的結點
692  *
693  * 參數說明:
694  *     tree 紅黑樹的根結點
695  *     key 鍵值
696  */
697 void delete_rbtree(RBRoot* root, Type key)
698 {
699     Node* z, * node;
700 
701     if ((z = search(root->node, key)) != NULL)
702         rbtree_delete(root, z);
703 }
704 
705 /*
706  * 銷毀紅黑樹
707  */
708 static void rbtree_destroy(RBTree tree)
709 {
710     if (tree == NULL)
711         return;
712 
713     if (tree->left != NULL)
714         rbtree_destroy(tree->left);
715     if (tree->right != NULL)
716         rbtree_destroy(tree->right);
717 
718     free(tree);
719 }
720 
721 void destroy_rbtree(RBRoot* root)
722 {
723     if (root != NULL)
724         rbtree_destroy(root->node);
725 
726     free(root);
727 }
728 
729 /*
730  * 打印"紅黑樹"
731  *
732  * tree       -- 紅黑樹的節點
733  * key        -- 節點的鍵值
734  * direction  --  0,表示該節點是根節點;
735  *               -1,表示該節點是它的父結點的左孩子;
736  *                1,表示該節點是它的父結點的右孩子。
737  */
738 static void rbtree_print(RBTree tree, Type key, int direction)
739 {
740     if (tree != NULL)
741     {
742         if (direction == 0)    // tree是根節點
743             printf("%2d(B) is root\n", tree->key);
744         else                // tree是分支節點
745             printf("%2d(%s) is %2d's %6s child\n", tree->key, rb_is_red(tree) ? "R" : "B", key, direction == 1 ? "right" : "left");
746 
747         rbtree_print(tree->left, tree->key, -1);
748         rbtree_print(tree->right, tree->key, 1);
749     }
750 }
751 
752 void print_rbtree(RBRoot* root)
753 {
754     if (root != NULL && root->node != NULL)
755         rbtree_print(root->node, root->node->key, 0);
756 }
rbtree.cpp

測試程序

 1 #include <stdio.h>
 2 #include <iostream>
 3 
 4 #include "rbtree.h"
 5 
 6 #define CHECK_INSERT 1    // "插入"動作的檢測開關(0,關閉;1,打開)
 7 #define CHECK_DELETE 0    // "刪除"動作的檢測開關(0,關閉;1,打開)
 8 #define LENGTH(a) ( (sizeof(a)) / (sizeof(a[0])) )
 9 
10 int main()
11 {
12     int a[] = { 10, 40, 30, 60, 90, 70, 20, 50, 80 };
13     int i, ilen = LENGTH(a);
14     RBRoot* root = NULL;
15 
16     root = create_rbtree();
17     printf("== 原始數據: ");
18     for (i = 0; i < ilen; i++)
19         printf("%d ", a[i]);
20     printf("\n");
21 
22     for (i = 0; i < ilen; i++)
23     {
24         insert_rbtree(root, a[i]);
25 #if CHECK_INSERT
26         printf("== 添加節點: %d\n", a[i]);
27         printf("== 樹的詳細信息: \n");
28         print_rbtree(root);
29         printf("\n");
30 #endif
31     }
32 
33     printf("== 前序遍歷: ");
34     preorder_rbtree(root);
35 
36     printf("\n== 中序遍歷: ");
37     inorder_rbtree(root);
38 
39     printf("\n== 后序遍歷: ");
40     postorder_rbtree(root);
41     printf("\n");
42 
43     if (rbtree_minimum(root, &i) == 0)
44         printf("== 最小值: %d\n", i);
45     if (rbtree_maximum(root, &i) == 0)
46         printf("== 最大值: %d\n", i);
47     printf("== 樹的詳細信息: \n");
48     print_rbtree(root);
49     printf("\n");
50 
51 #if CHECK_DELETE
52     for (i = 0; i < ilen; i++)
53     {
54         delete_rbtree(root, a[i]);
55 
56         printf("== 刪除節點: %d\n", a[i]);
57         if (root)
58         {
59             printf("== 樹的詳細信息: \n");
60             print_rbtree(root);
61             printf("\n");
62         }
63     }
64 #endif
65 
66     destroy_rbtree(root);
67 
68 
69     system("pause");
70     return 0;
71 
72 }
main.cpp

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM