1. 程式人生 > >【C語言】平衡二叉樹

【C語言】平衡二叉樹

avl 簡介 二叉搜索樹 沒有 TP 假設 它的 left 操作

AVL樹簡介

AVL樹的名字來源於它的發明作者G.M. Adelson-Velsky 和 E.M. Landis。AVL樹是最先發明的自平衡二叉查找樹(Self-Balancing Binary Search Tree,簡稱平衡二叉樹)。

平衡二叉樹定義(AVL):它或者是一顆空樹,或者具有以下性質的二叉排序樹:它的左子樹和右子樹的深度之差(平衡因子)的絕對值不超過1,且它的左子樹和右子樹都是一顆平衡二叉樹。

一棵AVL樹有如下必要條件:

• 條件一:它必須是二叉查找樹。

• 條件二:每個節點的左子樹和右子樹的高度差至多為1。

技術分享圖片

圖一中左邊二叉樹的節點45的左孩子46比45大,不滿足二叉搜索樹的條件,因此它也不是一棵平衡二叉樹。


右邊二叉樹滿足二叉搜索樹的條件,同時它滿足條件二,因此它是一棵平衡二叉樹。

技術分享圖片

左邊二叉樹的節點45左子樹高度2,右子樹高度0,左右子樹高度差為2-0=2,不滿足條件二;
右邊二叉樹的節點均滿足左右子樹高度差至多為1,同時它滿足二叉搜索樹的要求,因此它是一棵平衡二叉樹。

AVL樹的查找、插入、刪除操作在平均和最壞的情況下都是O(logn),這得益於它時刻維護著二叉樹的平衡。如果我們需要查找的集合本身沒有順序,在頻繁查找的同時也經常的插入和刪除,AVL樹是不錯的選擇。不平衡的二叉查找樹在查找時的效率是很低的,因此,AVL如何維護二叉樹的平衡是我們的學習重點。

AVL樹相關概念

1. 平衡因子:將二叉樹上節點的左子樹高度減去右子樹高度的值稱為該節點的平衡因子BF(Balance Factor)。
在圖二右邊的AVL樹上:
節點50的左子樹高度為3,右子樹高度為2,BF= 3-2 = 1;
節點45的左子樹高度為2,右子樹高度為1,BF= 2-1 = 1;
節點46的左子樹高度為0,右子樹高度為0,BF= 0-0 = 0;
節點65的左子樹高度為0,右子樹高度為1,BF= 0-1 = -1;
對於平衡二叉樹,BF的取值範圍為[-1,1]。如果發現某個節點的BF值不在此範圍,則需要對樹進行調整。

2. 最小不平衡子樹:距離插入節點最近的,且平衡因子的絕對值大於1的節點為根的子樹.。

技術分享圖片

在圖三中,左邊二叉樹的節點45的BF = 1,插入節點43後,節點45的BF = 2。節點45是距離插入點43最近的BF不在[-1,1]範圍內的節點,因此以節點45為根的子樹為最小不平衡子樹。

AVL樹失衡調整(LL型調整)

節點的插入或刪除都有可能導致AVL樹失去平衡,因此,失衡調整是插入與刪除操作的基礎。
AVL樹的失衡調整可以分為四種情況,我們逐一分析。
假設我們要為數組a[]={4,5,6,3,2,8,7,0,1}構建一棵AVL樹。

情況一:左單旋轉

首先插入{4,5,6},在插入元素6後出現不平衡的情況:

技術分享圖片

當我們在右子樹插入右孩子導致AVL失衡時,我們需要進行單左旋調整。旋轉圍繞最小失衡子樹的根節點進行。
在刪除新節點時也有可能會出現需要單左旋的情況。
左旋代碼如下:

情況二:右單旋轉

我們繼續插入元素{3,2},此時二叉樹為:

技術分享圖片

插入3、2後出現了不平衡的情況。此時的插入情況是“在左子樹上插入左孩子導致AVL樹失衡”,我們需要進行單右旋調整。
單右旋代碼為:

【C語言】平衡二叉樹