【算法导论】学习笔记——第14章 数据结构的扩张

这一章节特别有意思。习题也比较多,但是很容易掌握。主要描述的就是在已知数据结构的基础上,通过增加或修改部分基础操作。来构造更加有效的新数据结构。

14.1 动态数据统计
本节主要介绍如何修改红黑树,使得可以在O(lgn)时间内确定顺序统计量,如何在O(lgn)时间内确定一个元素的秩,即它在集合线性序中的位置。顺序统计树(order-static tree)T只是简单地在每个结点上存储附加信息的一棵红黑树,附加信息是当前子树的size大小。源代码如下:

  1 #include <iostream>
  2 #include <cstdio>
  3 #include <cstring>
  4 #include <cstdlib>
  5 #include <algorithm>
  6 using namespace std;
  7 
  8 #define LOCAL_DEBUG
  9 #define RED        true
 10 #define BLACK    false
 11 
 12 typedef struct Node_t {
 13     bool color;
 14     int key, size;
 15     Node_t *p, *left, *right;
 16     Node_t() {}
 17     Node_t(int kkey) {
 18         key = kkey;
 19     }
 20 } Node_t;
 21 
 22 typedef struct Tree_t {
 23     Node_t *NIL;
 24     Node_t *root;
 25     Tree_t() {
 26         NIL = new Node_t();
 27         NIL->key = 0;
 28         NIL->size = 0;
 29         NIL->color = BLACK;
 30         NIL->p = NIL->left = NIL->right = NIL;
 31         root = NIL;
 32     }
 33 } Tree_t;
 34 
 35 Tree_t *t;
 36 
 37 void Inorder_RBTree_Walk(Tree_t *t, Node_t *x) {
 38     if (x != t->NIL) {
 39         Inorder_RBTree_Walk(t, x->left);
 40         printf("key: %d, size: %d\n", x->key, x->size);
 41         Inorder_RBTree_Walk(t, x->right);
 42     }
 43 }
 44 
 45 void Preorder_RBTree_Walk(Tree_t *t, Node_t *x) {
 46     if (x != t->NIL) {
 47         printf("key: %d, size: %d\n", x->key, x->size);
 48         Preorder_RBTree_Walk(t, x->left);
 49         Preorder_RBTree_Walk(t, x->right);
 50     }
 51 }
 52 
 53 void Postorder_RBTree_Walk(Tree_t *t, Node_t *x) {
 54     if (x != t->NIL) {
 55         Postorder_RBTree_Walk(t, x->left);
 56         Postorder_RBTree_Walk(t, x->right);
 57         printf("key: %d, size: %d\n", x->key, x->size);
 58     }
 59 }
 60 
 61 void Inorder_RBTree_Walk_WithColor(Tree_t *t, Node_t *x) {
 62     if (x != t->NIL) {
 63         Inorder_RBTree_Walk_WithColor(t, x->left);
 64         printf("key: %d, size: %d, color: %s\n", x->key, x->size, x->color?"Red":"Black");
 65         Inorder_RBTree_Walk_WithColor(t, x->right);
 66     }
 67 }
 68 
 69 void Preorder_RBTree_Walk_WithColor(Tree_t *t, Node_t *x) {
 70     if (x != t->NIL) {
 71         printf("key: %d, size: %d, color: %s\n", x->key, x->size, x->color?"Red":"Black");
 72         Preorder_RBTree_Walk_WithColor(t, x->left);
 73         Preorder_RBTree_Walk_WithColor(t, x->right);
 74     }
 75 }
 76 
 77 void Postorder_RBTree_Walk_WithColor(Tree_t *t, Node_t *x) {
 78     if (x != t->NIL) {
 79         Postorder_RBTree_Walk_WithColor(t, x->left);
 80         Postorder_RBTree_Walk_WithColor(t, x->right);
 81         printf("key: %d, size: %d, color: %s\n", x->key, x->size, x->color?"Red":"Black");
 82     }
 83 }
 84 
 85 Node_t *RBTree_Minimum(Tree_t *t, Node_t *x) {
 86     while (x->left != t->NIL)
 87         x = x->left;
 88     return x;
 89 }
 90 
 91 Node_t *RBTree_Maximum(Tree_t *t, Node_t *x) {
 92     while (x->right != t->NIL)
 93         x = x->right;
 94     return x;
 95 }
 96 
 97 Node_t *RBTree_Search(Tree_t *t, int key) {
 98     Node_t *x = t->root;
 99     while (x!=t->NIL && x->key!=key) {
100         if (key < x->key) {
101             x = x->left;
102         } else {
103             x = x->right;
104         }
105     }
106     return x;
107 }
108 
109 void Left_Rotate(Tree_t *t, Node_t *x) {
110     Node_t *y = x->right;
111     x->right = y->left;
112     if (y->left != t->NIL)
113         y->left->p = x;
114     y->p = x->p;
115     if (x->p == t->NIL) {
116         // x is root
117         t->root = y;    
118     } else if (x == x->p->left) {
119         x->p->left = y;
120     } else {
121         x->p->right = y;
122     }
123     y->left = x;
124     x->p = y;
125     y->size = x->size;
126     x->size = x->left->size + x->right->size + 1;
127 }
128 
129 void Right_Rotate(Tree_t *t, Node_t *y) {
130     Node_t *x = y->left;
131     y->left = x->right;
132     if (x->right != t->NIL)
133         x->right->p = y;
134     x->p = y->p;
135     if (y->p == t->NIL) {
136         // y is root
137         t->root = x;
138     } else if (y == y->p->left) {
139         y->p->left = x;
140     } else {
141         y->p->right = x;
142     }
143     x->right = y;
144     y->p = x;
145     x->size = y->size;
146     y->size = y->left->size + y->right->size + 1;
147 }
148 
149 void RBTree_Transplant(Tree_t *t, Node_t *u, Node_t *v) {
150     if (u->p == t->NIL) {
151         t->root = v;
152     } else if (u == u->p->left) {
153         u->p->left = v;
154     } else {
155         u->p->right = v;
156     }
157     v->p = u->p;
158 }
159 
160 void RBTree_Insert_Fixup(Tree_t *t, Node_t *z) {
161     Node_t *y;
162     
163     while (z->p->color == RED) {
164         // means z->p->p->color == BLACK
165         if (z->p == z->p->p->left) {
166             y = z->p->p->right;
167             if (y->color == RED) {
168                 z->p->color = BLACK;
169                 y->color = BLACK;
170                 z->p->p->color = RED;
171                 z = z->p->p;
172             } else {
173                 // y->color is BLACK
174                 if (z == z->p->right) {
175                     z = z->p;
176                     Left_Rotate(t, z);
177                 }
178                 z->p->color = BLACK;    // break later
179                 z->p->p->color = RED;
180                 Right_Rotate(t, z->p->p);
181             }
182         } else {
183             y = z->p->p->left;
184             if (y->color == RED) {
185                 z->p->color = BLACK;
186                 y->color = BLACK;
187                 z->p->p->color = RED;
188                 z = z->p->p;
189             } else {
190                 // y->color is BLACK
191                 if (z == z->p->left) {
192                     z = z->p;
193                     Right_Rotate(t, z);
194                 }
195                 z->p->color = BLACK;    // break later
196                 z->p->p->color = RED;
197                 Left_Rotate(t, z->p->p);
198             }
199         }
200     }
201     t->root->color = BLACK;
202 }
203 
204 void RBTree_Insert(Tree_t *t, Node_t *z) {
205     Node_t *y = t->NIL;
206     Node_t *x = t->root;
207     while (x != t->NIL) {
208         y = x;
209         ++x->size;
210         if (z->key < x->key) {
211             x = x->left;
212         } else {
213             x = x->right;
214         }
215     }
216     z->p = y;
217     if (y == t->NIL) {
218         // tree is empty
219         t->root = z;
220     } else if (z->key < y->key) {
221         y->left = z;
222     } else {
223         y->right = z;
224     }
225     z->left = z->right = t->NIL;
226     z->color = RED;
227     z->size = 1;
228     RBTree_Insert_Fixup(t, z);
229 }
230 
231 void RBTree_Delete_Fixup(Tree_t *t, Node_t *x) {
232     Node_t *w;
233     
234     while (x!=t->root && x->color==BLACK) {
235         if (x == x->p->left) {
236             w = x->p->right;
237             if (w->color == RED) {
238                 w->color = BLACK;
239                 x->p->color = RED;
240                 Left_Rotate(t, x->p);
241                 w = x->p->right;
242             }
243             // means w->color == BLACK
244             if (w->left->color==BLACK && w->right->color==BLACK) {
245                 w->color = RED;
246                 x = x->p;    // fetch the black in w & x and pass it to x->p
247             } else {
248                 if (w->right->color == BLACK) {
249                     // means w->left->color == RED
250                     w->left->color = BLACK;
251                     w->color = RED;
252                     Right_Rotate(t, w);
253                     w = x->p->right;
254                 }
255                 // means w->right->color == RED && w->left->color == uncertain
256                 w->color = x->p->color;
257                 x->p->color = BLACK;
258                 w->right->color = BLACK;
259                 Left_Rotate(t, x->p);
260                 x = t->root;
261             }
262         } else {
263             w = x->p->left;
264             if (w->color == RED) {
265                 w->color = BLACK;
266                 x->p->color = RED;
267                 Right_Rotate(t, x->p);
268                 w = x->p->left;
269             }
270             // means w->color == BLACK
271             if (w->left->color==BLACK && w->right->color==BLACK) {
272                 w->color = RED;
273                 x = x->p; // fetch the black in w & x and pass it to x->p
274             } else {
275                 if (w->left->color == BLACK) {
276                     // means x->right->color == RED
277                     w->right->color = BLACK;
278                     w->color = RED;
279                     Left_Rotate(t, w);
280                     w = x->p->left;
281                 }
282                 // means w->left->color == RED && w->right->color = ANY
283                 w->color = x->p->color;
284                 x->p->color = BLACK;
285                 w->left->color = BLACK;
286                 Right_Rotate(t, x->p);
287                 x = t->root;
288             }
289         }
290     }
291     x->color = BLACK;
292 }
293 
294 void RBTree_Delete(Tree_t *t, Node_t *z) {
295     Node_t *x, *y = z;
296     Node_t *q;    // q used to back trace for maintening the [size] of Node_t
297     bool y_original_color = y->color;
298     
299     if (z->left == t->NIL) {
300         x = z->right;
301         q = y->p;
302         RBTree_Transplant(t, y, x);
303     } else if (z->right == t->NIL) {
304         x = z->left;
305         RBTree_Transplant(t, y, x);
306         q = y->p;
307     } else {
308         y = RBTree_Minimum(t, z->right);
309         y_original_color = y->color;
310         x = y->right;
311         if (y->p == z) {
312             x->p = y;
313             q = y;
314         } else {
315             RBTree_Transplant(t, y, x);
316             q = y->p;
317             y->right = z->right;
318             y->right->p = y;
319         }
320         RBTree_Transplant(t, z, y);
321         y->left = z->left;
322         y->left->p = y;
323         y->color = z->color;
324         y->size = z->size;
325     }
326     
327     // maintence the [size] of Node_t
328     while (q != t->NIL) {
329         --q->size;
330         printf("key=%d,size=%d, --\n", q->key, q->size);
331         q = q->p;
332     }
333     
334     if (y_original_color == BLACK)
335         RBTree_Delete_Fixup(t, x);    // use x replace y
336 }
337 
338 int check_BHeight(Tree_t *t, Node_t *x, bool &f) {
339     if (x == t->NIL)
340         return 1;
341     int lBH = check_BHeight(t, x->left, f);
342     int rBH = check_BHeight(t, x->right, f);
343     
344     if (f == false)
345         return 0;
346     
347     if (lBH != rBH)
348         f = false;
349     if (x->color == BLACK)
350         return lBH+1;
351     return lBH;
352 }
353 
354 bool check_RNode(Tree_t *t, Node_t *x) {
355     if (x == t->NIL)
356         return true;
357     if (x->color==RED && (x->left->color!=BLACK || x->right->color!=BLACK)) {
358         return false;
359     }
360     return check_RNode(t, x->left) && check_RNode(t, x->right);
361 }
362 
363 bool check_Size(Tree_t *t, Node_t *x) {
364     if (x == t->NIL) {
365         return x->size == 0;
366     }
367     
368     if (x->left->size+x->right->size+1 != x->size) {
369         printf("check_size: key=%d, size=%d, wrong!!!\n", x->key, x->size);
370         printf("x->left: key=%d, size=%d\n", x->left->key, x->left->size);
371         printf("x->right: key=%d, size=%d\n", x->right->key, x->right->size);
372         return false;
373     }
374     return check_Size(t, x->left) && check_Size(t, x->right) && x->left->size+x->right->size+1==x->size;
375 }
376 
377 bool check_RBTree(Tree_t *t) {
378     bool ret = true;
379     
380     if (t->NIL->color != BLACK)
381         return false;
382     if (t->root == t->NIL)
383         return ret;
384     if (t->root->color != BLACK)
385         return false;
386     
387     ret = check_RNode(t, t->root);
388     if (ret == false) {
389         puts("not fit B<-R->B");
390         return false;
391     }
392     
393     ret = check_Size(t, t->root);
394     if (ret == false) {
395         puts("size not fit");
396         return false;
397     }
398     
399     check_BHeight(t, t->root, ret);
400     if (ret == false)
401         puts("BHeight not fit");
402     
403     return ret;
404 }
405 
406 Node_t *OS_Select(Tree_t *t, Node_t *x, int i) {
407     int r = x->left->size + 1;
408     if (r == i)
409         return x;
410     else if (r > i)
411         return OS_Select(t, x->left, i);
412     else
413         return OS_Select(t, x->right, i-r);
414 }
415 
416 int OS_Rank(Tree_t *t, Node_t *x) {
417     int r = x->left->size + 1;
418     Node_t *y = x;
419     while (y != t->root) {
420         if (y == y->p->right)
421             r += y->p->left->size + 1;
422         y = y->p;
423     }
424     return r;
425 }
426 
427 void init() {
428     t = new Tree_t();
429     int a[] = {26, 17, 41, 14, 21, 30, 47, 10, 16, 19, 21, 28, 38, 7, 12, 14, 20, 35, 39, 3};
430     int n = sizeof(a) / sizeof(int);
431     Node_t *p;
432     
433     printf("n = %d\n", n);
434     for (int i=0; i<n; ++i) {
435         p = new Node_t(a[i]);
436         RBTree_Insert(t, p);
437     }
438     
439     Inorder_RBTree_Walk_WithColor(t, t->root);
440     if (check_RBTree(t))
441         puts("Right");
442     else
443         puts("Wrong");
444     printf("\n");
445 }
446 
447 void test_delete() {
448     Tree_t *t = new Tree_t();
449     int a[] = {26, 17, 41, 14, 21, 30, 47, 10, 16, 19, 21, 28, 38, 7, 12, 14, 20, 35, 39, 3};
450     int n = sizeof(a) / sizeof(int);
451     bool visit[30];
452     int i, j, k;
453     Node_t *p;
454     
455     printf("n = %d\n", n);
456     for (i=0; i<n; ++i) {
457         p = new Node_t(a[i]);
458         RBTree_Insert(t, p);
459     }
460     
461     memset(visit, false, sizeof(visit));
462     for (i=0; i<n; ++i) {
463         while (1) {
464             j = rand()%n;
465             if (visit[j] == false)
466                 break;
467         }
468         visit[j] = true;
469         p = RBTree_Search(t, a[j]);
470         printf("delete %d\n", a[j]);
471         RBTree_Delete(t, p);
472         Inorder_RBTree_Walk_WithColor(t, t->root);
473         if (check_RBTree(t))
474             puts("Right");
475         else
476             puts("Wrong");
477         RBTree_Insert(t, p);
478         if (check_RBTree(t))
479             puts("Right");
480         else
481             puts("Wrong");
482         printf("\n\n\n");
483     }
484 }
485 
486 int main() {
487     
488     #ifdef LOCAL_DEBUG
489         freopen("data.in", "r", stdin);
490         freopen("data.out", "w", stdout);
491     #endif
492     
493     //init();
494     test_delete();
495     
496     return 0;
497 }
View Code

 

