【算法导论】学习笔记——第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 }

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 }

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 }

时间: 2024-08-03 09:49:44

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

算法导论学习笔记——第10章 基本数据结构

栈 1 Stack-EMPTY(S) 2 if top[S]=0 3 then return TRUE 4 else return FALSE 5 6 PUSH(S,x) 7 top[S]←top[S]+1 8 S[top[S]]←x 9 10 POP(S) 11 if STACK-EMPTY(S) 12 then error "underflow" 13 else top[S]←top[S]-1 14 return S[top[S]+1] 队列 1 ENQUEUE(Q,x) 2 Q[

算法导论学习笔记——第12章 二叉查找树

二叉查找树性质 设x是二叉查找树中的一个结点,如果y是x的左子树中的一个结点,则k[y]<=key[x]:如果y是右子树中的一个结点,则k[y]>=k[x] 1 //中序遍历算法,输出二叉查找树T中的全部元素 2 INORDER-TREE-WALK(x) 3 if x!=nil 4 then INORDER-TREE-WALK(left[x]) 5 print key[x] 6 INORDER-TREE-WALK(right[x]) 查找 1 //递归版本 2 TREE-SEARCH(x,k)

算法导论学习笔记——第6章

堆 堆数据结构是一种数组对象,可以被视为一棵完全二叉树. 对于给定的数组A,树的根为A[1],对于给定的下标为i的结点A[i],其父结点PARENT(i)=floor(i/2),左子结点LEFT(i)=2i,右子结点RIGHT(i)=2i+1 叶级结点的高度可以认为是0,每向上一层,高度加一,定义树的告诉为根结点的高度. P74

算法导论学习笔记——第1章

所谓算法,就是定义良好的计算过程,它取一个或一组值作为输入,并产生出一个或一组值作为输出.亦即,算法是一系列的计算过程,将输入值转换成输出值. 一些常见的算法运行时间量级比较:对数级<多项式级<指数级<阶乘级 1 lgn < n 1/2 < n < nlgn < n 2 < n 3 < 2 n < n!

算法导论学习笔记——第8章 线性时间排序

任意一种比较排序算法,在最坏情况下的运行时间下限是Ω(nlgn) 计数排序 假设n个输入元素中的每一个都是介于0到k之间的整数,k为某个整数,当k=O(n)时,计数排序的运行时间为Θ(n) 1 //输入数组A[1..n],存放排序结果数组B[1..n],临时存储区C[0..k] 2 COUNTING-SORT(A,B,k) 3 for i←0 to k 4 do C[i]←0 5 for j←1 to length[A] 6 do C[A[j]]←C[A[j]]+1 7 for i←1 to k

算法导论学习笔记——第13章 红黑树

红黑树 红黑树是一种二叉查找树,但在每个结点上增加一个存储位存储结点的颜色,可以是red或black.通过对任意一条从根到叶的路径上结点颜色的限制,红黑树确保没有任何一条路径比其他路径长出两倍,因而是接近平衡的. 每个结点包含5个域,color,key,left,right,p 满足以下红黑性质: 1.每个结点是红色或黑色 2.根结点是黑色 3.每个叶结点(nil)是黑色 4.如果一个结点是红色,那么它的两个子结点都是黑色 5.对每个结点,从该结点到它每个子孙结点的路径上,黑结点数目相同 左旋转

算法导论学习笔记——第7章 快速排序

快速排序 1 QUICKSORT(A,p,r) 2 if p<r 3 then q←PARTITION(A,p,r) 4 QUICKSORT(A,p,q-1) 5 QUICKSORT(A,q+1,r) 6 7 PARTITION(A,p,r) 8 x←A[r] 9 i←p-1 10 for j←p to r-1 11 do if A[j]<=x 12 then i←i+1 13 exchange A[i]↔A[j] 14 exchange A[i+1]↔A[r] 15 return i+1 随

算法导论学习笔记 第7章 快速排序

对于包含n个数的输入数组来说,快速排序是一种时间复杂度为O(n^2)的排序算法.虽然最环情况的复杂度高,但是快速排序通常是实际应用排序中最好的选择,因为快排的平均性能非常好:它的期望复杂度是O(nlgn),而且O(nlgn)中的常数因子非常小.另外,快速排序还可以实现原址排序,甚至在虚拟环境中也能很好的工作. 1 快速排序的描述 与归并排序一样,快速排序也使用了分治法的思想,下面是对一个典型的子数组A[p.. r]进行快速排序的分治过长: 分解:数组A[p.. r]被划分为两个(可能为空)子数组

算法导论学习笔记——第11章 散列表

直接寻址表 1 DIRECT-ADDRESS-SEARCH(T,k) 2 return T[k] 3 4 DIRECT-ADDRESS-INSERT(T,x) 5 T[key[x]]←x 6 7 DIRECT-ADDRESS-DELETE(T,x) 8 T[key[x]]←nil