前言
二叉平衡樹
1)空樹
2)對於任何一個節點來說,它的左右兩個子樹的高度差的絕對值不超過1
紅黑樹
不算嚴格意義上的平衡樹,它具有以下特點
1)節點有顏色,要麼黑色要麼紅色
2)根節點必須是黑色
3)紅色節點的左右兩個子節點都是黑色
4)從任一節點到其每個葉子節點所有路徑都包含相同數目的黑色節點個數
這些約束強制了紅黑樹的關鍵性質:從根節點到葉子節點的最長路徑不大於最短路徑的兩倍長。這棵樹是大致平衡的。
特點:可以在O(logn)的時間複雜度內做查找、插入和刪除。
兩顆樹之間的對比
紅黑樹放棄了追求完全平衡,追求大致平衡,在與平衡二叉樹的時間複雜度相差不大的情況下,保證每次插入最多隻需要三次旋轉(三次旋轉的說法是否正確???)就能達到平衡,實現起來也更爲簡單。
平衡二叉樹追求絕對平衡,條件比較苛刻,實現起來比較麻煩,每次插入新節點之後需要旋轉的次數不能預知。執行插入還是刪除操作,只要不滿足上面的條件,就要通過旋轉來保持平衡,而它的旋轉非常耗時的。
可知平衡二叉樹適合用於插入與刪除次數比較少,但查找多的情況。實際工程中紅黑樹的運用比較多。比如HashMap底層的數據結構是數組+鏈表、數組+紅黑樹(JDK1.8之後)
平衡二叉樹
由於平衡二叉樹的第二個特性很容易被破壞,所以需要通過旋轉的方式來保持平衡。
有以下四種情況:
情況分類 | 解決方案 |
LL型 | 右旋 |
RR型 | 左旋 |
LR型 | 先左旋後右旋 |
RL型 | 先右旋後左旋 |
前期知識儲備
平衡因子=左子樹的高度-右子樹的高度
失衡節點的平衡因子的絕對值是大於1的。AVL樹失衡類型的判斷都基於這個失衡節點的。也就是說LL型需要調整的是失衡節點的左子樹的左子樹,LR型需要調整的是失衡節點左子樹的右子樹。
對於單旋轉操作,就是以中間節點爲中心旋轉。而雙旋轉中,因爲不是一次旋轉,不能在一開始就確定旋轉中心點,我們在第一次旋轉的過程中,只是旋轉後面的兩個節點,並保證節點值的大小關係,
情況一:
LL型
情況二:
RR型
情況三:
RL型
情況四:
LR型
圖片查考的地址:https://blog.csdn.net/HowardEmily/article/details/79543892 原作者若視爲侵權,立即刪除。
旋轉的代碼見此
(後序的補充)
紅黑樹
展開內容是 hashmapJDK1.8之前和之後的底層數據結構的分析,注:目前分析不牽扯源碼,只是單純數據結構分析。
HashMap1.8 底層數據結構是數組+鏈表和數組+紅黑樹
解決地址衝突問題,地址探測法和拉鍊法
1)當節點的個數大於8的時候,轉成紅黑樹
2)當節點的個數小於6的時候,轉成鏈表
爲什麼節點個數是8,6進行轉換?
首先選擇紅黑樹是爲了提高查找效率,鏈表的查找時間複雜度是O(n),紅黑樹的查找時間複雜度是O(logn)
鏈表的平均查找的時間複雜度是O(n/2),在n=6的時候,時間複雜度爲3
紅黑樹的平均查找的時間複雜度是O(logn),在n=8的時候,時間複雜度約等於3
結論:兩個查找的時間複雜度幾乎相等。所以設置了6和8這個臨界值。中間過渡的節點是7,爲了防止剛好在一個臨界值進行頻繁的刪除和增加。