1. 程式人生 > >平衡二叉樹(AVL)

平衡二叉樹(AVL)

上一篇我們聊過,二叉查詢樹不是嚴格的O(logN),如果找到一種方法,使得二叉查詢樹不受輸入序列和插入結點等的影響,始終保持平衡狀態,從而達到很好的檢索效率.平衡二叉樹就是基於此目的而產生的.

定義:平衡二叉樹或為空樹,或為如下性質的二叉排序樹(平衡二叉樹是一種特殊的二叉排序樹):
(1)左右子樹深度之差的絕對值不超過1;
(2)左右子樹仍然為平衡二叉樹.
平衡因子BF=左子樹深度-右子樹深度.
平衡二叉樹每個結點的平衡因子只能是1,0,-1。若其絕對值超過1,則該二叉排序樹就是不平衡的。

如圖所示為平衡樹和非平衡樹示意圖:
這裡寫圖片描述

顯然,如果有n個結點,則他的高度為O(logN),因而在其上進行的各種操作,都只需要O(logN)的時間代價.但問題在於如何保持一顆avl樹的結構,使得對他的任何操作,都不改變他的平衡特性.實際上,主要是通過旋轉的區域性操作來調整使其保持平衡特性.

旋轉
左旋:
這裡寫圖片描述
對x進行左旋,意味著”將x變成一個左節點”。

右旋:
這裡寫圖片描述
對y進行右旋,意味著”將y變成一個右節點”。

結點再怎麼失衡都逃不過4種情況,下面我們來看一下怎麼對這4中情況進行對應的旋轉。
<1>.LL型平衡旋轉法 —- 右旋

這裡寫圖片描述
我們看到,在向樹中追加“節點1”的時候,根據定義我們知道這樣會導致了“節點3”失衡,可以這樣想,把這棵樹比作齒輪,我們在“節點5”處把齒輪往下拉一個位置,也就變成了後面這樣“平衡”的形式.

<2>.RR型平衡旋轉法 —- 左旋

這裡寫圖片描述
同樣,”節點5“滿足”RR型“,其實我們也看到,這兩種情況是一種映象,當然操作方式也大同小異,我們在”節點1“的地方將樹往下拉一位,最後也就形成了我們希望的平衡效果。

<3>.LR型平衡旋轉法 —- 左右旋

這裡寫圖片描述
從圖中我們可以看到,當我們插入”節點3“時,“節點5”處失衡,注意,找到”失衡點“是非常重要的,當面對”LR型“時,我們將失衡點的左子樹進行”RR型左旋轉”,然後進行”LL型右旋轉“,經過這樣兩次的旋轉就OK了,很有意思,對吧。

<4>.RL型平衡旋轉法 —- 右左旋

這裡寫圖片描述
這種情況和“情景3”也是一種映象關係,很簡單,我們找到了”節點15“是失衡點,然後我們將”節點15“的右子樹進行”LL型右旋轉“,然後進行”RR型左旋轉“,最終得到了我們滿意的平衡。

插入
如果我們理解了上面的這幾種旋轉,那麼新增方法簡直是輕而易舉,出現了哪一種情況呼叫哪一種旋轉方法而已。

刪除
同理,刪除也是.