首先附上本文節選地址:http://www.cnblogs.com/huangxincheng/archive/2012/07/22/2603956.html
二叉查找樹不是嚴格的O(logN),導致了在真實場景中沒有用武之地,誰也不願意有O(N)的情況發生,作為一名碼農,肯定會希望能把“范圍查找”做到地球人都不能優化的地步。 當有很多數據灌到我的樹中時,我肯定會希望最好是以“完全二叉樹”的形式展現,這樣我才能做到“查找”是嚴格的O(logN),比如把這種”樹“調正到如下結構。
這里就涉及到了“樹節點”的旋轉,也是我們今天要聊到的內容。
一:平衡二叉樹(AVL)
1:定義
1、父節點的左子樹和右子樹的高度之差不能大於1,也就是說不能高過1層,否則該樹就失衡了,此時就要旋轉節點,在
編碼時,我們可以記錄當前節點的高度,比如空節點是-1,葉子節點是0,非葉子節點的height往根節點遞增,比如在下圖
中我們認為樹的高度為h=2。
2、它的左子樹和右子樹都是平衡二叉樹。
2:旋轉
節點再怎么失衡都逃不過4種情況,下面我們一一來看一下。
① 左左情況(左子樹的左邊節點)
我們看到,在向樹中追加“節點1”的時候,根據定義我們知道這樣會導致了“節點3"失衡,滿足“左左情況“,可以這樣想,把這
棵樹比作齒輪,我們在“節點5”處把齒輪往下拉一個位置,也就變成了后面這樣“平衡”的形式,如果用動畫解釋就最好理解了。
② 右右情況(右子樹的右邊節點)
同樣,”節點5“滿足”右右情況“,其實我們也看到,這兩種情況是一種鏡像,當然操作方式也大同小異,我們在”節點1“的地方
將樹往下拉一位,最后也就形成了我們希望的平衡效果。
③左右情況(左子樹的右邊節點)
從圖中我們可以看到,當我們插入”節點3“時,“節點5”處失衡,注意,找到”失衡點“是非常重要的,當面對”左右情況“時,我們將
失衡點的左子樹進行"右右情況旋轉",然后進行”左左情況旋轉“,經過這樣兩次的旋轉就OK了,很有意思,對吧。
④右左情況(右子樹的左邊節點)
這種情況和“情景3”也是一種鏡像關系,很簡單,我們找到了”節點15“是失衡點,然后我們將”節點15“的右子樹進行”左左情況旋轉“,
然后進行”右右情況旋轉“,最終得到了我們滿意的平衡。