前言
以前在瞭解HashMap時得知JDK8的Map是用紅黑樹實現的(存儲元素的鏈表達到一定長度後,會變爲紅黑樹),而且網上還流傳着面試手寫紅黑樹的梗,數據結構課上也沒交過這個
一、爲什麼要用紅黑樹
因爲相較於普通的二叉搜索樹,紅黑樹具有平衡性。這與AVL樹相似,在增加或刪除元素後可能會出現旋轉的操作。
但是相較於AVL樹嚴格的約束(左右子樹的高度之差的絕對值最多爲1),紅黑樹的平衡約束更爲寬鬆,其旋轉操作的時間複雜度爲O(1),而AVL樹的旋轉操作的時間複雜度爲O(log n)。
因此在做增加、刪除操作時可以選擇紅黑樹,而在做搜索操作時選擇AVL樹(因爲嚴格的平衡性,高度一般比紅黑樹低)。
二、定義
紅黑樹(Red Black Tree) 是一種自平衡二叉查找樹。
三、性質
- 節點時紅色或黑色
- 根節點是黑色
- 葉子節點(null節點)是黑色
- 紅色節點的子節點都是黑色的,紅色節點的父節點是黑色的
- 從根節點起到葉子節點的所有路徑中,不能有兩個連續的紅色節點
- 從根節點起到葉子節點的所有路徑中,黑色節點的個數都是相同的
爲了方便起見,後面省略null節點
四、操作
1.搜索
同二叉搜索樹一樣,差不了多少,從根節點比大小,走分支
2.添加
添加操作比較複雜,情況比較多。
2.1.添加到黑色節點
如圖,這是最簡單的一種情況,粉紅色的爲新添加的節點,其父節點爲黑色,不違反性質4。
2.2.添加到紅色節點
粉色僅代表新添加的元素,本身還是紅色,灰色代表待添加的元素。
2.2.1.LL型 uncle節點爲黑
如圖,新添加的元素60,是76左孩子的左孩子,這種類型被稱之爲LL型,顯然LL型是不符合性質4的。
此時右旋,將72變黑,76變紅,同時72變爲76的父節點,即可滿足性質4。
如果60有兄弟節點,則將其移動到祖節點。
2.2.2.RR型 uncle節點爲黑
如圖,新添加的元素52,是46右孩子的右孩子,這種類型被稱之爲RR型,顯然RR型是不符合性質4的。
此時左旋,將50變黑,46變紅,同時50變爲46的父節點,即可滿足性質4。
2.2.3.LR型 uncle節點爲黑
旋轉後
2.2.4.RL型 uncle節點爲黑
旋轉後
2.2.5.LL型 uncle節點爲紅色
將父節點,叔節點變黑,祖節點變紅,如下圖:
會發現,此時已然不符合性質4,但是25、38、55符合2.2.1的LL型,右旋即可。
2.2.6.RR型 uncle節點爲紅色
變色後
然後需要右旋
2.2.7.LR型 uncle節點爲紅色
變色後:
右旋
2.2.7.RL型 uncle節點爲紅色
…
3.刪除
3.1 刪除度爲2的黑色節點
找該節點的前驅或後繼替換掉該節點。
3.2 刪除擁有一個紅色子節點的黑色節點
找該節點的前驅或後繼替換掉該節點,然後染黑。
3.3 刪除度爲0的黑色節點
3.3.1 兄弟節點是黑色且有紅色子節點
刪除該節點,然後旋轉、染色。
3.3.2 兄弟節點是黑色且無紅色子節點
將兄弟節點染成紅色,父節點染成黑色。
3.4 刪除紅色節點
直接刪除
。。。。。。。太麻煩了。。。。。。。。。。。。。。。。。。。。。。。。。。不想寫了