《算法导论》笔记 第13章 13.4 删除

来源:互联网 发布:it监控软件 编辑:程序博客网 时间:2024/06/16 11:45

【笔记】

// 基本没搞懂


    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之后,树根总是黑色的。

循环的退出条件有两个,x为根或x非黑。

当x为根结点时,由case 4可知,x必为黑色。

当x非黑时,循环结束后x会被染成黑色。红黑树的性质得到保持。

因此树根总是黑色的。


13.4-2 证明:在RB-DELETE中,如果x和p[x]都是红色的,则性质4)可以通过调用RB-DELETE-FIXUP(T,x)来恢复。

调用fixup后,x直接被染成黑色并退出。

由RB-DELETE可知,p[x]只有x一个子结点,并且所有经过x的路径都缺少了一个黑结点,将x染为黑色即可保持性质4)。


13.4-3 在练习13.3-2中,我们将关键字41,38,31,12,19,8连续插入一棵初始为空的树中,从而得到一棵红黑树。请给出从该树中连续删除关键字8,12,19,31,38,41后的结果。



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将它从树中删除。结果的红黑树与之前的红黑树是否相同?

不相同,找的图:




0 0
原创粉丝点击