《算法導論》筆記 第13章 13.4 刪除

【筆記】

// 基本沒搞懂code


    NODE* rbDelete(NODE *z) {
        NODE *y, *x;
        if (z->l == nil || z->r == nil) { y = z; }
        else { y = treeSuccessor(z); }
        if (y->l != nil) { x = y->l; }
        else { x = y->r; }
        x->p = y->p;
        if (y->p == nil) { root = x; }
        else {
            if (y == y->p->l) { y->p->l = x; }
            else { y->p->r = x; }
        }
        if (y != z) {
            z->key = y->key;
            // copy y's satellite data into z
        }
        if (y->c == BLACK) { rbDeleteFixup(x); }
        return y;
    }
    void rbDeleteFixup(NODE *x) {
        NODE *w;
        while (x != root && x->c == BLACK) {
            if (x == x->p->l) {// x 爲左兒子
                w = x->p->r;// w 是 x 的兄弟
                if (w->c == RED) {// case 1:w 爲紅色,必有黑色兒子
                    w->c = BLACK;
                    x->p->c = RED;
                    leftRotate(x->p);
                    w = x->p->r;// x 的新兄弟必爲黑色
                }
                if (w->l->c == BLACK && w->r->c == BLACK) {// case 2:x 的兄弟 w 是黑色的,w 的兩個兒子都是黑色
                    w->c = RED;// 去掉一重黑色
                    x = x->p;// 以 x 父親重複 while 循環
                }
                else {
                    if (w->r->c == BLACK) {// case 3:x 的兄弟 w 是黑色的,w 的左兒子是紅色的,右兒子是黑色
                        w->l->c = BLACK;// 交換 w 與左兒子的顏色
                        w->c = RED;
                        rightRotate(w);// w 右旋
                        w = x->p->r;// 新兄弟是一個有紅色右孩子的黑結點
                    }
                    w->c = x->p->c;// case 4:x 的兄弟 w 是黑色的,並且 w 的右兒子是紅色的
                    x->p->c = BLACK;
                    w->r->c = BLACK;
                    leftRotate(x->p);
                    x = root;
                }
            }
            else if (x == x->p->r) {// x 爲右兒子
                w = x->p->l;// w 是 x 的兄弟
                if (w->c == RED) {// case 1:w 爲紅色,必有黑色兒子
                    w->c = BLACK;
                    x->p->c = RED;
                    rightRotate(x->p);
                    w = x->p->l;// x 的新兄弟必爲黑色
                }
                if (w->l->c == BLACK && w->r->c == BLACK) {// case 2:x 的兄弟 w 是黑色的,w 的兩個兒子都是黑色
                    w->c = RED;// 去掉一重黑色
                    x = x->p;// 以 x 父親重複 while 循環
                }
                else {
                    if (w->l->c == BLACK) {// case 3:x 的兄弟 w 是黑色的,w 的右兒子是紅色的,左兒子是黑色
                        w->r->c = BLACK;// 交換 w 與右兒子的顏色
                        w->c = RED;
                        leftRotate(w);// w 左旋
                        w = x->p->l;// 新兄弟是一個有紅色左孩子的黑結點
                    }
                    w->c = x->p->c;// case 4:x 的兄弟 w 是黑色的,並且 w 的左兒子是紅色的
                    x->p->c = BLACK;
                    w->l->c = BLACK;
                    rightRotate(x->p);
                    x = root;
                }
            }
        }
        x->c = BLACK;
    }


【練習】

13.4-1 證實:在執行RB-DELETE-FIXUP以後,樹根老是黑色的。blog

循環的退出條件有兩個,x爲根或x非黑。ip

當x爲根結點時,由case 4可知,x必爲黑色。it

當x非黑時,循環結束後x會被染成黑色。紅黑樹的性質獲得保持。class

所以樹根老是黑色的。file


13.4-2 證實:在RB-DELETE中,若是x和p[x]都是紅色的,則性質4)能夠經過調用RB-DELETE-FIXUP(T,x)來恢復。循環

調用fixup後,x直接被染成黑色並退出。sso

由RB-DELETE可知,p[x]只有x一個子結點,而且全部通過x的路徑都缺乏了一個黑結點,將x染爲黑色便可保持性質4)。im


13.4-3 在練習13.3-2中,咱們將關鍵字41,38,31,12,19,8連續插入一棵初始爲空的樹中,從而獲得一棵紅黑樹。請給出從該樹中連續刪除關鍵字8,12,19,31,38,41後的結果。img



13.4-4 在RB-DELETE-FIXUP的哪些行中,可能會檢查或修改哨兵nil。


13.4-5 在每種狀況中,給出所示子樹的根至每一個子樹α,β,…,ξ之間的黑結點個數,並驗證它們在轉換以後保持不變。當一個結點的color屬性爲c或c'時,在計數中可用記號count(c)或count(c')來表示。


13.4-6 證實p[x]在case 1的開頭必是黑色的。

若p[x]爲紅色,則x的兄弟必爲黑色,不知足case 1的條件。所以p[x]在case 1開頭必爲黑色。


13.4-7 假設用RB-INSERT來將一個結點x插入一棵紅黑樹,緊接着又用RB-DELETE-FIXUP將它從樹中刪除。結果的紅黑樹與以前的紅黑樹是否相同?

不相同,找的圖:

相關文章
相關標籤/搜索