網上關於紅黑樹的博文不少,可是可能是上來即講定義,未說其因此然,難以理解且無所養分,甚者示例圖有誤且概念模糊的比比便是;html
因爲最近在學習相關知識找到一篇較爲透徹且深刻剖析的博文特此轉載修訂數據結構
注:原文示例圖中有所錯誤本文中已從新修正,並增長了紅黑樹相關部分更多內容性能
紅黑樹,對很多人來講是個比較頭疼的名字,在網上搜資料也不多有講清楚其演變來源的,多數一上來就給你來五條定義,紅啊黑啊與根節點距離相等之類的,而後就開始進行旋轉、插入、刪除這些操做。一通操做下來,連紅色和黑色怎麼來的,是什麼含義,有什麼做用都雲裏霧裏的,能搞清楚就怪了。學習
本文介紹紅黑樹,暫時不涉及任何代碼,只是幫助你理解紅黑樹的演變來源,樹結構中紅黑色具體含義,保證你理解了事後,再去看什麼旋轉插入的東西,要清晰得多。換句話說,理解本文要描述的內容是從代碼級理解紅黑樹的基礎。spa
開始以前,我仍是懇請你保持耐心,一步一步仔細看完,浮躁的話真的作很差任何事情。.net
紅黑樹的起源,天然是二叉查找樹了,這種樹結構從根節點開始,左子節點小於它,右子節點大於它。每一個節點都符合這個特性,因此易於查找,是一種很好的數據結構。可是它有一個問題,就是容易偏向某一側,這樣就像一個鏈表結構了,失去了樹結構的優勢,查找時間會變壞。設計
因此咱們都但願樹結構都是矮矮胖胖的,像這樣:3d
而不是像這樣:htm
在這種需求下,平衡樹的概念就應運而生了。blog
紅黑樹就是一種平衡樹,它能夠保證二叉樹基本符合矮矮胖胖的結構,可是理解紅黑樹以前,必須先了解另外一種樹,叫2-3樹,紅黑樹背後的邏輯就是它。
好吧來看2-3樹吧。
2-3樹是二叉查找樹的變種,樹中的2和3表明兩種節點,如下表示爲2-節點和3-節點。
2-節點即普通節點:包含一個元素,兩條子連接。
3-節點則是擴充版,包含2個元素和三條連接:兩個元素A、B,左邊的連接指向小於A的節點,中間的連接指向介於A、B值之間的節點,右邊的連接指向大於B的節點。
2-節點: 3-節點:
在這兩種節點的配合下,2-3樹能夠保證在插入值過程當中,任意葉子節點到根節點的距離都是相同的。徹底實現了矮胖矮胖的目標。怎麼配合的呢,下面來看2-3樹的構造過程。
所謂構造,就是從零開始一個節點一個節點的插入。
在二叉查找樹中,插入過程從根節點開始比較,小於節點值往右繼續與左子節點比,大於則繼續與右子節點比,直到某節點左或右子節點爲空,把值插入進去。這樣沒法避免偏向問題。在2-3樹中,插入的過程是這樣的。
若是將值插入一個2-節點,則將2-節點擴充爲一個3-節點。
若是將值插入一個3-節點,分爲如下幾種狀況。
(1).3-節點沒有父節點,即整棵樹就只有它一個三節點。此時,將3-節點擴充爲一個4-節點,即包含三個元素的節點,而後將其分解,變成一棵二叉樹。
此時二叉樹依然保持平衡。
(2).3-節點有一個2-節點的父節點,此時的操做是,3-節點擴充爲4-節點,而後分解4-節點,而後將分解後的新樹的父節點融入到2-節點的父節點中去。
(3).3-節點有一個3-節點的父節點,此時操做是:3-節點擴充爲4-節點,而後分解4-節點,新樹父節點向上融合,上面的3-節點繼續擴充,融合,分解,新樹繼續向上融合,直到父節點爲2-節點爲止,若是向上到根節點都是3-節點,將根節點擴充爲4-節點,而後分解爲新樹,至此,整個樹增長一層,仍然保持平衡。
第三種狀況稍微複雜點,爲了便於直觀理解,如今咱們從零開始構建2-3樹,囊括上面全部的狀況,看完因此步驟後,你也能夠本身畫一畫。
咱們將{7,8,9,10,11,12}中的數值依次插入2-3樹,畫出它的過程:
因此,2-3樹的設計徹底能夠保證二叉樹保持矮矮胖胖的狀態,保持其性能良好。可是,將這種直白的表述寫成代碼實現起來並不方便,由於要處理的狀況太多。這樣須要維護兩種不一樣類型的節點,將連接和其餘信息從一個節點複製到另外一個節點,將節點從一種類型轉換爲另外一種類型等等。
所以,紅黑樹出現了,紅黑樹的背後邏輯就是2-3樹的邏輯,可是因爲用紅黑做爲標記這個小技巧,最後實現的代碼量並不大。(可是,要直接理解這些代碼是如何工做的以及背後的道理,就比較困難了。因此你必定要理解它的演化過程,才能真正的理解紅黑樹)
咱們來看看紅黑樹和2-3樹的關聯,首先,最檯面上的問題,紅和黑的含義。紅黑樹中,全部的節點都是標準的2-節點,爲了體現出3-節點,這裏將3-節點的兩個元素用左斜紅色的連接鏈接起來,即鏈接了兩個2-節點來表示一個3-節點。這裏紅色節點標記就表明指向其的連接是紅連接,黑色標記的節點就是普通的節點。因此纔會有那樣一條定義,叫「從任一節點到其每一個葉子的全部簡單路徑都包含相同數目的黑色節點」,由於紅色節點是能夠與其父節點合併爲一個3-節點的,紅黑樹實現的實際上是一個完美的黑色平衡,若是你將紅黑樹中全部的紅色連接放平,那麼它全部的葉子節點到根節點的距離都是相同的。因此它並非一個嚴格的平衡二叉樹,可是它的綜合性能已經很優秀了。
借一張別人的圖來看:
紅連接放平:
因此,紅黑樹的另外一種定義是知足下列條件的二叉查找樹:
⑴紅連接均爲左連接。
⑵沒有任何一個結點同時和兩條紅連接相連。(這樣會出現4-節點)
⑶該樹是完美黑色平衡的,即任意空連接到根結點的路徑上的黑連接數量相同。
理解了這個過程之後,再去看紅黑樹的各類嚴格定義,以及其插入,刪除還有旋轉等操做,相信你腦子裏的思路會清晰得多的。
注:紅黑數是平衡二叉樹的一種,插入時遵循二叉樹「左右」定律:
該父節點的左子節點:爲小於父節點中且子樹中最接近父節點值得數。
該父節點的右子節點:爲大於父節點中且子樹中最接近父節點值得數。
R-B Tree,全稱是Red-Black Tree,又稱爲「紅黑樹」,它一種特殊的二叉查找樹。紅黑樹的每一個節點上都有存儲位表示節點的顏色,能夠是紅(Red)或黑(Black)。
紅黑樹的特性:
(1)每一個節點或者是黑色,或者是紅色。
(2)根節點是黑色。
(3)每一個葉子節點(NIL)是黑色。 [注意:這裏葉子節點,是指爲空(NIL或NULL)的葉子節點!]
(4)若是一個節點是紅色的,則它的子節點必須是黑色的。
(5)從一個節點到該節點的子孫節點的全部路徑上包含相同數目的黑節點。
注意:
(01) 特性(3)中的葉子節點,是隻爲空(NIL或null)的節點。
(02) 特性(5),確保沒有一條路徑會比其餘路徑長出倆倍。於是,紅黑樹是相對是接近平衡的二叉樹。
紅黑樹示意圖以下:
紅黑樹的應用比較普遍,主要是用它來存儲有序的數據,它的時間複雜度是O(lgn),效率很是之高。
例如,Java集合中的TreeSet和TreeMap,C++ STL中的set、map,以及Linux虛擬內存的管理,都是經過紅黑樹去實現的。
紅黑樹的時間複雜度爲: O(lgn)
下面經過「數學概括法」對紅黑樹的時間複雜度進行證實。
定理:一棵含有n個節點的紅黑樹的高度至多爲2log(n+1).
證實:
"一棵含有n個節點的紅黑樹的高度至多爲2log(n+1)" 的逆否命題是 "高度爲h的紅黑樹,它的包含的內節點個數至少爲 2h/2-1個"。
咱們只須要證實逆否命題,便可證實原命題爲真;即只需證實 "高度爲h的紅黑樹,它的包含的內節點個數至少爲 2h/2-1個"。
從某個節點x出發(不包括該節點)到達一個葉節點的任意一條路徑上,黑色節點的個數稱爲該節點的黑高度(x's black height),記爲bh(x)。關於bh(x)有兩點須要說明:
第1點:根據紅黑樹的"特性(5) ,即從一個節點到該節點的子孫節點的全部路徑上包含相同數目的黑節點"可知,從節點x出發到達的全部的葉節點具備相同數目的黑節點。這也就意味着,bh(x)的值是惟一的!
第2點:根據紅黑色的"特性(4),即若是一個節點是紅色的,則它的子節點必須是黑色的"可知,從節點x出發達到葉節點"所經歷的黑節點數目">= "所經歷的紅節點的數目"。假設x是根節點,則能夠得出結論"bh(x) >= h/2"。進而,咱們只需證實 "高度爲h的紅黑樹,它的包含的黑節點個數至少爲 2bh(x)-1個"便可。
到這裏,咱們將須要證實的定理已經由
"一棵含有n個節點的紅黑樹的高度至多爲2log(n+1)"
轉變成只須要證實
"高度爲h的紅黑樹,它的包含的內節點個數至少爲 2bh(x)-1個"。
下面經過"數學概括法"開始論證高度爲h的紅黑樹,它的包含的內節點個數至少爲 2bh(x)-1個"。
(01) 當樹的高度h=0時,
內節點個數是0,bh(x) 爲0,2bh(x)-1 也爲 0。顯然,原命題成立。
(02) 當h>0,且樹的高度爲 h-1 時,它包含的節點個數至少爲 2bh(x)-1-1。這個是根據(01)推斷出來的!
下面,由樹的高度爲 h-1 的已知條件推出「樹的高度爲 h 時,它所包含的節點樹爲 2bh(x)-1」。
當樹的高度爲 h 時,
對於節點x(x爲根節點),其黑高度爲bh(x)。
對於節點x的左右子樹,它們黑高度爲 bh(x) 或者 bh(x)-1。
根據(02)的已知條件,咱們已知 "x的左右子樹,即高度爲 h-1 的節點,它包含的節點至少爲 2bh(x)-1-1 個";
因此,節點x所包含的節點至少爲 ( 2bh(x)-1-1 ) + ( 2bh(x)-1-1 ) + 1 = 2^bh(x)-1。即節點x所包含的節點至少爲 2bh(x)-1。
所以,原命題成立。
由(01)、(02)得出,"高度爲h的紅黑樹,它的包含的內節點個數至少爲 2^bh(x)-1個"。
所以,「一棵含有n個節點的紅黑樹的高度至多爲2log(n+1)」。
摘要:https://blog.csdn.net/chen_zhang_yu/article/details/52415077