1. 程式人生 > >紅黑樹(1)真的只說原理

紅黑樹(1)真的只說原理

樹可以分為兩大類:平衡的樹和不平衡的樹。

那些都有自己大名的自然就是平衡的樹。我們使用樹這結構就是看中它插刪與搜尋擁有同等的高效 O(log n)。

平衡樹的特點就是每層都幾乎佈滿,不會出現某一分支特別長的情況。因為樹的查詢跟層數有關,層數越大越耗時間。如果有10個節點就有10層,那就跟連結串列一樣了。

現在要學習的這個“紅黑樹”就是其中平衡樹的一種。

接下來展開想像力:

前提所有的葉子節點都在同一層上

如果每個節點只能放一個值,那麼肯定存在不在同一層的時候,比如四個值的時候(2個的那個就不說了)。根佔了一個,要麼左邊2右邊1,要麼右邊2左邊1.

既然放1個不行,那就放2個、3個嘛。

紅黑樹的原來就是這樣,某“節點”可以放多個(紅黑樹中最多可以有3個值)。

原理是這樣,但我們看多種語言中無論是Java 還是C++它們都是一個節點都存一個值。為什麼呢。因為我們畫圖上看很清晰明瞭,但實際實現的時候會碰到多種問題。最直接能想到的就是資源浪費。每個節點最多能放三個值,那麼初始時肯定是留三個位置的。如果最後每個節點只有一個值,那虧的是用的2倍。當然還有其他的原因。由此來看,如果沒想到其他辦法,每個節點存一個值是最經濟也最簡單明瞭的。那麼我如果約束一個樹平衡呢(要像每個節點可放多值一樣約束)。

我們“物理”上不可能,可以在邏輯上實現嘛。

我們把本該放於同一節點的值,轉換成父子節點的關係,但是我規定”這個“子節點是和“這個“父節點是一起的。有什麼標誌呢?

”紅“和”黑“啊(你想叫”玫瑰金“和”孔雀藍“也是可以的)

到這裡大家應該明白了為什麼會有紅黑這兩東西了吧。

由此大家應該明白了很多大家看”紅黑樹原理及演算法“之中的規定為什麼要這麼規定了吧。比如:

1.每個節點為紅或者為黑

 :     (這不廢話嘛)其實也不算廢話,只少知道不會有藍色(哈哈)。但我相信大部分文件是不會告訴你為什麼要這麼分。完整看完上面碼字的相信已經知道為什麼會有紅黑的區別了。

2.如果一個節點是紅色的,則它的子節點必須是黑色的(或類似這種描述)

:前面我們說了紅黑樹的原理是一個”節點“中最多可放3個值而不是4個,卻沒說為什麼(當然要問為什麼)。因為二叉樹的一個節點最多會有兩個分支的,那麼如果這兩個分支的節點都是紅的話那麼就表示這”三父子“都是在一個”節點“的。當然最多也就三個,秉著物盡其用的原則,當然就3個了。有人會說4個也可以啊,拿子節點的子節點來標紅。那我就想說這兩個子節點的子節點總共有4個,你是想哪一個標紅呢。再往下說下去就越說越複雜了,在此打住,3個是比較明瞭的啦。其實該問題的人話就是“不能有兩個連續紅包的節點”。就是因為父節點佔了中間位置,左邊只有一個空位了(右邊有另一個,那是留給右邊的),所以只有一個能標紅的,連續兩個那是破壞規矩的了。

3.從一個節點到該節點的子孫節點的所有路徑上包含相同數目的黑節點

:這就是紅黑樹的一個特性。什麼叫特性呢,就是你睜開眼看上去能總結出來的規律。這沒啥好說的,因為真正的層數是黑色說的算(紅色就是黑色的一個附屬品),我們是號稱“所有葉子都在同一層的平衡樹”嘛,那每一條線的黑包當然要相同啦,不同你平衡個屁啊。

......

其實只要瞭解紅黑樹的“真實身份”,我們是不要記那麼多規定,那麼多特性的。