1、在理解紅黑樹以前,先看一些二叉查找樹java
二叉查找樹特性:左字數上全部的節點的值都小於或等於他的根節點上的值數組
右子樹上全部節點的值均大於或等於他的根節點的值3d
左、右子樹也跟別爲平衡二叉樹blog
舉個二叉樹的例子:class
能夠看到若是要查詢10的話,10>9二叉樹
所以到他的右子樹,右子樹根節點爲13,10<13遍歷
所以到其左子樹,左子樹根節點爲11>10im
到其左子樹,爲10,找到相應的節點d3
不過二叉查找樹有一些問題,可能會出現不平橫的狀況,即以下圖所示的狀況鏈表
從這種狀況能夠看出,明顯存在左子樹和右子樹深度相差過多,在使用平衡狀況下的二叉查找樹是時間複雜度爲logn,而出現這種極端狀況的話,想要查9的位置就須要每一次都遍歷下一個右子樹,頗有可能時間複雜度變爲n(與數組普通查詢的時間複雜度相同)
基於上述狀況,引入了平衡二叉樹,紅黑樹即爲平衡二叉樹的一種
2、紅黑樹
特性:節點是紅色或黑色
根節點必定是黑色
每一個葉節點都是黑色的空節點(NIL節點)
每一個紅節點的兩個子節點都是黑色的(從每一個葉子到跟的全部路徑上不能有兩個連續的紅節點)(即對於層來講除了NIL節點,紅黑節點是交替的,第一層是黑節點那麼其下一層確定都是紅節點,反之同樣)
從任一節點到其每一個葉子節點的全部路徑都包含相同數目的黑色節點
正是因爲這些緣由使得紅黑樹是一個平衡二叉樹
紅黑樹的例子
向紅黑樹中插入節點14(通常默認插入節點是紅色的)
在原樹上插入20
能夠看到,插入之後樹已經不是一個平衡的二叉樹,並且並不知足紅黑樹的要求,由於20和21均爲紅色,這種狀況下就須要對紅黑樹進行變色,21須要變爲黑色,22就會變成紅色,若是22變成紅色,則須要17和25都變成黑色
而17變成黑色顯然是不成立的,由於若是17變爲黑色,那麼13就會變爲紅色,不知足二叉樹的規則,所以此處須要進行另外一個操做---------左旋操做
左旋:下圖就是一個左旋的例子,通常狀況下,若是左子樹深度過深,那麼便須要進行左旋操做以保證左右子樹深度差變小
對於上圖因爲右子樹中17變爲黑色之後須要把13變成紅色,所以進行一次左旋,將17放在根節點,這樣既可保證13爲紅色,左旋後結果
然後根據紅黑樹的要求進行顏色的修改
進行左旋後,發現從根節點17,到1左子樹的葉子節點通過了兩個黑節點,而到6的左葉子節點或者右葉子節點要經歷3個黑節點,很顯然也不知足紅黑樹,所以還須要進行下一步操做,須要進行右旋操做
右旋:與左旋正好相反
因爲是從13節點出現的不平衡,所以對13節點進行右旋,獲得結果
然後再對其節點進行變色,獲得結果
這即是紅黑樹的一個變換,它主要用途有不少,例如java中的TreeMap以及JDK1.8之後的HashMap在當個節點中鏈表長度大於8時都會用到。