1. 程式人生 > >紅黑樹(2)保持平衡的根本套路

紅黑樹(2)保持平衡的根本套路

有了解過的同學們應該都知道,紅黑樹為了保持平衡,有三個基本的操作:左旋、右旋和著色。(不知道的同學也沒關係 ,因為在此我只想告訴你們的是這三個操作都是為了什麼)

首先要有這樣一個意識:要棵紅黑樹在你插入新節點之前就是平衡的(不理解紅黑樹平衡的可看上一節),我們要做的是使新節點插入後也平衡。

比如當只有一個根節點時,它是平衡的,當你再插入一個節點時,無論是放左邊還是右邊,都會使原來的平衡破壞。為了保持平衡我們觀察發現根節點相關聯的節點為空(也就是它關聯的左節點有右節點都沒有),那麼我們可以將新插入節點標紅,表示將其插入到與根節點同一層,沒有產生新層,至此保持平衡。

所以,要記住一句話,紅黑樹在新節點插入前,總是平衡的,新節點的插入總是產生新層,破壞平衡。

現在回到正題,左旋、右旋和著色三個操作有什麼用。大的來說,就是修復產生新層這個平衡。如何保持呢:

著色(將黑色變為紅色):

這個的用意上面舉例就有提到,當一個新節點由黑變紅的時候,說明它所在的層減少(上升)了一層。因為新增節點總是產生新層,減少產生的這個新層是修復平衡的一個方法。

左旋:

左旋是指目標節點與父節點為右支關係時,將目標節點上升到父節點的位置,父節點變為目標節點的左節點,目標節點的左分支變為原父節點的右分支。這麼做的目的也是為了讓目標節點上升一層。

右旋:

與左旋相反的操作。目的也一樣。

新增總體思路是:

我們新增一個節點後,如果其父節點還沒滿三個(左右節點都為紅表示滿 了),並且空位在新增節點這邊,那麼變色即可完成修改。

如果新加節點的父節是紅色,說明沒空位了。那麼就得拆分,將紅節點變黑。這時會發現又新增了一層,於就通過父節點的左旋或右旋,將父節點上升一層。於是又變回只新增一層,又可以重新按思路走下去。

如果新增節點沒有空位讓其補進去,會如此一直旋轉變色下去,最後到達根節點處。或是左旋或是右旋,根節點會變為原來子節點的子節點,子節點上升為根節點,到此,層數增長。由此也可以知道,層數增長總是發生在根處。