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
版權宣告:本文為博主原創文章,轉載請附上博文連結!