1. 程式人生 > >AVL樹的旋轉圖解和簡單實現

AVL樹的旋轉圖解和簡單實現

平衡條件
一個最理想的平衡條件是左右兩個子樹的高度完全相等,但只有節點數量為2^n-1的樹才滿足這個條件(n是層數,2層要3個,3層要7個)。這個條件太嚴格,不好用。

如果只要求根節點平衡的話,上面的條件可能會容易實現一點,但是會出現下面這樣壞的二叉樹: 


因此一顆AVL樹的條件是,對於每個節點來說,這個節點的左右子樹的高度最多差1.

簡單示例
AVL樹: 

這裡寫圖片描述
非AVL二叉樹: 


這裡寫圖片描述
旋轉
在每一次插入數值之後,樹的平衡性都可能被破壞,這時可以通過一個簡單的操作來矯正平衡–旋轉。

旋轉的目的就是減少高度,通過降低整棵樹的高度來平衡。哪邊的樹高,就把那邊的樹向上旋轉。

通過旋轉可以降低高度。

所謂的左旋和右旋都是以子樹為原點的:如b是a的子樹,那麼旋轉就圍繞b來進行。
如果b是a的左子樹,那麼就圍繞b將a向右旋轉,看著就像是a直接掉下來了,掉成了b的右子樹。
如果b是a的右子樹,那麼就圍繞b將a向左旋轉,看著就像是a直接掉下來了,掉成了b的左子樹。
插入節點時分四種情況,四種情況對應的旋轉方法是不同的:

例如對於被破壞平衡的節點 a 來說:

插入方式    描述    旋轉方式
LL    在a的左子樹根節點的左子樹上插入節點而破壞平衡    右旋轉
RR    在a的右子樹根節點的右子樹上插入節點而破壞平衡    左旋轉
LR    在a的左子樹根節點的右子樹上插入節點而破壞平衡    先左旋後右旋
RL    在a的右子樹根節點的左子樹上插入節點而破壞平衡    先右旋後左旋
1.LL 右旋轉
就拿最簡單的舉例了。

一個簡單的AVL樹: 

這裡寫圖片描述

這時是平衡的,如果在插入一

這時是平衡的,如果在插入一個元素3,就會變成下面這樣,破壞平衡: 

這裡寫圖片描述
被破壞了平衡首先要找到是哪個樹被破壞了平衡,然後調整這個樹。然後繼續往上一個一個的調整。

既然是被新插入的節點3破壞的,那麼不平衡的樹一定在從新插入的節點3到根節點8的路徑上。找離新插入的節點最近的不平衡的樹進行調整,上圖中就是7.

節點7的左子樹 高度為1,右子樹為空,高度為-1 ,不平衡。根據表格要進行右旋轉。

先把7這顆不平衡的樹挑出來: 

這裡寫圖片描述
這棵樹是最近的不平衡的樹,7的左子樹5高度為1,右子樹為空,所以右子樹高度是-1.兩者的高度差達到了2,超過了1.

因為左子樹5的高度更高,所以要把左子樹5向上提一下,這時旋轉就很明顯了,抓著5向上一提,7就掉到5的右邊了,成了5的右子樹。

這個過程就是右旋: 

這裡寫圖片描述
這時繼續往上找,發現每個節點都符合了平衡條件,所以整棵樹就變成了AVL樹。

那如果節點5本來就有了右子樹呢?照樣右旋轉,只要把原來5的右子樹變成旋轉後的7的左子樹就行了。因為5的右子樹肯定比5大,但是也肯定比7小的: 

這裡寫圖片描述
其實上面最後旋轉成的樹是下面這樣的: 

這裡寫圖片描述
這棵樹的根節點是不平衡的,還需要使用後面的雙旋轉來調整。

使用LR先左旋後右旋調整後是這樣的,具體方法看後面的: 

這裡寫圖片描述
2. RR 左旋轉
在右子樹的右子樹上插入節點破壞的平衡需要左旋轉來矯正。

左旋轉和右旋轉類似,都是單旋轉,給個流程圖。 

這裡寫圖片描述
3. LR 先左旋再右旋
如果在第一個例子中插入的不是3,而是6,就成了下面的樣子,依然說破壞了平衡 

這裡寫圖片描述
被破壞平衡的樹依然是7,但是這次就不能通過一次旋轉解決了,咋轉都不行。

要從6開始到7進行先左旋再右旋才可以矯正平衡: 


這裡寫圖片描述
4. RL 先右旋再左旋
當破壞平衡的節點是這個樹的右子樹的左子樹時,要進行先右旋轉再左旋轉來矯正。

同樣是從破壞平衡的那個節點開始旋轉,先右旋轉後左旋轉: 


這裡寫圖片描述

--------------------- 
作者:喵了個嗚s 
來源:CSDN 
原文:https://blog.csdn.net/qq_25806863/article/details/74755131 
版權宣告:本文為博主原創文章,轉載請附上博文連結!