紅黑樹 插入算法(一)

前言

紅黑樹在數據結構裏面,是一種能自動平衡的樹,它的查詢速度很快,因爲能夠用到二分法,二分法的查詢複雜度只有O(log2(N)),幾萬條的數據也就只需查十幾次,不過要維持那麼高的查詢速度也是有代價,它的添加和刪除節點都需要每次都保證平衡.下面就開始介紹一它的節點添加算法.

一.紅黑樹的定義

我們先來介紹一下紅黑樹的特點,首先,紅黑樹必須滿足下面的5個條件:
• 1.節點是紅色或黑色。
• 2.根是黑色。
• 3.所有葉子都是黑色(葉子是NIL節點)。
• 4.每個紅色節點必須有兩個黑色的子節點。(從每個葉子到根的所有路徑上不能有兩個連續的紅色節點。)
• 5.從任一節點到其每個葉子的所有簡單路徑都包含相同數目的黑色節點(簡稱黑高)

以上是紅黑樹必須滿足的條件,如果有一條不滿足它就變成一個普通的樹,所以需要保證每次添加或刪除節點都能滿足以上要求.

另外紅黑樹還有一個特點,紅黑樹和平均樹不一樣,它的高度其實並不非常的平均,不過它的最高的高度永遠都不會超過它的最矮的高度的兩倍.爲什麼呢?下面就來看一下一個最極端的紅黑樹:

在這裏插入圖片描述
上圖的紅黑樹,我很容易可以看出來,上面最短的高度是最左邊的節點那裏,全部都是黑色的,最右邊的高度是最長的,我們知道紅黑樹的任何節點出發必須滿足每個黑色節點數量一致.所以如果我們要它的某一邊高度儘可能的長,我們就只能插入紅色節點,不能插入黑色節點,那我們能夠插入最多的紅節點,我們只能在每個黑色的節點下面再加多一個紅節點,並且一個黑節點只能加最多一個紅節點,因爲紅黑樹第4點已經提到,
紅節點的節點不能是紅節點.所以它最長的數量是 n個黑節點+n個紅節點=2n個節點.

二.插入算法實現

首先先來介紹一下紅黑樹的平衡手段.

1.節點旋轉;
2.節點變色

節點旋轉
旋轉是所有樹的一種特點,它分爲左旋和右旋轉兩種:

左旋轉
在這裏插入圖片描述
右旋轉
在這裏插入圖片描述
還有一種情況是不能直接旋轉的,列如下面的這種情況:
在這裏插入圖片描述
在這裏插入圖片描述
假如我要在節點30後面插入一個35的節點,是直接旋轉不了的,不過並不代我們對它完全沒有辦法,我們可以通過下面間接的旋轉,先將節點30和35調換位置,然後再讓35和40右旋轉

在這裏插入圖片描述

節點變色
節點也是可以改變兩邊的平衡的,下圖,左邊是不平衡的,右邊是平衡的,它們的結構完全沒有變化,就只該變了節點.那插入新的節點的時候是紅色的?
在這裏插入圖片描述
原因是插入之前所有的節點都是平衡的,如果插入黑色節點,會100%打破平衡.如果插入的是紅色的節點只有50%情況會打破平衡.

上面說完了平衡節點的兩種方式,下面再來說一下插入的流程.在這裏插入圖片描述
I.首先找到要插入的節點位置,作爲當前節點

II.插入節點
----1.當前節點爲黑色,插入紅色節點到到當前子節點,無需變色和旋轉。
----2.當前節點爲紅色:
------21.如果當前節點和它的兄弟節點爲紅色,將當前節點和它兄弟節點變爲黑色,如果父節點不是根節點,變爲紅色。
------------211.變完色之後,如果祖父節點爲紅色,然後把祖父節點作爲當前節點跳到步驟2(遞歸)。
------22.當前節點的兄弟節點爲黑色,當前節點變黑色,父節點變紅色,當前節點跳到步驟3。
----3.如果能旋轉,則進行左旋或右旋,不能旋轉則將當前節點的位置與子節點對換,再作旋轉。

