前言
前幾天學習了ConcurrentHashMap的一些結構,瞭解了底層通過鏈表以及紅黑樹來實現的數據結構,所以在此基礎上想要學習紅黑樹的一些知識。當然了既然要學習紅黑樹就要從二叉樹、平衡二叉樹進行學習,畢竟紅黑樹是在平衡二叉樹的基礎上進行變形。既然學習了紅黑樹那麼也要同時學習B-Tree(B
槓
Tree,不是B減
Tree)以及B+Tree。今天就把自己學習到的一些關於樹的知識進行整理總結。
1、二叉樹
1.1定義:
在計算機科學中,二叉樹是每個結點最多有兩個子樹的樹結構。--------來自百度百科
與根結點相連的兩個子樹成爲左子樹、右子樹。
1.2結構:
圖片摘自:https://blog.csdn.net/u014209205/article/details/81043002
1.3特點/性質:
二叉樹中有如下特點:
- 每個結點最多有兩棵子樹,所以二叉樹中不存在度大於2的結點。
- 二叉樹的子樹有左右之分,次序不能任意顛倒。
- 左子樹的鍵值小於根的鍵值,右子樹的鍵值大於根的鍵值。
1.4總結:
- 二叉樹的時間複雜度爲O(Log2n),近似與折半查找,但是二叉樹完全不平衡時,二叉樹成爲了鏈表,時間複雜度變爲O(n)。因此二叉排序樹的查找性能在O(Log2n)到O(n)之間。
- 通過以上的二叉樹結構中我們可以看到存在結點都在一個子樹的問題,這樣就導致了二叉樹的深度增加,從而影響了二叉樹的效率,爲了解決這種效率就提出了
平衡二叉樹(AVL樹)
。
2、平衡二叉樹(AVL樹)
2.1定義:
平衡二叉樹是一種特殊的二叉樹,是爲了解決二叉樹中所有結點都在一個子樹的問題。平衡二叉樹通過一種平衡算法使所有落在樹上的結點保持樹的平衡性(左子樹和右子樹的深度(高度)之差的絕對值不超過1;左子樹和右子樹都是平衡二叉樹)
。
2.2結構:
圖片摘自:https://blog.csdn.net/qq_25940921/article/details/82183093
2.3特點/性質:
平衡二叉樹(AVL樹)的特點:
- 滿意二叉樹的條件
- 左子樹和右子樹都是平衡二叉樹
- 左子樹和右子樹的深度(高度)之差的絕對值不超過1
- 新增和刪除操作可能造成平衡二叉樹失去平衡
2.4變換:
在平衡二叉樹中新增和刪除操作都有可能導致平衡二叉樹失去平衡,爲了維持平衡二叉樹的平衡性,需要通過一定的旋轉操作來使平衡二叉樹重新達到平衡。
2.4.1:左旋(LL旋轉)
在以上的平衡二叉樹的結構中,結點1
的存在導致了根結點5
的失衡,爲了保持平衡,需要對根結點5
進行LL旋轉,LL旋轉過程:
1. 結點5的左結點結點3代替結點5,
2. 結點5成爲了結點3的右結點,
3. 結點4調整位置成爲結點5的左結點。
最後調整結構如下:
2.4.2右旋(RR旋轉)
上圖的平衡二叉樹的結構中,根結點6的存在導致了根結點2的失衡,爲了維持平衡需要對結點2進行右旋(RR旋轉),RR旋轉的過程:
1. 結點2的右節點結點4代替結點2
2. 結點2成爲結點4的左結點
3. 結點3調整位置成爲結點2的右節點
最後旋轉效果如下:
2.4.3左右旋(LR旋轉)
在以上的結構中,結點3導致了結點5的失衡,結點3位於結點5的左子樹的右子樹上,所以我們在進行旋轉操作時,需要兩次旋轉才能調節平衡,因爲我們直接對結點5進行LL旋轉
時,結點2的右子樹
無法進行調整,所以我們需要先調整結點2
的右子樹(RR旋轉
),然後再調整結點5(LL旋轉)
。調整過程如下(先上圖,通過看圖分析):
1. 結點2進行RR旋轉:結點4代替結點2,結點2成爲結點4的左結點,結點3調整位置成爲結點2的右節點
2. 然後對結點5進行LL旋轉:結點4代替結點5,結點5成爲結點4的右節點
2.4.4右左旋(RL旋轉)
以上圖中,結點3的存在導致了結點2失衡,結點3位於結點2的右子樹的左子樹,需要兩次旋轉來調節平衡,第一次旋轉使問題結點成爲結點6,這樣就可以使用LL旋轉進行調整。
第一次對結點5進行LL旋轉,然後再對結點2進行RR旋轉。調整過程如下:
- 結點5進行LL旋轉:結點4代替結點5,結點5成爲結點4的右節點
- 結點2進行RR旋轉:結點4代替結點2,結點2成爲結點4的左結點,結點3調整位置成爲結點2的右節點
2.5總結
- 平衡二叉樹中通過一系列的旋轉來維持平衡
- 插入,查找,刪除的時間複雜度最好情況和最壞情況都維持在O(logN),但是頻繁的旋轉會消耗一定的時間。
3、紅黑樹
3.1定義:
因爲平衡二叉樹會維持絕對的平衡,所以在進行插入、刪除時會頻繁的進行旋轉
,從而造成性能的問題,爲了解決該問題,提出了紅黑樹
。
紅黑樹是一種特化的AVL樹(平衡二叉樹),都是在進行插入和刪除操作時通過特定操作保持二叉查找樹的平衡,從而獲得較高的查找性能。------來讀百度百科
紅黑樹是一個自平衡(不是絕對的平衡)的二叉查找樹。
3.2結構:
圖片來自:https://www.cnblogs.com/fornever/archive/2011/12/02/2270692.html
3.3特點/性質:
- 結點是紅色或黑色。
- 根結點是黑色。
- 每個葉子節點(NIL)是黑色。
- 如果一個節點是紅色的,則它的子節點必須是黑色的。
- 任意一結點到每個葉子結點的路徑都包含數量相同的黑結點(
也就是如果一個結點存在黑結點,那麼該結點肯定有兩個子結點
)。
3.4分析:
通過紅黑樹的特點以及性質,限定了紅黑樹不會退化成爲鏈表,同時也保證了任意節點到其每個葉子節點路徑最長不會超過最短路徑的2倍。可以通過下圖來理解:
上圖中最短路徑都是由黑色結點組成,最長路徑有四條
(圖中只畫出兩條),並且每條最長路徑都包含相同數量的黑色結點,並且最長路徑的長度最短路徑的兩倍
。
最長路徑爲:
M---->Q---->Y---->Z
M---->Q---->Y---->X
M---->Q---->O---->N
M---->Q---->O---->P
最短路徑爲:
M---->E
圖片來自:https://www.jianshu.com/p/e136ec79235c
紅黑樹並不是絕對平衡的二叉樹,所以並不會像平衡二叉樹那樣要求左子樹與右子樹的高度差爲1,紅黑樹通過任意一結點到每個葉子結點的路徑都包含數量相同的黑結點
這個性質來達到自己的平衡。
3.5變換:
紅黑樹的旋轉以及變換顏色的過程自己暫時還沒想通怎麼處理,因爲紅黑樹不僅涉及到旋轉,還需要在插入時進行顏色的變換。這裏自己沒想通,所以這裏就不做描述了,有興趣的可以看下這幾個博主。
https://segmentfault.com/a/1190000012728513
https://www.cnblogs.com/skywang12345/p/3245399.html
3.6總結:
- 通過紅黑樹很好的解決了平衡二叉樹存在的頻繁旋轉的問題,提高了一定的性能。
- 紅黑樹和平衡二叉樹在檢索的時候效率差不多,都是通過平衡進行二分查找,時間複雜度都是O(lnN)
- 在刪除和修改時,紅黑樹的效率更好,這是因爲紅黑樹不像AVL樹更爲嚴格的平衡,允許局部的很少的不完全平衡,但是影響不大,從而省去了很多沒必要的調節平衡的操作,AVL需要更多的旋轉次數來調節平衡的數據結構,所以效率不如紅黑樹。這樣在HashMap以及ConcurrentHashMap中,在插入、更新、刪除數據時不需要頻繁的旋轉,提高了這些操作的性能,所以HashMap以及ConcurrentHashMap採用紅黑樹而不是平衡二叉樹。
結語:
以上就是自己對於二叉樹、平衡二叉樹、紅黑樹的整理以及總結,也加深自己對這三個樹的認識,下面再整理B-Tree以及B+Tree的知識。