紅黑樹

我們在前面的2票博文中已經寫到簡單介紹了搜索二叉樹搜索二叉樹,AVL樹AVL樹的創建,我們能該看到的是AVL樹是一個搜索二叉樹,其實,我們現在說的紅黑樹也是基於搜索二叉樹和AVL樹中的一些操作上來實現的,如果你對搜索二叉樹有疑問,可以看看上面的兩篇博文,如果,有錯誤,還望不吝賜教,如果你對搜索二叉樹與AVL樹不熟悉,紅黑樹理解起來就很難了(對我而言),總之,我覺得在看紅黑樹之前,搜索二叉樹,AVL樹是需要掌握的;

本篇博文中出現的代碼都是模塊需要出現的段代碼,完整代碼以上傳GitHub:紅黑樹的創建;

下面我們就開始紅黑樹的實現:

紅黑樹的概念

上面我們已經說過,紅黑樹是基於搜索二叉樹與AVL樹實現的,所以它本身是一顆搜索二叉樹,它在每個結點上面增加了一個存儲位來表示結點的瑤瑟,可以是RED或BLACK,通過對任何一條從根結點到葉子結點上的簡單路徑來約束,紅誒書保證最長路徑不超過最短路徑的兩倍,因而近似平衡。

紅黑樹的性質(很重要,很重要,很重要)

1、每個節點不是紅色就是黑色;
2、根結點爲黑色;
3、如果根結點爲紅,則它的兩個葉子結點一定是黑色的(沒有連續兩個紅色結點,可以有連續兩個黑色結點哦)
4、對於每個結點,從該節點到其所在後代葉子結點的簡單路徑上,均包含相同數目的黑色結點(每條路徑上黑色結點的數量相同)
5、每個葉子結點都是黑色的(此處的葉子結點是指NULL結點)

在概念中我們提到通過紅黑顏色的約束,紅黑樹能保證最長路徑不超過最短路徑的兩倍,爲什麼?
由性質3我們可以知道任何一個簡單路徑上不能有兩個連續的紅色結點,所以最短路徑可能會是全黑結點最長路徑是紅黑交替,又由4可知,每條路徑上黑色結點的數量相同,所以最長路徑最大就是最短路徑的2倍,所以說不會超過。

插入結點##(只實現了他在左邊的情況,鏡像實現在完整版代碼中有)

根據上述的5個性質,我們大致應該把新插入的結點默認的設置爲紅色的;
情況1:插入的結點爲根結點:

這種情況,其實很簡單,我們只需要把它的顏色換爲黑色就可以了;
情況2:在黑色結點下插入一個新結點:

其實這種情況也很簡單,直接插入下去就可以了,並沒有影響紅黑樹;

情況3:插入結點的雙親和叔叔結點都爲紅色,祖父結點爲黑色;
這裏寫圖片描述

我們需要將雙親和叔叔結點改爲黑色,把祖父結點改爲紅色,然後在往上調整就可以了;

Node* Uncle = Grandfather->_pRight;
                if (Uncle && RED == Uncle->_color)//情況3
                {
                    parent->_color = Uncle->_color = BLACK;
                    Grandfather->_color = RED;

                    NewNode = Grandfather;
                    parent = Grandfather->_pParent;
                }

情況4:插入結點的雙親爲紅色,插入結點爲雙親的左孩子,祖父結點爲黑色,叔叔結點不存在/存在爲黑色;
這裏寫圖片描述

我們要以祖父結點爲parent進行右單旋,這裏的單旋就不在介紹了,前面的AVL樹中已經說到過了,如有不懂可以看看:
然後把祖父結點的顏色和雙親結點的顏色互換;

_RotateR(Grandfather);  //情況4
                    std::swap(parent->_color, Grandfather->_color);

情況5:插入結點的雙親爲紅色,插入結點爲雙親的右孩子,祖父結點爲黑色,叔叔結點不存在/存在爲黑色;

這裏寫圖片描述

這種情況,要先以雙親爲根進行左單旋,然後就是情況4了,再安裝情況4執行就可以了;

                    if (NewNode == parent->_pRight)  //情況5,因爲情況5處理完還要處理情況4 ,所以先處理5中的旋轉;
                    {
                        _RotateL(parent);
                        std::swap(parent, NewNode);
                    }
                    _RotateR(Grandfather);  //情況4
                    std::swap(parent->_color, Grandfather->_color);
                }
發佈了63 篇原創文章 · 獲贊 50 · 訪問量 6萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章