1. 程式人生 > >小橙書閱讀指南(九)——紅黑平衡樹(2)

小橙書閱讀指南(九)——紅黑平衡樹(2)

mage 檢查 旋轉 img his 基本 查找 兩種 1.2

從標準二叉樹的極端情況我們推導出2-3樹這樣的數據結構具備自平衡的特性,但是要實現這個特性在算法上相當復雜。考慮在大部分情況下,對於檢索的指數級時間消費O(lgN)要求並不嚴格。因此,我們會看到如何將一顆標準的2-3樹轉變成紅黑樹的過程。

一、局部變換

考慮如果在2-節點上掛新的鍵並不會破壞2-3樹的平衡結構。可是在3-節點上掛新的鍵,可能的變化卻多達6種。這個臨時的4-節點可能是根節點,可能是一個2-節點的左子節點或者右子節點,也可能是3-節點的左子節點、中子節點或者右子節點。2-3樹插入算法的根本在於這些變換都是局部的:除了相關的節點和鏈接之外不必修改該或者檢查樹的其他部分。因此,每次變換中,變更的鏈接數量都不會超過一個很小的常熟。

技術分享圖片

每一個變換都會將4-節點中的一個鍵送入它的父節點中,並重構相應的鏈接,但不必涉及樹的其他部分。這也是2-3樹的重要特性:一次聚聚變換不會影響樹的有序和平衡性:

技術分享圖片

二、紅黑樹與2-3樹的相互轉換

盡管2-3樹一種高效的結構並提供了自平衡特性,但是它的算法過於復雜以至於在一般的情況下我們並不願意使用這樣的結構作為首選方案。但是紅黑樹則不然,它的實現算法非常簡單,代碼量也不大。但理解整個紅黑樹的構造過程卻需要一番仔細的探究。

紅黑二叉查找樹背後的基本思想是用標準的二叉查找樹和一些額外信息來表示2-3樹。我們將樹中的鏈接分為兩種類型:紅連接將2個2-節點連接起來構成一個3-節點,黑鏈接則是2-3樹中的普通鏈接。

技術分享圖片

對於紅黑樹我們給出的定義如下:

1.紅連接均為左連接;

2.沒有任何一個節點同時和兩條紅連接相連;

3.該樹是完美黑色平衡的,即任意空節點到根節點的路徑上的黑色鏈接數量相等。

我們只需要將一顆紅黑樹中的紅連接畫平,那麽所有的空節點到根節點的距離都是相同的。如果我們將由紅連接項鏈的節點合並,得到的就是一顆2-3樹。

技術分享圖片

方便起見,因為每一個節點都只會由一條指向自己的鏈接,我們將鏈接的顏色泊岸村在表示節點的Node對象中,布爾變量color為true表示紅色,false為黑色。節點定義代碼如下:

class Node {
        private Key key;
        private
Value val; private Node left; private Node right; private boolean color; private int size; public Node(Key key, Value val, boolean color, int size) { this.key = key; this.val = val; this.color = color; this.size = size; } }

三、旋轉和顏色變化

對紅黑樹來說旋轉是它的基礎變化,在實現代碼前我們先思考一下為什麽需要旋轉。

技術分享圖片

向2-3樹的2-節點插入新的鍵是非常簡單的,無論這個鍵本身是E還是S,在插入新的鍵以後都一個樣子。但對於紅黑樹來說就不是這樣了,回想一下之前對紅黑樹的定義:紅連接均為左連接。如果要插入的新值小於節點我們可以直接插入,如果新值大於節點,我們就會創建一條紅色的右鏈接。因此我們就需要通過旋轉將右鏈接變成左連接。當然更復雜的情況下,我們還會通過旋轉把左連接變成右鏈接。也許到這裏有人會問:當插入的新鍵大於節點的時候,為什麽不可以直接插入一條黑色的右鏈接呢?在思考一下2-3樹的生長特性以及紅黑樹對平衡的定義:

1.2-3樹是區別於二叉樹,它是向上生長的。

2.紅黑樹中任一空節點到根節點的距離相同。

綜合起來就是,我們在紅黑樹中插入的新鍵都必須從紅鏈接開始,再通過變換來調整樹的高度以恢復平衡。

技術分享圖片

接下來我們再考慮一個問題,如果我們向紅黑樹插入了一條向左的紅鏈接(顯然此時並未破壞樹的平衡性,因此我們不必調整樹的結構)然後再向同一個節點插入了一條紅色的右鏈接怎麽辦?左鏈接已經被占據了,我們無法再通過旋轉調整平衡。

技術分享圖片

回想一下2-3樹在遇到這樣的情況是是如何變化的:我們先構造一個臨時的4-節點,再將它轉換成3個2-節點並把父節點向上轉移。那麽對於紅黑樹來說似乎就更簡單了一些。我們只需要調整兩條子鏈接為黑鏈接並把根鏈接變成紅連接即可。

技術分享圖片

你或許又會問了:如果父節點已經是紅色的怎麽辦呢?事實上你完全不用擔心這樣的情況發生,因為紅黑樹的另一條特性已經保證了:沒有任何一個節點同時和兩條紅連接相連。換言之,如果父節點(E)為紅色,當我們在插入(A)的時候已經不符合紅黑樹的定義,我們需要通過旋轉來恢復平衡。

總的來說,無論之前節點的情況如何,我們通過0次,1次或2次旋轉以及顏色的變化得到期望的結果。

技術分享圖片

小橙書閱讀指南(九)——紅黑平衡樹(2)