【笔记】
// 基本没搞懂
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将它从树中删除。结果的红黑树与之前的红黑树是否相同?
不相同,找的图: