二叉搜索樹只有保持平衡時其查找效率纔會高。spa
要保持二叉搜索樹的平衡不是一件易事。不過仍是有一些很是經典的辦法能夠作到,其中最好的方法就是將二叉搜索樹實現爲AVL樹。指針
AVL樹得名於它的發明者 G.M. Adelson-Velsky 和 E.M. Landis,他們在 1962 年的論文 "An algorithm for the organization of information" 中發表了它。AVL樹是一種特殊類型的二叉樹,它的每一個結點都保存一份額外的信息:結點的平衡因子。orm
結點的平衡因子 = 左子樹的高度 - 右子樹的高度blog
插入和刪除操做都會致使AVL樹的自我調整(自我平衡),使得全部結點的平衡因子保持爲+一、-1或0。it
當子樹的根結點的平衡因子爲+1時,它是左傾斜的(left-heavy)。io
當子樹的根結點的平衡因子爲 -1時,它是右傾斜的(right-heavy)。form
一顆子樹的根結點的平衡因子就表明該子樹的平衡性。效率
保持全部子樹幾乎都處於平衡狀態,AVL樹在整體上就可以基本保持平衡。二叉樹
AVL樹的基本查找、插入結點的操做和二叉樹的操做同樣。可是,當向AVL樹中插入一個結點後,還有一些額外的工做要作。首先,必須計算因插入操做對平衡因子帶來的改變。其次,若是任何平衡因子變成了+/-2,就必須從這個結點開始往下從新平衡這顆樹,這個從新平衡的過程就稱爲旋轉。搜索
旋轉操做用來從新平衡樹的某個部分。經過從新安排結點 ,使結點之間的關係始終保持左子結點小於父結點,父結點小於右子結點。使得該樹仍然是一顆二叉搜索樹。旋轉事後,旋轉子樹中的全部結點的平衡因子都爲+一、-1或0。
AVL樹的旋轉類型有4種, 分別是LL(left-left)旋轉、LR(left-right)旋轉、RR(right-right)旋轉和RL(right-left)旋轉。
爲方便理解在什麼時候執行哪種旋轉,設x表明剛插入AVL樹中的結點,設A爲離x最近且平衡因子更改成2的絕對值的祖先。能夠概括爲下面4種處理狀況:
以下圖所示,當x位於A的左子樹的左子樹上時,執行LL旋轉。
設left爲A的左子樹,要執行LL旋轉,將A的左指針指向left的右子結點,left的右指針指向A,將原來指向A的指針指向left。
旋轉事後,將A和left的平衡因子都改成0。全部其餘結點的平衡因子沒有發生變化。
當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。全部其餘結點的平衡因子不發生改變。