14.1-5


14.1-6
注意在新的秩的定义下, x.size = x.left.size + 1. 因此,相关函数修改为

 1 void RBTree_Insert(Tree_t *t, Node_t *z) {
 2         ......
 3         while (x != t->NIL) {
 4             y = x;
 5             if (z->key < x->key) {
 6                 ++x->size;
 7                 x = x->left;
 8             } else {
 9                 x = x->right;
10             }
11         }
12         ......
13     }
14 
15     void Left_Rotate(Tree_t *t, Node_t *x) {
16         ......
17         y->size += x->left->size;
18     }
19 
20     void Right_Rotate(Tree_t *t, Node_t *y) {
21         ......
22         y->size -= x->left->size;
23     }
24 
25     void RBTree_Delete(Tree_t *t, Node_t *z) {
26         ......
27         while (q != t->NIL) {
28             if (q == q->p->left)
29                 --q->size;
30             q = q->p;
31         }
32     }


14.1-7


14.2 如何扩张数据结构
扩张一种数据结构一般分为4个步骤:
1. 选择一种基础数据结构;
2. 确定基础数据结构中要维护的附加信息;
3. 检验基础数据结构上的基本修改操作能否维护附加信息;
4. 设计一些新操作。
这一章节还有一个非常有意思的定理。
定理14.1 设f是n个结点的红黑树T扩张的属性,且假设对任一结点x,f的值仅依赖于结点x、x.left和x.right的信息,还可能包括x.left.f和x.right.f。那么,我们可以再插入或删除操作期间对T的所有结点的f值进行维护,并且不影响这两个操作的渐进时间性能。
这个定理主要说的是x.f如何仅依赖于x,x.left,x.right以及x.left.f,x.right.f,那么就可以在原始时间复杂度的基础上稍作修改维护新的属性f。
该章节后面的大部分习题都以此为基础。

