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

【轉】平衡二叉樹(AVL)

平衡二叉樹的定義 (AVL—— 發明者為Adel'son-Vel'skii 和 Landis)

平衡二叉查詢樹(AVL樹),具備二叉查詢樹的特點外,還具有一個重要特點: 它的左子樹和右子樹都是平衡二叉樹,並且左子樹和右子樹的平衡因子不超過1 (也就是每個節點的平衡因子只能是1,0,-1)

什麼是平衡因子?

節點的左子樹和右子樹高度(深度)的差值

平衡二叉樹是如何在插入資料的時候保持平衡的

當插入一個結點的時候,先檢查是否因為插入結點而破壞了平衡,若破壞,找出其中的最小不平衡二叉樹,調整最小不平衡二叉樹,達到平衡。 最小不平衡二叉樹指的是離插入結點最近並且平衡因子的絕對值大於1的結點為根的子樹。

平衡二叉樹的操作

查詢操作

       平衡二叉樹的查詢基本與二叉查詢樹相同。

插入操作

       在平衡二叉樹中插入結點與二叉查詢樹最大的不同在於要隨時保證插入後整棵二叉樹是平衡的。那麼調整不平衡樹的基本方法就是: 旋轉 。 下面我們歸納一下平衡旋轉的4中情況

1> 繞某元素左旋

         

從圖上看,以結點80和結點90為槓桿,左旋

插入結點100後,結點80的平衡因子改變為-2,也就是當結點的平衡因子變為-2,需要按照結點左旋

當樹中節點X的右孩子的右孩子上插入新元素,且平衡因子從-1變成-2後,就需要繞節點X進行左旋

2> 繞某元素右旋

從圖上看,是結點100和結點85為槓桿,右旋

插入結點80後,結點100的平衡因子改變為2,當結點的平衡因子改變為2時候,進行右旋操作

當樹中節點X的左孩子的左孩子上插入新元素,且平衡因子從1變成2後,就需要繞節點X進行右旋

3> 按照某元素的左子結點左旋轉,在按照元素自己右旋轉

當結點X的左孩子Y的右孩子插入新元素,平衡因子由1變為2,需按照Y左旋轉,在按照X結點右旋轉

4> 按照某元素的右子結點旋轉,在按照元素自身左旋轉

當結點X的右孩子Y的左孩子插入結點,X的平衡因子由-1變為-2,需要按照Y結點右旋轉,再按照X結點自身左旋

平衡二叉樹效能分析

平衡二叉樹的效能優勢:

      很顯然,平衡二叉樹的優勢在於不會出現普通二叉查詢樹的最差情況。其查詢的時間複雜度為O(logN)。

平衡二叉樹的缺陷:

      (1) 很遺憾的是,為了保證高度平衡,動態插入和刪除的代價也隨之增加。因此,我們在下一專題中講講《紅黑樹》 這種更加高效的查詢結構。

      (2) 所有二叉查詢樹結構的查詢代價都與樹高是緊密相關的,能否通過減少樹高來進一步降低查詢代價呢。我們可以通過多路查詢樹的結構來做到這一點,在後面專題中我們將通過《多路查詢樹/B-樹/B+樹 》來介紹。

      (3) 在大資料量查詢環境下(比如說系統磁盤裡的檔案目錄,資料庫中的記錄查詢 等),所有的二叉查詢樹結構(BST、AVL、RBT)都不合適。如此大規模的資料量(幾G資料),全部組織成平衡二叉樹放在記憶體中是不可能做到的。那麼把這棵樹放在磁碟中吧。問題就來了:假如構造的平衡二叉樹深度有1W層。那麼從根節點出發到葉子節點很可能就需要1W次的硬碟IO讀寫。大家都知道,硬碟的機械部件讀寫資料的速度遠遠趕不上純電子媒體的記憶體。 查詢效率在IO讀寫過程中將會付出巨大的代價。在大規模資料查詢這樣一個實際應用背景下,平衡二叉樹的效率就很成問題了。對這一問題的解決:我們也會在《多路查詢樹/B-樹/B+樹 》 將詳細分析。

      上面提到的紅黑樹和多路查詢樹都是屬於深度有界查詢樹(depth-bounded tree —DBT)

轉載:http://hxraid.iteye.com/blog/609949