目錄
一、平衡二叉樹的定義
平衡二叉樹,簡稱平衡樹(AVL樹)——樹上任一結點的左子樹和右子樹的高度之差不超過1。
結點的平衡因子=左子樹高-右子樹高。
typedef struct AVLNode{
int key;
int balance;
struct AVLNode *lchild,*rchild;
}AVLNode,*AVLTree;
二、平衡二叉樹的插入
思考:在二叉排序樹中插入新結點後,如何保持平衡?
注:每次調整的對象都是“最小不平衡子樹”
三、調整最小不平衡子樹A
四種情況:
①LL——在A的左孩子的左子樹中插入導致不平衡
②RR——在A的右孩子的右子樹中插入導致不平衡
③LR——在A的左孩子的右子樹中插入導致不平衡
④RL——在A的右孩子的左子樹中插入導致不平衡
四、調整最小不平衡子樹(LL)
目標:1.恢復平衡;2.保持二叉排序樹特性
二叉排序樹的特性:左子樹結點值<根節點值<右子樹結點值
BL<B<BR<A<AR
LL平衡旋轉(右單旋轉)。由於在結點A的左孩子(L)的左子樹(L)上插入了新結點,A的平衡因子由1增至2,導致以A爲根的子樹失去平衡,需要一次向右的旋轉操作。將A的左子樹B向右上旋轉代替A稱爲根節點,將A結點向右下旋轉稱爲B的右子樹的根結點,而B的原右子樹則作爲A結點的左子樹。
五、調整最小不平衡子樹(RR)
二叉排序樹的特性:左子樹結點值<根節點值<右子樹結點值
AL<A<BL<B<BR
RR平衡旋轉(左單旋轉)。由於在結點A的右孩子(R)的右子樹(R)上插入了新結點,A的平衡因子由-1減至-2,導致以A爲根的子樹失去平衡,需要一次向左的旋轉操作,將A的右孩子B向左上旋轉代替A稱爲根結點,將A結點向左下旋轉稱爲B的左子樹的根結點,而B的原左子樹則作爲A結點的右子樹
代碼思路
實現f向右下旋轉,p向右上旋轉:
其中f是爹,p爲左孩子,g爲f他爹
①f->lchild = p->rchild;
②p->rchild = f;
③gf->lchild/rchild = p;
BL<B<BR<A<AR
實現f向左下旋轉,p向左手旋轉:
其中f是爹,p爲右孩子,gf爲f他爹
①f->rchild = p->lchild;
②p->lchild = f;
③gf->lchild/rchild = p;
AL<A<BL<B<BR
七、調整最小平衡子樹(LR)
LR平衡旋轉(先左後右雙旋轉)。由於在A的左孩子(L)的右子樹(R)上插入新結點,A的平衡因子由1增至2,導致以A爲根的子樹失去平衡,需要進行兩次旋轉操作,先左旋轉後又旋轉。先將A結點的左孩子B的右子樹的根結點C向左上旋轉提升到B結點的位置,然後再把該C結點向右上旋轉提升到A結點的位置
BL<B<CL<C<CR<A<AR
兩種情況:
①
②
八、調整最小不平衡子樹(RL)
RL平衡旋轉(先右後左雙旋轉)。由於在A的右孩子(R)的左子樹(L)上插入新結點,A的平衡因子由-1減至-2,導致以A爲根的子樹失去平衡,需要進行兩次旋轉操作,先右旋轉後左旋轉。先將A結點的右孩子B的左子樹的根節點C向右上旋轉提升到B結點的位置,然後再把該C結點向左上旋轉提升到A結點的位置
兩種情況:
①
②
九、調整最小不平衡子樹
總結:只有左孩子才能右上旋轉,只有右孩子才能左上旋轉
插入操作導致“最小不平衡子樹”高度+1,經過調整後高度恢復
十、練習
1.RR型
2.RL型
3.LR型
十、查找效率分析
若樹高爲h,則最壞情況下,查找一個關鍵字最多需要對比h次,即查找操作的時間複雜度不可能超過O(h)