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