紅黑樹
1.概述
紅黑樹解決了二叉查找樹多次插入新節點可能導致的不平衡問題,紅黑樹是一種自平衡的二叉查找樹,除了符合二叉查找樹的基本特性外,它還具有以下特性:
1.節點是紅色或者黑色。
2.根節點是黑色。
3.每個葉子節點都是黑色的空節點(NIL節點)。
4.每個紅色節點的兩個子節點都是黑色。(從每個葉子到根的所有路徑上都不能有兩個連續的紅色節點)。
5.從任一節點到其每個葉子的所有路徑都包含相同數目的黑色節點。
具體結構如圖:
學習紅黑樹的概念,需要先了解什麼是二叉查找樹。
2.二叉查找樹
二叉查找樹(BST)的特性:
1.左子樹上所有節點的數值均小於或等於它根節點的值
2.右子樹上所有節點的數值均大於或等於它根節點的值
3.左,右子樹也分別爲二叉查找樹
二叉查找樹的結構如圖:
舉例說明
如果我們要查詢值爲10的節點用二叉查找樹會怎麼來查呢?
1.首先查看根節點9
2.由於10>9,因此查看右子樹節點13
3.由於10<13,因此查看13節點下左子樹的11
4由於10<11,因此查看11節點下左子樹的10,發現10正是要查找的節點
由上我們可以得出查找所需的最大次數等同於二叉查找樹的高度。
插入節點
在插入節點的適合也是利用類似的方法,通過一層層比較大小,找到新節點適合插入的位置。
缺點
缺點體現在多次插入新節點時二叉查找樹有可能會出現不平衡,這樣大大降低查找的效率
例如:
假設初始的二叉查找樹只有三個節點,根節點值爲9,左子樹值爲8,右子樹值爲12
接下來我們依次插入五個節點: 7,6,5,4,3,依照二叉查找樹的特性,結果幾乎變成了線性。
總結
正是二叉查找樹的這個缺陷,多次插入新節點有可能導致數據結構的不平衡,而產生了紅黑樹這種更高效合理的數據結構。
3.紅黑樹
從文章開始的地方我們可以知道紅黑樹的特點,正是因爲在二叉查找樹的基礎上增加的這些新的特點和規則,才保證了紅黑樹的自平衡,紅黑樹從根到葉子的最長路徑不會超過最短路徑的兩倍。
當插入或刪除節點的時候,紅黑叔的規則有可能被打破。
舉例說明
一.不會破壞紅黑樹規則的情況
1.向原紅黑樹插入值爲14的新節點
由於父節點15是黑色節點,因此這種情況並不會破壞紅黑樹的規則,無需做任何調整
二.會破壞紅黑樹規則的情況
1.向原紅黑樹插入值爲21的新節點:
由於父節點22是紅色節點,因此破壞了紅黑樹的規則4(從每個葉子到根的所有路徑上都不能有兩個連續的紅色節點),必須調整使之符合紅黑樹的規則
調整方法
1.變色
爲了符合紅黑樹的規則,嘗試把紅色節點變成黑色,或者把黑色節點變成紅色。
下圖所表示的是紅黑樹的一部分,需要注意節點25並不是根節點,因爲節點21和節點22連續出現了紅色,不符合規則4,所以把節點22從紅色變成黑色
因爲右多出的黑色節點打破了規則5(從任一節點到其葉子的路徑上都包含數量相同的黑色節點)所以發生連鎖反應,需要繼續把節點25從黑色變成紅色。
此時因爲出現了兩個連續紅色節點打破了規則6(從根節點到葉子的路徑上不能出現兩個連續的紅色節點),需要繼續把節點27從紅色變成黑色。
如上完成了所有的變色調整後纔算是一次完整的紅黑樹的自平衡。
2.旋轉
紅黑樹的旋轉調整又分爲左旋轉和右旋轉
我們來先看左旋轉:
逆時針旋轉紅黑樹的兩個節點,使得父節點被自己的右子樹取代,而自己成爲自己的左子樹。
如圖:
身爲右子樹的Y取代了X的位置,而X變成了自己的左子樹。此爲左旋轉。
關於右旋轉:
順時針旋轉紅黑樹的兩個節點,使得父節點被自己的左子樹取代,而自己成爲自己的右子樹。
如圖:
身爲左子樹的Y取代了X的位置,而X變成了自己的右子樹,此爲右旋轉。
4.紅黑樹的應用
紅黑樹的應用有很多,其中JDK的集合類TreeMap和TreeSet底層都是用的紅黑樹實現,在Java8中HashMap也使用了紅黑樹。