二叉搜尋樹的平衡--AVL樹和樹的旋轉(圖解)

來源:互聯網
上載者:User

二叉搜尋樹的平衡--AVL樹和樹的旋轉(圖解)

二叉搜尋樹只有保持平衡時其尋找效率才會高。

要保持二叉搜尋樹的平衡不是一件易事。不過還是有一些非常經典的辦法可以做到,其中最好的方法就是將二叉搜尋樹實現為AVL樹。

AVL樹得名於它的發明者 G.M. Adelson-Velsky 和 E.M. Landis,他們在 1962 年的論文 "An algorithm for the organization of information" 中發表了它。AVL樹是一種特殊類型的二叉樹,它的每個結點都儲存一份額外的資訊:結點的平衡因子。

結點的平衡因子 = 左子樹的高度 - 右子樹的高度

插入和刪除操作都會導致AVL樹的自我調整(自我平衡),使得所有結點的平衡因子保持為+1、-1或0。

當子樹的根結點的平衡因子為+1時,它是左傾斜的(left-heavy)。

當子樹的根結點的平衡因子為 -1時,它是右傾斜的(right-heavy)。

一顆子樹的根結點的平衡因子就代表該子樹的平衡性。

保持所有子樹幾乎都處於平衡狀態,AVL樹在總體上就能夠基本保持平衡。

 

AVL樹的基本尋找、插入結點的操作和二叉樹的操作一樣。但是,當向AVL樹中插入一個結點後,還有一些額外的工作要做。首先,必須計算因插入操作對平衡因子帶來的改變。其次,如果任何平衡因子變成了+/-2,就必須從這個結點開始往下重新平衡這顆樹,這個重新平衡的過程就稱為旋轉。

AVL樹的旋轉

旋轉操作用來重新平衡樹的某個部分。通過重新安排結點 ,使結點之間的關係始終保持左子結點小於父結點,父結點小於右子結點。使得該樹仍然是一顆二叉搜尋樹。旋轉過後,旋轉子樹中的所有結點的平衡因子都為+1、-1或0。

AVL樹的旋轉類型有4種, 分別是LL(left-left)旋轉、LR(left-right)旋轉、RR(right-right)旋轉和RL(right-left)旋轉。

為方便理解在何時執行哪一種旋轉,設x代表剛插入AVL樹中的結點,設A為離x最近且平衡因子更改為2的絕對值的祖先。可以歸納為下面4種處理情況:

LL旋轉

如所示,當x位於A的左子樹的左子樹上時,執行LL旋轉。

設left為A的左子樹,要執行LL旋轉,將A的左指標指向left的右子結點,left的右指標指向A,將原來指向A的指標指向left。

旋轉過後,將A和left的平衡因子都改為0。所有其他結點的平衡因子沒有發生變化。

 LR旋轉

當x位於A的左子樹的右子樹上時,執行LR旋轉。

設left是A的左子結點,並設A的子孫結點grandchild為left的右子結點。

要執行LR旋轉,將left的右子結點指向grandchild的左子結點,grandchild的左子結點指向left,A的左子結點指向grandchild的右子結點,再將grandchild的右子結點指向A,最後將原來指向A的指標指向grandchild。

執行LR旋轉之後,調整結點的平衡因子取決於旋轉前grandchild結點的原平衡因子值。

如果grandchild結點的原始平衡因子為+1,就將A的平衡因子設為-1,將left的平衡因子設為0。

如果grandchild結點的原始平衡因子為0,就將A和left的平衡因子都設定為0。

如果grandchild結點的原始平衡因子為-1,就將A的平衡因子設定為0,將left的平衡因子設定為+1。

在所有的情況下,grandchild的新平衡因子都是0。所有其他結點的平衡因子都沒有改變。

 

RR旋轉

當x位於A的左子樹的右子樹上時,執行RR旋轉。

RR旋轉與LL旋轉是對稱的關係。

設A的右子結點為Right。要執行RR旋轉,將A的右指標指向right的左子結點,right的左指標指向A,原來指向A的指標修改為指向right。

完成旋轉以後,將A和left的平衡因子都修改為0。所有其他結點的平衡因子都沒有改變。

RL旋轉

當x位於A的右子樹的左子樹上時,執行RL旋轉。

 RL旋轉與LR旋轉是對稱的關係。

設A的右子結點為right,right的左子結點為grandchild。要執行RL旋轉,將right結點的左子結點指向grandchild的右子結點,將grandchild的右子結點指向right,將A的右子結點指向grandchild的左子結點,將grandchild的左子結點指向A,最後將原來指向A的指標指向grandchild。

執行RL旋轉以後,調整結點的平衡因子取決於旋轉前grandchild結點的原平衡因子。這裡也有三種情況需要考慮:

如果grandchild的原始平衡因子值為+1,將A的平衡因子更新為0,right的更新為-1;

如果grandchild的原始平衡因子值為  0,將A和right的平衡因子都更新為0;

如果grandchild的原始平衡因子值為-1,將A的平衡因子更新為+1,right的更新為0;

在所有情況中,都將grandchild的新平衡因子設定為0。所有其他結點的平衡因子不發生改變。

本文永久更新連結地址:https://www.bkjia.com/Linux/2018-03/151314.htm

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.