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


    【笔记】


        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。




  • 相关阅读:
    通用类 GetCPU 返回系统CPU占用百分比
    通用类 NVCSpecialized 序列和反序列化
    通用类 Logger 日志类
    第07组 Alpha冲刺 (1/6)(组长)
    第07组 Alpha冲刺 (5/6)(组长)
    第07组 Alpha冲刺 (6/6)(组长)
    第07组 Alpha冲刺 (2/6)(组长)
    第07组 Alpha冲刺 总结(组长)
    第07组 Alpha冲刺 (4/6)(组长)
    第07组 Alpha冲刺 (3/6)(组长)
  • 原文地址:https://www.cnblogs.com/cyendra/p/3687869.html
Copyright © 2020-2023  润新知