14.2-1
其实就和线索树一样,增加4个指针并进行维护。

14.2-2
可以,可以参考英文参考答案。

14.3 区间树
这里的区间树特别像线段树。区间树是定理14.1的应用。
区间三分律(interval trichotomy),任何两个区间i和i'满足下面三条性质之一:
a. i和i'重叠;
b. i在i'的左边,即i.high < i'.low;
c. i在i'的右边,即i'.high < i.low;
区间树源代码如下:

  1 #include <iostream>
  2 #include <cstdio>
  3 #include <cstring>
  4 #include <cstdlib>
  5 #include <algorithm>
  6 using namespace std;
  7 
  8 #define LOCAL_DEBUG
  9 #define RED        true
 10 #define BLACK    false
 11 #define INF        9999999
 12 
 13 typedef struct interval_t {
 14     int low, high;
 15     interval_t() {}
 16     interval_t(int l, int h) {
 17         low = l; high = h;
 18     }
 19     friend bool operator ==(const interval_t &a, const interval_t &b) {
 20         return a.low==b.low && a.high==b.high;
 21     }
 22 } interval_t;
 23 
 24 typedef struct Node_t {
 25     bool color;
 26     int key, mmax;
 27     interval_t intr;
 28     Node_t *p, *left, *right;
 29     Node_t() {}
 30     Node_t(interval_t iintr) {
 31         intr = iintr;
 32         key = iintr.low;
 33     }
 34 } Node_t;
 35 
 36 typedef struct Tree_t {
 37     Node_t *NIL;
 38     Node_t *root;
 39     Tree_t() {
 40         NIL = new Node_t();
 41         NIL->key = 0;
 42         NIL->mmax = -INF;
 43         NIL->color = BLACK;
 44         NIL->p = NIL->left = NIL->right = NIL;
 45         root = NIL;
 46     }
 47 } Tree_t;
 48 
 49 Tree_t *t;
 50 
 51 void Inorder_RBTree_Walk(Tree_t *t, Node_t *x) {
 52     if (x != t->NIL) {
 53         Inorder_RBTree_Walk(t, x->left);
 54         printf("[%d, %d] | %d\n", x->intr.low, x->intr.high, x->mmax);
 55         Inorder_RBTree_Walk(t, x->right);
 56     }
 57 }
 58 
 59 void Preorder_RBTree_Walk(Tree_t *t, Node_t *x) {
 60     if (x != t->NIL) {
 61         printf("[%d, %d] | %d\n", x->intr.low, x->intr.high, x->mmax);
 62         Preorder_RBTree_Walk(t, x->left);
 63         Preorder_RBTree_Walk(t, x->right);
 64     }
 65 }
 66 
 67 void Postorder_RBTree_Walk(Tree_t *t, Node_t *x) {
 68     if (x != t->NIL) {
 69         Postorder_RBTree_Walk(t, x->left);
 70         Postorder_RBTree_Walk(t, x->right);
 71         printf("[%d, %d] | %d\n", x->intr.low, x->intr.high, x->mmax);
 72     }
 73 }
 74 
 75 void Inorder_RBTree_Walk_WithColor(Tree_t *t, Node_t *x) {
 76     if (x != t->NIL) {
 77         Inorder_RBTree_Walk_WithColor(t, x->left);
 78         printf("%s: [%d, %d] | %d\n", x->color?"Red":"Black", x->intr.low, x->intr.high, x->mmax);
 79         Inorder_RBTree_Walk_WithColor(t, x->right);
 80     }
 81 }
 82 
 83 void Preorder_RBTree_Walk_WithColor(Tree_t *t, Node_t *x) {
 84     if (x != t->NIL) {
 85         printf("%s: [%d, %d] | %d\n", x->color?"Red":"Black", x->intr.low, x->intr.high, x->mmax);
 86         Preorder_RBTree_Walk_WithColor(t, x->left);
 87         Preorder_RBTree_Walk_WithColor(t, x->right);
 88     }
 89 }
 90 
 91 void Postorder_RBTree_Walk_WithColor(Tree_t *t, Node_t *x) {
 92     if (x != t->NIL) {
 93         Postorder_RBTree_Walk_WithColor(t, x->left);
 94         Postorder_RBTree_Walk_WithColor(t, x->right);
 95         printf("%s: [%d, %d] | %d\n", x->color?"Red":"Black", x->intr.low, x->intr.high, x->mmax);
 96     }
 97 }
 98 
 99 Node_t *RBTree_Minimum(Tree_t *t, Node_t *x) {
100     while (x->left != t->NIL)
101         x = x->left;
102     return x;
103 }
104 
105 Node_t *RBTree_Maximum(Tree_t *t, Node_t *x) {
106     while (x->right != t->NIL)
107         x = x->right;
108     return x;
109 }
110 
111 bool overlap(interval_t a, interval_t b) {
112     return b.low<=a.high && a.low<=b.high;
113 }
114 
115 Node_t *RBTree_Search(Tree_t *t, interval_t intr) {
116     Node_t *x = t->root;
117     while (x!=t->NIL && !overlap(intr, x->intr)) {
118         if (x->left!=t->NIL && x->left->mmax>=intr.low) {
119             x = x->left;
120         } else {
121             x = x->right;
122         }
123     }
124     return x;
125 }
126 
127 void Left_Rotate(Tree_t *t, Node_t *x) {
128     Node_t *y = x->right;
129     x->right = y->left;
130     if (y->left != t->NIL)
131         y->left->p = x;
132     y->p = x->p;
133     if (x->p == t->NIL) {
134         // x is root
135         t->root = y;    
136     } else if (x == x->p->left) {
137         x->p->left = y;
138     } else {
139         x->p->right = y;
140     }
141     y->left = x;
142     x->p = y;
143     // maintenance attr mmax
144     x->mmax = max(
145         max(x->left->mmax, x->right->mmax), x->intr.high
146     );
147     y->mmax = max(
148         max(y->left->mmax, y->right->mmax), y->intr.high
149     );
150 }
151 
152 void Right_Rotate(Tree_t *t, Node_t *y) {
153     Node_t *x = y->left;
154     y->left = x->right;
155     if (x->right != t->NIL)
156         x->right->p = y;
157     x->p = y->p;
158     if (y->p == t->NIL) {
159         // y is root
160         t->root = x;
161     } else if (y == y->p->left) {
162         y->p->left = x;
163     } else {
164         y->p->right = x;
165     }
166     x->right = y;
167     y->p = x;
168     // maintenance attr mmax
169     y->mmax = max(
170         max(y->left->mmax, y->right->mmax), y->intr.high
171     );
172     x->mmax = max(
173         max(x->left->mmax, x->right->mmax), x->intr.high
174     );
175 }
176 
177 void RBTree_Transplant(Tree_t *t, Node_t *u, Node_t *v) {
178     if (u->p == t->NIL) {
179         t->root = v;
180     } else if (u == u->p->left) {
181         u->p->left = v;
182     } else {
183         u->p->right = v;
184     }
185     v->p = u->p;
186 }
187 
188 void RBTree_Insert_Fixup(Tree_t *t, Node_t *z) {
189     Node_t *y;
190     
191     while (z->p->color == RED) {
192         // means z->p->p->color == BLACK
193         if (z->p == z->p->p->left) {
194             y = z->p->p->right;
195             if (y->color == RED) {
196                 z->p->color = BLACK;
197                 y->color = BLACK;
198                 z->p->p->color = RED;
199                 z = z->p->p;
200             } else {
201                 // y->color is BLACK
202                 if (z == z->p->right) {
203                     z = z->p;
204                     Left_Rotate(t, z);
205                 }
206                 z->p->color = BLACK;    // break later
207                 z->p->p->color = RED;
208                 Right_Rotate(t, z->p->p);
209             }
210         } else {
211             y = z->p->p->left;
212             if (y->color == RED) {
213                 z->p->color = BLACK;
214                 y->color = BLACK;
215                 z->p->p->color = RED;
216                 z = z->p->p;
217             } else {
218                 // y->color is BLACK
219                 if (z == z->p->left) {
220                     z = z->p;
221                     Right_Rotate(t, z);
222                 }
223                 z->p->color = BLACK;    // break later
224                 z->p->p->color = RED;
225                 Left_Rotate(t, z->p->p);
226             }
227         }
228     }
229     t->root->color = BLACK;
230 }
231 
232 void RBTree_Insert(Tree_t *t, Node_t *z) {
233     Node_t *y = t->NIL;
234     Node_t *x = t->root;
235     Node_t *q;
236     
237     while (x != t->NIL) {
238         y = x;
239         if (z->key < x->key) {
240             x = x->left;
241         } else {
242             x = x->right;
243         }
244     }
245     z->p = y;
246     if (y == t->NIL) {
247         // tree is empty
248         t->root = z;
249     } else if (z->key < y->key) {
250         y->left = z;
251     } else {
252         y->right = z;
253     }
254     z->left = z->right = t->NIL;
255     z->color = RED;
256     // maintence the [mmax] of tree
257     q = z;
258     while (q != t->NIL) {
259         q->mmax = max(
260             max(q->left->mmax, q->right->mmax), q->intr.high
261         );
262         q = q->p;
263     }
264     RBTree_Insert_Fixup(t, z);
265 }
266 
267 void RBTree_Delete_Fixup(Tree_t *t, Node_t *x) {
268     Node_t *w;
269     
270     while (x!=t->root && x->color==BLACK) {
271         if (x == x->p->left) {
272             w = x->p->right;
273             if (w->color == RED) {
274                 w->color = BLACK;
275                 x->p->color = RED;
276                 Left_Rotate(t, x->p);
277                 w = x->p->right;
278             }
279             // means w->color == BLACK
280             if (w->left->color==BLACK && w->right->color==BLACK) {
281                 w->color = RED;
282                 x = x->p;    // fetch the black in w & x and pass it to x->p
283             } else {
284                 if (w->right->color == BLACK) {
285                     // means w->left->color == RED
286                     w->left->color = BLACK;
287                     w->color = RED;
288                     Right_Rotate(t, w);
289                     w = x->p->right;
290                 }
291                 // means w->right->color == RED && w->left->color == uncertain
292                 w->color = x->p->color;
293                 x->p->color = BLACK;
294                 w->right->color = BLACK;
295                 Left_Rotate(t, x->p);
296                 x = t->root;
297             }
298         } else {
299             w = x->p->left;
300             if (w->color == RED) {
301                 w->color = BLACK;
302                 x->p->color = RED;
303                 Right_Rotate(t, x->p);
304                 w = x->p->left;
305             }
306             // means w->color == BLACK
307             if (w->left->color==BLACK && w->right->color==BLACK) {
308                 w->color = RED;
309                 x = x->p; // fetch the black in w & x and pass it to x->p
310             } else {
311                 if (w->left->color == BLACK) {
312                     // means x->right->color == RED
313                     w->right->color = BLACK;
314                     w->color = RED;
315                     Left_Rotate(t, w);
316                     w = x->p->left;
317                 }
318                 // means w->left->color == RED && w->right->color = ANY
319                 w->color = x->p->color;
320                 x->p->color = BLACK;
321                 w->left->color = BLACK;
322                 Right_Rotate(t, x->p);
323                 x = t->root;
324             }
325         }
326     }
327     x->color = BLACK;
328 }
329 
330 void RBTree_Delete(Tree_t *t, Node_t *z) {
331     Node_t *x, *y = z;
332     Node_t *q;    // q used to back trace for maintening the [mmax] of Node_t
333     bool y_original_color = y->color;
334     
335     if (z->left == t->NIL) {
336         x = z->right;
337         q = y->p;
338         RBTree_Transplant(t, y, x);
339     } else if (z->right == t->NIL) {
340         x = z->left;
341         RBTree_Transplant(t, y, x);
342         q = y->p;
343     } else {
344         y = RBTree_Minimum(t, z->right);
345         y_original_color = y->color;
346         x = y->right;
347         if (y->p == z) {
348             x->p = y;
349             q = y;
350         } else {
351             RBTree_Transplant(t, y, x);
352             q = y->p;
353             y->right = z->right;
354             y->right->p = y;
355         }
356         RBTree_Transplant(t, z, y);
357         y->left = z->left;
358         y->left->p = y;
359         y->color = z->color;
360     }
361     
362     // maintence the [size] of Node_t
363     while (q != t->NIL) {
364         q->mmax = max(
365             max(q->left->mmax, q->right->mmax), q->intr.high
366         );
367         q = q->p;
368     }
369     
370     if (y_original_color == BLACK)
371         RBTree_Delete_Fixup(t, x);    // use x replace y
372 }
373 
374 Node_t *RBTree_Search_Min(Tree_t *t, Node_t *z, interval_t intr) {
375     Node_t *x;    
376     
377     if (z == t->NIL)
378         return t->NIL;
379     
380     if (z->left!=t->NIL && z->left->mmax>=intr.low) {
381         x = RBTree_Search_Min(t, z->left, intr);
382         if (x != t->NIL)
383             return x;
384     }
385     
386     if (overlap(intr, z->intr))
387         return z;
388     
389     if (z->right != t->NIL)
390         return RBTree_Search_Min(t, z->right, intr);
391     
392     return t->NIL;
393 }
394 
395 void RBTree_Search_All(Tree_t *t, Node_t *z, interval_t intr) {
396     Node_t *x;
397     
398     if (z == t->NIL)
399         return ;
400     
401     if (z->left!=t->NIL && z->left->mmax>=intr.low) {
402         RBTree_Search_All(t, z->left, intr);
403     }
404     
405     if (overlap(intr, z->intr)) {
406         printf("[%d, %d]\n", z->intr.low, z->intr.high);
407     }
408     
409     if (z->right!=t->NIL && z->right->mmax>=intr.low) {
410         RBTree_Search_All(t, z->right, intr);
411     }
412 }
413 
414 Node_t *RBTree_Seach_Exactly(Tree_t *t, interval_t intr) {
415     Node_t *x = t->root;
416     
417     while (x != t->NIL) {
418         if (overlap(intr, x->intr)) {
419             if (intr == x->intr)
420                 break;
421             if (x->left!=t->NIL && intr.low<x->key)
422                 x = x->left;
423             else
424                 x = x->right;
425         } else {
426             if (x->left!=t->NIL && x->left->mmax>=intr.low)
427                 x = x->left;
428             else
429                 x = x->right;
430         }
431     }
432     return x;
433 }
434 
435 int check_BHeight(Tree_t *t, Node_t *x, bool &f) {
436     if (x == t->NIL)
437         return 1;
438     int lBH = check_BHeight(t, x->left, f);
439     int rBH = check_BHeight(t, x->right, f);
440     
441     if (f == false)
442         return 0;
443     
444     if (lBH != rBH)
445         f = false;
446     if (x->color == BLACK)
447         return lBH+1;
448     return lBH;
449 }
450 
451 bool check_RNode(Tree_t *t, Node_t *x) {
452     if (x == t->NIL)
453         return true;
454     if (x->color==RED && (x->left->color!=BLACK || x->right->color!=BLACK)) {
455         return false;
456     }
457     return check_RNode(t, x->left) && check_RNode(t, x->right);
458 }
459 
460 bool check_OthAttr(Tree_t *t, Node_t *x) {
461     if (x == t->NIL)
462         return x->mmax == -INF;
463     if (x->intr.high>x->mmax || x->left->mmax>x->mmax || x->right->mmax>x->mmax) {
464         return false;
465     }
466     return check_OthAttr(t, x->left) && check_OthAttr(t, x->right);
467 }
468 
469 bool check_RBTree(Tree_t *t) {
470     bool ret;
471     
472     if (t->NIL->color != BLACK) {
473         puts("NIL color is not black.");
474         return false;
475     }
476     
477     if (t->root == t->NIL)
478         return true;
479     
480     if (t->root->color != BLACK) {
481         puts("root color is not black.");
482         return false;
483     }
484     
485     if (check_RNode(t, t->root) == false) {
486         puts("color attr is not right.");
487         return false;
488     }
489     
490     ret = true;
491     check_BHeight(t, t->root, ret);
492     if (ret == false) {
493         puts("black height is not right.");
494         return false;
495     }
496     
497     if (check_OthAttr(t, t->root) == false) {
498         puts("mmax attr is not right.");
499         return false;
500     }
501     
502     return true;
503 }
504 
505 void init() {
506     int i, j, k;
507     Tree_t *t = new Tree_t();
508     interval_t intrs[10] = {
509         interval_t(16, 21),
510         interval_t(8 , 9 ),
511         interval_t(25, 30),
512         interval_t(5 , 8 ),
513         interval_t(15, 23),
514         interval_t(17, 19),
515         interval_t(26, 26),
516         interval_t(0 , 3 ),
517         interval_t(6 , 10),
518         interval_t(19, 20)
519     };
520     int n = sizeof(intrs) / sizeof(interval_t);
521     Node_t *p;
522     
523     printf("n = %d\n", n);
524     for (i=0; i<n; ++i) {
525         p = new Node_t(intrs[i]);
526         printf("key=%d, intr=[%d, %d]\n", p->key, p->intr.low, p->intr.high);
527         RBTree_Insert(t, p);
528     }
529     
530     printf("\n\nInorder the tree with color:\n");
531     Inorder_RBTree_Walk_WithColor(t, t->root);
532     if (check_RBTree(t))
533         puts("\nRight");
534     else
535         puts("\nWrong");
536     printf("\n");
537 }
538 
539 void check_delete() {
540     int i, j, k;
541     Tree_t *t = new Tree_t();
542     interval_t intrs[10] = {
543         interval_t(16, 21),
544         interval_t(8 , 9 ),
545         interval_t(25, 30),
546         interval_t(5 , 8 ),
547         interval_t(15, 23),
548         interval_t(17, 19),
549         interval_t(26, 26),
550         interval_t(0 , 3 ),
551         interval_t(6 , 10),
552         interval_t(19, 20)
553     };
554     Node_t *nds[10];
555     bool visit[10];
556     int n = sizeof(intrs) / sizeof(interval_t);
557     Node_t *p;
558     
559     printf("n = %d\n", n);
560     for (i=0; i<n; ++i) {
561         p = new Node_t(intrs[i]);
562         nds[i] = p;
563         RBTree_Insert(t, p);
564     }
565     
566     memset(visit, false, sizeof(visit));
567     for (i=0; i<n; ++i) {
568         while (1) {
569             j = rand()%n;
570             if (!visit[j])
571                 break;
572         }
573         visit[j] = true;
574         RBTree_Delete(t, nds[j]);
575         if (check_RBTree(t))
576             puts("Right");
577         else
578             puts("Wrong");
579     }
580 }
581 
582 void check_Search() {
583     int i, j, k;
584     Tree_t *t = new Tree_t();
585     interval_t intrs[10] = {
586         interval_t(16, 21),
587         interval_t(8 , 9 ),
588         interval_t(25, 30),
589         interval_t(5 , 8 ),
590         interval_t(15, 23),
591         interval_t(17, 19),
592         interval_t(26, 26),
593         interval_t(0 , 3 ),
594         interval_t(6 , 10),
595         interval_t(19, 20)
596     };
597     int n = sizeof(intrs) / sizeof(interval_t);
598     Node_t *p;
599     
600     printf("n = %d\n", n);
601     for (i=0; i<n; ++i) {
602         p = new Node_t(intrs[i]);
603         RBTree_Insert(t, p);
604     }
605     
606     interval_t tmp = interval_t(15, 28);
607     // // test 14.3-3
608     // p = RBTree_Search_Min(t, t->root, tmp);
609     // if (p == t->NIL) {
610         // puts("no overlap interval");
611     // } else {
612         // printf("[%d, %d]\n", p->intr.low, p->intr.high);
613     // }
614     
615     // // test 14.3-4
616     // RBTree_Search_All(t, t->root, tmp);
617     // test 14.3-5
618     printf("\n\nInorder the tree with color:\n");
619     Inorder_RBTree_Walk_WithColor(t, t->root);
620     printf("\n\nsearch exactly [%d, %d]\n", tmp.low, tmp.high);
621     p = RBTree_Seach_Exactly(t, tmp);
622     if (p == t->NIL)
623         puts("not found such exactly intr");
624     else
625         puts("found a exactly intr");
626     tmp = interval_t(17, 19);
627     printf("\n\nsearch exactly [%d, %d]\n", tmp.low, tmp.high);
628     p = RBTree_Seach_Exactly(t, tmp);
629     if (p == t->NIL)
630         puts("not found such exactly intr");
631     else
632         puts("found a exactly intr");
633 }
634 
635 int main() {
636     
637     #ifdef LOCAL_DEBUG
638         freopen("data.in", "r", stdin);
639         freopen("data.out", "w", stdout);
640     #endif
641     
642     // init();
643     // check_delete();
644     check_Search();
645     
646     return 0;
647 }
View Code