樹的查找就不多解釋了,就是一個個值比對,直到找到葉節點.

1.首先我們需要歸納一下下圖中標記黑色箭頭的都是在黑色節點上可以插入新節點的地方

在這裏插入圖片描述
雖然在不同的節點上,但它的結構其實只有下面這種,當我們插入紅色的節點,對它的平衡來說完全沒有改變.
在這裏插入圖片描述
所以我們可以歸納出通用的一步:1當前節點爲黑色,插入紅色節點到到當前子節點,無需變色和旋轉。

2當我們插入的是紅色節點時,這種情況比較多,因爲紅黑不能存在有兩個連續的節點,所以我們插入新節點是要判斷怎麼變色和旋轉.下面標出我們能夠插入的紅色節點的位置.
在這裏插入圖片描述

我來歸納一下一共有5種情況:
在這裏插入圖片描述

當我們要插入的那個節點,它的兄弟節點也是紅色,我有4個位置可插入
在這裏插入圖片描述
但其實四個位置都是一樣的,因爲它是對稱的,不管插入到那個子節點上,都只需要改被插入節點及其父節點和兄弟節點的顏色就行
在這裏插入圖片描述
所以我們又歸納出了第二條規律:21.如果當前節點和它的兄弟節點爲紅色,將當前節點和它兄弟節點變爲黑色,如果父節點不是根節點,變爲紅色。

下面我們來分析這種情況,首先整個節點是沒有兄弟節點的,但是我們可以吧nil節點看作是黑色的,所以它有一個黑色的兄弟節點
在這裏插入圖片描述
當我們把節點插到它右邊時,它是沒法一口氣做旋轉的,所以我們將旋轉抽象爲一個獨立的步驟:3.如果能旋轉,則進行左旋或右旋,不能旋轉則將當前節點的位置與子節點對換,再作旋轉。
下面這個圖是將節點31與節點38對調了位置,再與節點45做旋轉.
在這裏插入圖片描述
當我們把節點插入到左邊時
在這裏插入圖片描述
其實上面兩種情況其實也一樣,現在我們又能得出另外一種結論:22.當前節點的兄弟節點爲黑色,當前節點變黑色,父節點變紅色,當前節點跳到步驟3。(我截的圖是先旋轉再變色,這裏是先變色再旋轉其實結果一樣)

來我們接着繼續分析,這個的兄弟節點也是黑色的,所以和上面的條件是一樣的,那我們看看,結果是不是也一樣
在這裏插入圖片描述
插入新節點到左邊:
在這裏插入圖片描述
插入到右邊節點:
在這裏插入圖片描述
步驟22仍然適用這種場景

再看看下面這種場景是不是一樣
在這裏插入圖片描述
插入到左節點
在這裏插入圖片描述
插入到右節點
在這裏插入圖片描述
一樣適用步驟22

最後下面這種情況也也一樣
在這裏插入圖片描述

所以我們的算法只需要考慮下面兩種情況,其他的都是它們的變形:
在這裏插入圖片描述
在這裏插入圖片描述

不過兩個節點相同的還有一種情況要考慮,就使它的祖父節點爲紅色時:
在這裏插入圖片描述
在這裏插入圖片描述
所以需要將在步驟21處理後,再補充一點:211.變完色之後,如果祖父節點爲紅色,然後把祖父節點作爲當前節點跳到步驟2(遞歸)。
就21點需要考慮遞歸問題,其步驟不需要,因爲調整完之後,父節點還是黑色的,和原來沒啥不一樣.

結語

紅黑樹的插入算法講完了,因爲刪除節點和插入節點的算法是不對稱的,而且要複雜得多,後面本人再繼續完善刪除算法.
感謝各位看官,看完了本人的博客,如果覺得對你本人有用,請不要吝嗇您的點贊,謝謝大家.

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章