zoukankan      html  css  js  c++  java
  • 【算法导论】学习笔记——第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
    ", 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
    ", 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
    ", 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
    ", 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
    ", 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
    ", 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, --
    ", 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!!!
    ", x->key, x->size);
    370         printf("x->left: key=%d, size=%d
    ", x->left->key, x->left->size);
    371         printf("x->right: key=%d, size=%d
    ", 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);
    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("
    ");
    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);
    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
    ", 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("
    
    
    ");
    483     }
    484 }
    485 
    486 int main() {
    487     
    488     #ifdef LOCAL_DEBUG
    489         freopen("data.in", "r", stdin);
    490         freopen("data.out", "w", stdout);
    491     #endif
    492     
    493     //init();
    494     test_delete();
    495     
    496     return 0;
    497 }
    View Code

    14.1-5


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

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


    14.1-7


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

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

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

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

      1 #include <iostream>
      2 #include <cstdio>
      3 #include <cstring>
      4 #include <cstdlib>
      5 #include <algorithm>
      6 using namespace std;
      7 
      8 #define LOCAL_DEBUG
      9 #define RED        true
     10 #define BLACK    false
     11 #define INF        9999999
     12 
     13 typedef struct interval_t {
     14     int low, high;
     15     interval_t() {}
     16     interval_t(int l, int h) {
     17         low = l; high = h;
     18     }
     19     friend bool operator ==(const interval_t &a, const interval_t &b) {
     20         return a.low==b.low && a.high==b.high;
     21     }
     22 } interval_t;
     23 
     24 typedef struct Node_t {
     25     bool color;
     26     int key, mmax;
     27     interval_t intr;
     28     Node_t *p, *left, *right;
     29     Node_t() {}
     30     Node_t(interval_t iintr) {
     31         intr = iintr;
     32         key = iintr.low;
     33     }
     34 } Node_t;
     35 
     36 typedef struct Tree_t {
     37     Node_t *NIL;
     38     Node_t *root;
     39     Tree_t() {
     40         NIL = new Node_t();
     41         NIL->key = 0;
     42         NIL->mmax = -INF;
     43         NIL->color = BLACK;
     44         NIL->p = NIL->left = NIL->right = NIL;
     45         root = NIL;
     46     }
     47 } Tree_t;
     48 
     49 Tree_t *t;
     50 
     51 void Inorder_RBTree_Walk(Tree_t *t, Node_t *x) {
     52     if (x != t->NIL) {
     53         Inorder_RBTree_Walk(t, x->left);
     54         printf("[%d, %d] | %d
    ", 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
    ", 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
    ", 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
    ", 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
    ", 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
    ", 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]
    ", 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);
    524     for (i=0; i<n; ++i) {
    525         p = new Node_t(intrs[i]);
    526         printf("key=%d, intr=[%d, %d]
    ", p->key, p->intr.low, p->intr.high);
    527         RBTree_Insert(t, p);
    528     }
    529     
    530     printf("
    
    Inorder the tree with color:
    ");
    531     Inorder_RBTree_Walk_WithColor(t, t->root);
    532     if (check_RBTree(t))
    533         puts("
    Right");
    534     else
    535         puts("
    Wrong");
    536     printf("
    ");
    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);
    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);
    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]
    ", 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("
    
    Inorder the tree with color:
    ");
    619     Inorder_RBTree_Walk_WithColor(t, t->root);
    620     printf("
    
    search exactly [%d, %d]
    ", 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("
    
    search exactly [%d, %d]
    ", tmp.low, tmp.high);
    628     p = RBTree_Seach_Exactly(t, tmp);
    629     if (p == t->NIL)
    630         puts("not found such exactly intr");
    631     else
    632         puts("found a exactly intr");
    633 }
    634 
    635 int main() {
    636     
    637     #ifdef LOCAL_DEBUG
    638         freopen("data.in", "r", stdin);
    639         freopen("data.out", "w", stdout);
    640     #endif
    641     
    642     // init();
    643     // check_delete();
    644     check_Search();
    645     
    646     return 0;
    647 }
    View Code

    14.3-1
    见区间树源代码。

    14.3-2

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


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

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

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

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

      1 #include <iostream>
      2 #include <cstdio>
      3 #include <cstring>
      4 #include <cstdlib>
      5 #include <algorithm>
      6 using namespace std;
      7 
      8 #define LOCAL_DEBUG
      9 #define RED        true
     10 #define BLACK    false
     11 #define INF        9999999
     12 
     13 typedef struct Node_t {
     14     bool color;
     15     int key, mmax, mmin;
     16     Node_t *p, *left, *right;
     17     Node_t() {}
     18     Node_t(int kkey) {
     19         key = kkey;
     20     }
     21 } Node_t;
     22 
     23 typedef struct Tree_t {
     24     Node_t *NIL;
     25     Node_t *root;
     26     Tree_t() {
     27         NIL = new Node_t();
     28         NIL->key = 0;
     29         NIL->mmax = -INF;
     30         NIL->mmin = INF;
     31         NIL->color = BLACK;
     32         NIL->p = NIL->left = NIL->right = NIL;
     33         root = NIL;
     34     }
     35 } Tree_t;
     36 
     37 Tree_t *t;
     38 
     39 void Inorder_RBTree_Walk(Tree_t *t, Node_t *x) {
     40     if (x != t->NIL) {
     41         Inorder_RBTree_Walk(t, x->left);
     42         printf("key=%d, mmin=%d, mmax=%d
    ", 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
    ", 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
    ", 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
    ", 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
    ", 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
    ", 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);
    446     for (i=0; i<n; ++i) {
    447         p = new Node_t(a[i]);
    448         RBTree_Insert(t, p);
    449     }
    450     
    451     printf("
    
    Inorder the tree with color:
    ");
    452     Inorder_RBTree_Walk_WithColor(t, t->root);
    453     if (check_RBTree(t))
    454         puts("
    Right");
    455     else
    456         puts("
    Wrong");
    457     printf("
    ");
    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
    ", 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);
    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
    
    ", a[j], k, gap);
    522     }
    523 }
    524 
    525 int main() {
    526     
    527     #ifdef LOCAL_DEBUG
    528         freopen("data.in", "r", stdin);
    529         freopen("data.out", "w", stdout);
    530     #endif
    531     
    532     // init();
    533     check_delete();
    534     
    535     return 0;
    536 }
    View Code



  • 相关阅读:
    JS练习:定时器--背景颜色交替变换
    JS练习:切换图片
    BOM对象和DOM对象
    CSS练习:仿小米官网
    classification
    where does the error come from
    梯度下降
    torch 中各种图像格式转化
    regression
    torch 的包应用
  • 原文地址:https://www.cnblogs.com/bombe1013/p/4311300.html
Copyright © 2011-2022 走看看