14.3-1
见区间树源代码。

14.3-2

 1     bool overlap(interval_t a, interval_t b) {
 2         return b.low<a.high && a.low<b.high;    // <= -> <
 3     }
 4     
 5     Node_t *RBTree_Search(Tree_t *t, interval_t intr) {
 6         Node_t *x = t->root;
 7         while (x!=t->NIL && !overlap(intr, x->intr)) {
 8             if (x->left!=t->NIL && x->left->mmax>intr.low) {    // >= -> >
 9                 x = x->left;
10             } else {
11                 x = x->right;
12             }
13         }
14         return x;
15     }


14.3-3
见区间树源代码RBTree_Search_Min。

14.3-4
见区间树源代码RBTree_Search_All。

14.3-5
见区间树源代码RBTree_Search_Exactly。

14.3-6
在原始红黑树的基础上增加mmax,mmin属性(最大值,最小值)。源代码如下:

  1 #include <iostream>
  2 #include <cstdio>
  3 #include <cstring>
  4 #include <cstdlib>
  5 #include <algorithm>
  6 using namespace std;
  7 
  8 #define LOCAL_DEBUG
  9 #define RED        true
 10 #define BLACK    false
 11 #define INF        9999999
 12 
 13 typedef struct Node_t {
 14     bool color;
 15     int key, mmax, mmin;
 16     Node_t *p, *left, *right;
 17     Node_t() {}
 18     Node_t(int kkey) {
 19         key = kkey;
 20     }
 21 } Node_t;
 22 
 23 typedef struct Tree_t {
 24     Node_t *NIL;
 25     Node_t *root;
 26     Tree_t() {
 27         NIL = new Node_t();
 28         NIL->key = 0;
 29         NIL->mmax = -INF;
 30         NIL->mmin = INF;
 31         NIL->color = BLACK;
 32         NIL->p = NIL->left = NIL->right = NIL;
 33         root = NIL;
 34     }
 35 } Tree_t;
 36 
 37 Tree_t *t;
 38 
 39 void Inorder_RBTree_Walk(Tree_t *t, Node_t *x) {
 40     if (x != t->NIL) {
 41         Inorder_RBTree_Walk(t, x->left);
 42         printf("key=%d, mmin=%d, mmax=%d\n", x->key, x->mmin, x->mmax);
 43         Inorder_RBTree_Walk(t, x->right);
 44     }
 45 }
 46 
 47 void Preorder_RBTree_Walk(Tree_t *t, Node_t *x) {
 48     if (x != t->NIL) {
 49         printf("key=%d, mmin=%d, mmax=%d\n", x->key, x->mmin, x->mmax);
 50         Preorder_RBTree_Walk(t, x->left);
 51         Preorder_RBTree_Walk(t, x->right);
 52     }
 53 }
 54 
 55 void Postorder_RBTree_Walk(Tree_t *t, Node_t *x) {
 56     if (x != t->NIL) {
 57         Postorder_RBTree_Walk(t, x->left);
 58         Postorder_RBTree_Walk(t, x->right);
 59         printf("key=%d, mmin=%d, mmax=%d\n", x->key, x->mmin, x->mmax);
 60     }
 61 }
 62 
 63 void Inorder_RBTree_Walk_WithColor(Tree_t *t, Node_t *x) {
 64     if (x != t->NIL) {
 65         Inorder_RBTree_Walk_WithColor(t, x->left);
 66         printf("%s: key=%d, mmin=%d, mmax=%d\n", x->color?"Red":"Black", x->key, x->mmin, x->mmax);
 67         Inorder_RBTree_Walk_WithColor(t, x->right);
 68     }
 69 }
 70 
 71 void Preorder_RBTree_Walk_WithColor(Tree_t *t, Node_t *x) {
 72     if (x != t->NIL) {
 73         printf("%s: key=%d, mmin=%d, mmax=%d\n", x->color?"Red":"Black", x->key, x->mmin, x->mmax);
 74         Preorder_RBTree_Walk_WithColor(t, x->left);
 75         Preorder_RBTree_Walk_WithColor(t, x->right);
 76     }
 77 }
 78 
 79 void Postorder_RBTree_Walk_WithColor(Tree_t *t, Node_t *x) {
 80     if (x != t->NIL) {
 81         Postorder_RBTree_Walk_WithColor(t, x->left);
 82         Postorder_RBTree_Walk_WithColor(t, x->right);
 83         printf("%s: key=%d, mmin=%d, mmax=%d\n", x->color?"Red":"Black", x->key, x->mmin, x->mmax);
 84     }
 85 }
 86 
 87 Node_t *RBTree_Minimum(Tree_t *t, Node_t *x) {
 88     while (x->left != t->NIL)
 89         x = x->left;
 90     return x;
 91 }
 92 
 93 Node_t *RBTree_Maximum(Tree_t *t, Node_t *x) {
 94     while (x->right != t->NIL)
 95         x = x->right;
 96     return x;
 97 }
 98 
 99 Node_t *RBTree_Search(Tree_t *t, int key) {
100     Node_t *x = t->root;
101     while (x!=t->NIL && x->key!=key) {
102         if (key < x->key) {
103             x = x->left;
104         } else {
105             x = x->right;
106         }
107     }
108     return x;
109 }
110 
111 void Left_Rotate(Tree_t *t, Node_t *x) {
112     Node_t *y = x->right;
113     x->right = y->left;
114     if (y->left != t->NIL)
115         y->left->p = x;
116     y->p = x->p;
117     if (x->p == t->NIL) {
118         // x is root
119         t->root = y;    
120     } else if (x == x->p->left) {
121         x->p->left = y;
122     } else {
123         x->p->right = y;
124     }
125     y->left = x;
126     x->p = y;
127     // maintenance attr mmax & mmin
128     y->mmin = x->mmin;
129     x->mmax = max(x->key, x->right->mmax);
130 }
131 
132 void Right_Rotate(Tree_t *t, Node_t *y) {
133     Node_t *x = y->left;
134     y->left = x->right;
135     if (x->right != t->NIL)
136         x->right->p = y;
137     x->p = y->p;
138     if (y->p == t->NIL) {
139         // y is root
140         t->root = x;
141     } else if (y == y->p->left) {
142         y->p->left = x;
143     } else {
144         y->p->right = x;
145     }
146     x->right = y;
147     y->p = x;
148     // maintenance attr mmax & mmin
149     x->mmax = y->mmax;
150     y->mmin = min(y->key, y->left->mmin);
151 }
152 
153 void RBTree_Transplant(Tree_t *t, Node_t *u, Node_t *v) {
154     if (u->p == t->NIL) {
155         t->root = v;
156     } else if (u == u->p->left) {
157         u->p->left = v;
158     } else {
159         u->p->right = v;
160     }
161     v->p = u->p;
162 }
163 
164 void RBTree_Insert_Fixup(Tree_t *t, Node_t *z) {
165     Node_t *y;
166     
167     while (z->p->color == RED) {
168         // means z->p->p->color == BLACK
169         if (z->p == z->p->p->left) {
170             y = z->p->p->right;
171             if (y->color == RED) {
172                 z->p->color = BLACK;
173                 y->color = BLACK;
174                 z->p->p->color = RED;
175                 z = z->p->p;
176             } else {
177                 // y->color is BLACK
178                 if (z == z->p->right) {
179                     z = z->p;
180                     Left_Rotate(t, z);
181                 }
182                 z->p->color = BLACK;    // break later
183                 z->p->p->color = RED;
184                 Right_Rotate(t, z->p->p);
185             }
186         } else {
187             y = z->p->p->left;
188             if (y->color == RED) {
189                 z->p->color = BLACK;
190                 y->color = BLACK;
191                 z->p->p->color = RED;
192                 z = z->p->p;
193             } else {
194                 // y->color is BLACK
195                 if (z == z->p->left) {
196                     z = z->p;
197                     Right_Rotate(t, z);
198                 }
199                 z->p->color = BLACK;    // break later
200                 z->p->p->color = RED;
201                 Left_Rotate(t, z->p->p);
202             }
203         }
204     }
205     t->root->color = BLACK;
206 }
207 
208 void RBTree_Insert(Tree_t *t, Node_t *z) {
209     Node_t *y = t->NIL;
210     Node_t *x = t->root;
211     Node_t *q;
212     
213     while (x != t->NIL) {
214         y = x;
215         if (z->key < x->key) {
216             x = x->left;
217         } else {
218             x = x->right;
219         }
220     }
221     z->p = y;
222     if (y == t->NIL) {
223         // tree is empty
224         t->root = z;
225     } else if (z->key < y->key) {
226         y->left = z;
227     } else {
228         y->right = z;
229     }
230     z->left = z->right = t->NIL;
231     z->color = RED;
232     // maintence the [mmax] of tree
233     q = z;
234     while (q != t->NIL) {
235         q->mmax = max(q->right->mmax, q->key);
236         q->mmin = min(q->left->mmin, q->key);
237         q = q->p;
238     }
239     RBTree_Insert_Fixup(t, z);
240 }
241 
242 void RBTree_Delete_Fixup(Tree_t *t, Node_t *x) {
243     Node_t *w;
244     
245     while (x!=t->root && x->color==BLACK) {
246         if (x == x->p->left) {
247             w = x->p->right;
248             if (w->color == RED) {
249                 w->color = BLACK;
250                 x->p->color = RED;
251                 Left_Rotate(t, x->p);
252                 w = x->p->right;
253             }
254             // means w->color == BLACK
255             if (w->left->color==BLACK && w->right->color==BLACK) {
256                 w->color = RED;
257                 x = x->p;    // fetch the black in w & x and pass it to x->p
258             } else {
259                 if (w->right->color == BLACK) {
260                     // means w->left->color == RED
261                     w->left->color = BLACK;
262                     w->color = RED;
263                     Right_Rotate(t, w);
264                     w = x->p->right;
265                 }
266                 // means w->right->color == RED && w->left->color == uncertain
267                 w->color = x->p->color;
268                 x->p->color = BLACK;
269                 w->right->color = BLACK;
270                 Left_Rotate(t, x->p);
271                 x = t->root;
272             }
273         } else {
274             w = x->p->left;
275             if (w->color == RED) {
276                 w->color = BLACK;
277                 x->p->color = RED;
278                 Right_Rotate(t, x->p);
279                 w = x->p->left;
280             }
281             // means w->color == BLACK
282             if (w->left->color==BLACK && w->right->color==BLACK) {
283                 w->color = RED;
284                 x = x->p; // fetch the black in w & x and pass it to x->p
285             } else {
286                 if (w->left->color == BLACK) {
287                     // means x->right->color == RED
288                     w->right->color = BLACK;
289                     w->color = RED;
290                     Left_Rotate(t, w);
291                     w = x->p->left;
292                 }
293                 // means w->left->color == RED && w->right->color = ANY
294                 w->color = x->p->color;
295                 x->p->color = BLACK;
296                 w->left->color = BLACK;
297                 Right_Rotate(t, x->p);
298                 x = t->root;
299             }
300         }
301     }
302     x->color = BLACK;
303 }
304 
305 void RBTree_Delete(Tree_t *t, Node_t *z) {
306     Node_t *x, *y = z;
307     Node_t *q;    // q used to back trace for maintening the [mmax] of Node_t
308     bool y_original_color = y->color;
309     
310     if (z->left == t->NIL) {
311         x = z->right;
312         q = y->p;
313         RBTree_Transplant(t, y, x);
314     } else if (z->right == t->NIL) {
315         x = z->left;
316         RBTree_Transplant(t, y, x);
317         q = y->p;
318     } else {
319         y = RBTree_Minimum(t, z->right);
320         y_original_color = y->color;
321         x = y->right;
322         if (y->p == z) {
323             x->p = y;
324             q = y;
325         } else {
326             RBTree_Transplant(t, y, x);
327             q = y->p;
328             y->right = z->right;
329             y->right->p = y;
330         }
331         RBTree_Transplant(t, z, y);
332         y->left = z->left;
333         y->left->p = y;
334         y->color = z->color;
335     }
336     
337     // maintence the [size] of Node_t
338     while (q != t->NIL) {
339         q->mmax = max(q->right->mmax, q->key);
340         q->mmin = min(q->left->mmin, q->key);
341         q = q->p;
342     }
343     
344     if (y_original_color == BLACK)
345         RBTree_Delete_Fixup(t, x);    // use x replace y
346 }
347 
348 int Min_Gap(Tree_t *t, Node_t *x) {
349     if (x == t->NIL)
350         return INF;
351     int lgap = Min_Gap(t, x->left);
352     int rgap = Min_Gap(t, x->right);
353     int gap;
354     if (x->right->mmin == INF)
355         gap = x->key - x->left->mmax;
356     else
357         gap = min(
358             x->key - x->left->mmax, x->right->mmin - x->key
359         );
360     int ret = min(
361         min(lgap, rgap), gap
362     );
363     
364     return ret;
365 }
366 
367 int check_BHeight(Tree_t *t, Node_t *x, bool &f) {
368     if (x == t->NIL)
369         return 1;
370     int lBH = check_BHeight(t, x->left, f);
371     int rBH = check_BHeight(t, x->right, f);
372     
373     if (f == false)
374         return 0;
375     
376     if (lBH != rBH)
377         f = false;
378     if (x->color == BLACK)
379         return lBH+1;
380     return lBH;
381 }
382 
383 bool check_RNode(Tree_t *t, Node_t *x) {
384     if (x == t->NIL)
385         return true;
386     if (x->color==RED && (x->left->color!=BLACK || x->right->color!=BLACK)) {
387         return false;
388     }
389     return check_RNode(t, x->left) && check_RNode(t, x->right);
390 }
391 
392 bool check_OthAttr(Tree_t *t, Node_t *x) {
393     if (x == t->NIL)
394         return x->mmax==-INF && x->mmin==INF;
395     Node_t *p = RBTree_Minimum(t, x);
396     Node_t *q = RBTree_Maximum(t, x);
397     
398     return p->key==x->mmin && q->key==x->mmax && check_OthAttr(t, x->left) && check_OthAttr(t, x->right);
399 }
400 
401 bool check_RBTree(Tree_t *t) {
402     bool ret;
403     
404     if (t->NIL->color != BLACK) {
405         puts("NIL color is not black.");
406         return false;
407     }
408     
409     if (t->root == t->NIL)
410         return true;
411     
412     if (t->root->color != BLACK) {
413         puts("root color is not black.");
414         return false;
415     }
416     
417     if (check_RNode(t, t->root) == false) {
418         puts("color attr is not right.");
419         return false;
420     }
421     
422     ret = true;
423     check_BHeight(t, t->root, ret);
424     if (ret == false) {
425         puts("black height is not right.");
426         return false;
427     }
428     
429     if (check_OthAttr(t, t->root) == false) {
430         puts("mmax/mmin attr is not right.");
431         return false;
432     }
433     
434     return true;
435 }
436 
437 void init() {
438     int i, j, k, tmp;
439     int gap;
440     Tree_t *t = new Tree_t();
441     int a[] = {26, 17, 41, 14, 21, 30, 47, 10, 16, 19, 23, 28, 38, 7, 12, 15, 20, 35, 39, 3};
442     int n = sizeof(a) / sizeof(int);
443     Node_t *p;
444     
445     printf("n = %d\n", n);
446     for (i=0; i<n; ++i) {
447         p = new Node_t(a[i]);
448         RBTree_Insert(t, p);
449     }
450     
451     printf("\n\nInorder the tree with color:\n");
452     Inorder_RBTree_Walk_WithColor(t, t->root);
453     if (check_RBTree(t))
454         puts("\nRight");
455     else
456         puts("\nWrong");
457     printf("\n");
458     
459     gap = Min_Gap(t, t->root);
460     sort(a, a+n);
461     k = INF;
462     for (i=1; i<n; ++i) {
463         tmp = a[i] - a[i-1];
464         k = min(tmp, k);
465     }
466     printf("gap = %d, Min_gap = %d\n", k, gap);
467 }
468 
469 int cal_Gap(int *a, bool *visit, int n) {
470     int b[30], m = 0;
471     int i, j, k;
472     
473     for (i=0; i<n; ++i)
474         if (!visit[i])
475             b[m++] = a[i];
476     
477     sort(b, b+m);
478     k = INF;
479     for (i=1; i<m; ++i) {
480         j = b[i] - b[i-1];
481         k = min(j, k);
482     }
483     return k;
484 }
485 
486 void check_delete() {
487     int i, j, k, tmp;
488     int gap;
489     Tree_t *t = new Tree_t();
490     int a[] = {26, 17, 41, 14, 21, 30, 47, 10, 16, 19, 23, 28, 38, 7, 12, 15, 20, 35, 39, 3};
491     int n = sizeof(a) / sizeof(int);
492     bool visit[30];
493     Node_t *p;
494     
495     printf("n = %d\n", n);
496     for (i=0; i<n; ++i) {
497         p = new Node_t(a[i]);
498         RBTree_Insert(t, p);
499     }
500     
501     // Inorder_RBTree_Walk_WithColor(t, t->root);
502     // puts("");
503     
504     memset(visit, false, sizeof(visit));
505     for (i=1; i<n; ++i) {
506         while (1) {
507             j = rand()%n;
508             if (!visit[j])
509                 break;
510         }
511         visit[j] = true;
512         p = RBTree_Search(t, a[j]);    
513         RBTree_Delete(t, p);
514         // Inorder_RBTree_Walk_WithColor(t, t->root);
515         if (check_RBTree(t))
516             puts("Right");
517         else
518             puts("Wrong");
519         gap = Min_Gap(t, t->root);
520         k = cal_Gap(a, visit, n);
521         printf("delete = %d, gap = %d, Min_gap = %d\n\n", a[j], k, gap);
522     }
523 }
524 
525 int main() {
526     
527     #ifdef LOCAL_DEBUG
528         freopen("data.in", "r", stdin);
529         freopen("data.out", "w", stdout);
530     #endif
531     
532     // init();
533     check_delete();
534     
535     return 0;
536 }
View Code



posted on 2015-03-03 16:33  Bombe  阅读(506)  评论(0编辑  收藏  举报

导航