其餘更多java基礎文章:
java基礎學習(目錄)html
學習資料:
紅黑樹詳細分析,看了都說好
紅黑樹刪除操做
碼圖並茂紅黑樹
紅黑樹從頭到尾插入和刪除結點的全程演示圖java
在研究集合類源碼的時候,發現Map,Set裏面很多用到紅黑樹,爲了可以更順利的學習源碼。我決定把紅黑樹知識惡補一下。若是不瞭解樹、二叉樹、平衡二叉樹定義的同窗先了解一下這些前提知識。 因爲能力時間有限,我就不復述學習資料裏大神寫的內容了。關於一些基礎知識和概念請你們先讀一遍學習資料裏的文章。我接下來的講解都將基於這三篇的基礎之上,進行更細緻的講解,把我在學習過程當中遇到的一些比較難理解的點嘗試用文字或圖例變得更容易理解。post
我強烈建議你們的閱讀順序爲:先讀紅黑樹詳細分析,看了都說好。這篇文章講的比較全,可是刪除部分對我來講,文字上有點難理解。接着閱讀紅黑樹刪除操做。這篇文章把刪除講解的比較細緻。最後再閱讀紅黑樹從頭到尾插入和刪除結點的全程演示圖或碼圖並茂紅黑樹。前者格式很差,後者漏了一步,能夠主要之後者爲主。兩篇文章就是來學以至用的,文章以圖來全程演示此紅黑樹的全部插入,和刪除狀況。可是缺點是沒有任何講解,因此正適合檢驗一下前兩篇的學習和理解,建議你們能夠先本身推理一步,而後再看與文章中的下一步的結果圖是否一致。學習
OK,如今就當你們已經按上面步驟閱讀完了。若是此時還有疑問或不懂的地方,能夠繼續往下閱讀,也能夠在評論中詢問我,我會盡力回答。因爲我的只是對紅黑樹的刪除部分以爲有難點,因此下面主要講的是紅黑樹刪除部分。.net
D表示要被刪除的節點。即:取 Delete 的首字母;
P 表示父節點。即:取 Parent 的首字母;
S表示兄弟姐妹節點。即:取 Sibling的首字母;
U表示叔伯節點。即:取Uncle的首字母;
G表示祖父節點。即:取 Grandfather的首字母;
L表示左樹。即:取Left的首字母 ;
R表示右樹。即:取Right的首字母;
Nil表示葉子節點。即所謂的空節點;注意:紅黑樹中的葉子節點與其餘樹中所述說的葉子節點不是同一律念。並且紅黑樹中的葉子節點(即:Nil節點)永遠是被定義爲黑色的。3d
下文的節點命名錶示將會使用以上這些命名約定或它們的組合表示。所以,請先牢記這些命名約定。舉例:
DR表示要被刪除的節點的右子樹,即:右子節點; SL表示兄弟節點的左子樹,即:左子節點;code
在紅黑樹中,刪除一個節點往大的說,只有如下四種狀況。
狀況一:刪除的節點的左、右子樹都非空;
狀況二:刪除的節點的左子樹爲空樹,右子樹非空;
狀況三:刪除的節點的右子樹爲空樹,左子樹非空;
狀況四:刪除的節點的左、右子樹都爲空樹;cdn
其中狀況一,能夠按與其餘二叉搜索樹的刪除方式同樣處理,最終能夠轉換到後面的三種狀況。具體爲:找到(Old)D節點的直接後繼節點(暫且稱爲X節點)
,而後將X的值轉移到D節點,最後將X節點做爲真正要被刪除掉的節點(即:(Real)D節點)。 這樣刪除操做後,能夠保證該樹仍然爲一棵二叉搜索樹。但因爲紅黑樹的定義(即:紅黑樹的性質)約定。這樣刪除(Real)D節點後,可能會破壞紅黑樹的性質。因此須要額外作一些調整處理,這即是下面將要詳細討論的內容。 說明:下文中所提到的D,除非有特別說明,不然都將指的是(Real)D。htm
經過閱讀紅黑樹詳細分析,看了都說好、紅黑樹刪除操做 兩篇文章,能夠發現雖說法不一樣,可是絕大多數應對的情形是同樣,我整理爲下列表格:blog
圖例 | 《紅黑樹刪除操做》 | 《紅黑樹詳細分析》 | 備註 |
---|---|---|---|
被刪除D爲紅 | 只須要直接將D節點刪除,並將DR做爲P的左子節點便可。 | ||
D爲黑,DR不爲Nil、DR必爲紅 | 因爲紅黑樹定義5,(P-D-Nil)和(P-D-DR-Nil)的黑點數同樣,因此DR必爲紅 | ||
D黑、DR爲Nil、S紅 | 狀況二 | 仍需繼續平衡 | |
D黑、S黑、SL紅 | 狀況五(後續爲狀況六) | 這裏兩篇文章有些不一樣,《刪除操做》中單獨處理,《詳細分析》將與狀況六搭配起來處理平衡,可是結果是同樣的。我的喜歡使用狀況五六搭配起來使用方式 | |
D黑、S黑、SR紅 | 狀況六 | ||
D黑、S黑、P紅、SL黑、SR黑 | 狀況四 | ||
D黑、S黑、P黑、SL黑、SR黑 | 狀況三 | 可能仍需繼續平衡,此時通過P的路徑的黑節點個數將會比不通過它的路徑少一個。所以,咱們將P做爲待平衡的節點(即:此時的P至關於DR的角色)往上繼續上溯,直到P爲根節點爲止。 |
在紅黑樹刪除操做中D黑、DR爲Nil、S紅
這個分支我的認爲講的有點太繞了。圖畫的容易讓人混淆。我從新畫個圖方便你們理解。其實做者省略了SL和SR的葉子節點,準確的紅黑樹圖應該以下:
D黑、S黑、P紅、SL黑、SR黑
的狀況。
因此最終平衡結果以下:
在刪除結點演示圖中的刪除結點16,就是這個狀況。
這裏咱們根據紅黑樹從頭到尾插入和刪除結點的全程演示圖的刪除演示圖,詳解其中的幾步。
先尋找到結點12的後繼結點13,而後將13的值複製到結點12處,將結點13刪除,此時能夠發現匹配D黑、S黑、SR紅
的狀況(由於是鏡像的緣由,因此是SR紅不是SL紅),根據匹配的結果旋轉變色,最後獲得結果紅黑樹:
此時紅黑樹爲,咱們將刪除結點13
把注意力集中在13-16-17這棵紅黑樹上,發現匹配D黑、S黑、P黑、SL黑、SR黑
情形,根據匹配結果着色爲下圖(右):
此時以結點16爲根的紅黑樹平衡了,可是咱們把目光放在整棵紅黑樹上,會發現全部通過結點16的黑節點數會比不通過結點16的少1,因此根據
D黑、S黑、P黑、SL黑、SR黑
的備註,咱們將原P(結點16)做爲待平衡的節點(DR)往上繼續上溯,直到P爲根節點爲止。以下圖所示(結點16連線斷開僅是爲了防止匹配時被紅結點17干擾):
最後,若是你也在學習紅黑樹,但願這篇文章可以幫助到你。另外,因爲紅黑樹自己比較複雜,加之本人水平有限,不免會出一些錯誤。若是有錯或者有疑問,還望你們指出來,咱們共同討論。