《算法導論》筆記 第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)被破壞。code


13.3-2 在將關鍵字41,38,31,12,19,8插入一棵初始爲空的紅黑樹中以後結果樹是什麼樣子?blog



13.3-3 假設3種情景中子樹αβγδε的黑高度都是k。標上各個結點的黑高度,以驗證圖中所示的各類轉換能保證性質5)。ip

case 1:皆爲kclass

case 2:皆爲kfile

case 3:皆爲kim


13.3-4 證實RB-INSERT-FIXUP永遠不會將nil的COLOR設置爲RED。img

case 1:將z的爺爺置爲紅,考慮z的爺爺爲nil的狀況,則z爲root的兒子,而在該狀況下,root不是nil的兒子,所以不會進入任何case中。紅黑樹

case 二、3:對z的爺爺作一次右旋並染爲紅,若z的爺爺爲nil,與case 1一樣的緣由,不會出現這種狀況。while

綜上,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。

相關文章
相關標籤/搜索