《算法导论》笔记 第13章 13.3 插入

来源:互联网 发布:ps如何做淘宝详情页 编辑:程序博客网 时间:2024/05/29 04:03

【笔记】


    void rbInsert(NODE *z) {        NODE *y = nil;        NODE *x = root;        while (x != nil) {            y = x;            if (z->key < x->key) { x = x->l; }            else { x = x->r; }        }        z->p = y;        if (y == nil) { root = z; }        else {            if (z->key < y->key) { y->l = z; }            else { y->r = z; }        }        z->l = nil;        z->r = nil;        z->c = RED;        rbInsertFixup(z);    }    void rbInsertFixup(NODE *z) {        NODE *y;        while (z->p->c == RED) {            if (z->p == z->p->p->l) {// z 的父亲是爷爷的左儿子                y = z->p->p->r;// z 的叔叔 y                if (y->c == RED) {// case 1:叔叔是红的                    z->p->c = BLACK;// 将 z 的父亲与叔叔置为黑                    y->c = BLACK;                    z->p->p->c = RED;// 将 z 的爷爷置为红                    z = z->p->p;// 问题上移两层                }                else {                    if (z == z->p->r) {// case 2:z 是右儿子                        z = z->p;                        leftRotate(z);// 左旋,转为 case 3                    }                    z->p->c = BLACK;// case 3:z 是左儿子,对z的爷爷做一次右旋即可完成维护                    z->p->p->c = RED;                    rightRotate(z->p->p);                }            }            else if (z->p == z->p->p->r) {// z 的父亲是爷爷的右儿子                y = z->p->p->l;// z 的叔叔 y                if (y->c == RED) {// case 1:叔叔是红的                    z->p->c = BLACK;// 将 z 的父亲与叔叔置为黑                    y->c = BLACK;                    z->p->p->c = RED;// 将 z 的爷爷置为红                    z = z->p->p;// 问题上移两层                }                else {                    if (z == z->p->l) {// case 2:z 是左儿子                        z = z->p;                        rightRotate(z);// 右旋,转为 case 3                    }                    z->p->c = BLACK;                    z->p->p->c = RED;                    leftRotate(z->p->p);                }            }        }        root->c = BLACK;    }



【练习】


13.3-1 RB-INSERT中假设新插入的节点是红的。注意如果将z着为黑色,则红黑树的性质4)就不会被破坏。那么我们为什么没有选择将z着为黑色呢?

性质5)被破坏。


13.3-2 在将关键字41,38,31,12,19,8插入一棵初始为空的红黑树中之后结果树是什么样子?



13.3-3 假设3种情景中子树αβγδε的黑高度都是k。标上各个结点的黑高度,以验证图中所示的各种转换能保证性质5)。

case 1:皆为k

case 2:皆为k

case 3:皆为k


13.3-4 证明RB-INSERT-FIXUP永远不会将nil的COLOR设置为RED。

case 1:将z的爷爷置为红,考虑z的爷爷为nil的情况,则z为root的儿子,而在该情况下,root不是nil的儿子,因此不会进入任何case中。

case 2、3:对z的爷爷做一次右旋并染为红,若z的爷爷为nil,与case 1同样的原因,不会出现这种情况。

综上,nil永远不会被设置为RED。


13.3-5 考虑用RB-INSERT插入n个结点而成的一棵红黑树。证明:如果n>1,则该树至少有一个红结点。

当n==2时,不进行维护,该树有一个红叶子结点。

假设n==k-1时,至少有一个红结点。

当n==k时,case 1中,一黑三红变为两黑两红,至少有两个红结点;case 2与case 3中,两红一黑结点数量不变。若有红的根结点被染为黑,仍然剩下至少一个红结点。

因此n>1时该树至少一个红结点。


13.3-6 说明如果红黑树的表示中不提供父指针的话,应当如何有效的实现RB-INSERT。




0 0
原创粉丝点击