AVL平衡二叉樹的各種問題(Balanced Binary Tree)
阿新 • • 發佈:2018-12-08
AVL樹或者是一棵空樹,或者是具有以下性質的非空二叉搜尋樹:
1. 任一結點的左、右子樹均為AVL樹;
2.根結點左、右子樹高度差的絕對值不超過1.
1.宣告
#include<iostream> #include<cstdio> #include<queue> using namespace std; typedef int ElementType; typedef struct AVLNode * AVLTree; //AVL樹型別 struct AVLNode{ ElementType Data;View Code//結點資料 AVLTree Left; //左子樹 AVLTree Right; //右子樹 int Height; //樹高 };
2.獲取高度
int GetHeight(AVLTree T){ if(T) return max(GetHeight(T->Left ),GetHeight(T->Right )) + 1; else return 0; }View Code
3.左單旋LL
AVLTree SingleLeftRotation(AVLTree A){View Code// 注意:A 必須有一個左子結點 B // 將 A 與 B 左單選,更新 A 與 B 的高度,返回新的根結點 B AVLTree B = A->Left ; A->Left = B->Right ; B->Right = A; A->Height = max(GetHeight(A->Left ), GetHeight(A->Right )) + 1; B->Height = max(GetHeight(B->Left ),A->Height ) + 1; return B; }
4.右單旋RR
AVLTree SingleRightRotation(AVLTree A){ AVLTree B = A->Right ; A->Right = B->Left ; B->Left = A; A->Height = max(GetHeight(A->Left ), GetHeight(A->Right )) + 1; B->Height = max(GetHeight(B->Right ),A->Height ) + 1; return B; }View Code
5.左-右雙旋LR
AVLTree DoubleLeftRightRotation(AVLTree A){ // 注意:A必須有一個左子結點 B,且 B必須有一個右子結點 C // 將 A、B 與 C 做兩次單旋,返回新的根結點 C //將 B 與 C 做右單旋,C被返回 A->Left = SingleRightRotation(A->Left ); //將 A 與 C 做左單旋,C被返回 return SingleLeftRotation(A); }View Code
6.右-左雙旋RL
AVLTree DoubleRightLeftRotation(AVLTree A){ A->Right = SingleLeftRotation(A->Right ); return SingleRightRotation(A); }View Code
7.AVL樹的插入
AVLTree Insert(AVLTree T, ElementType X){ //將 X 插入AVL樹 T 中,並且返回調整後的AVL樹 if(! T){ //若插入空樹,則新建包含一個結點的樹 T = (AVLTree)malloc(sizeof(struct AVLNode)); T->Data = X; T->Height = 1; T->Left = T->Right = NULL; } else if(X < T->Data ){ // 插入 T 的左子樹 T->Left =Insert(T->Left , X); // 如果需要左旋 if(GetHeight(T->Left ) - GetHeight(T->Right )== 2) if(X <T->Left ->Data) T = SingleLeftRotation(T); //左單旋 else T = DoubleLeftRightRotation(T); //左-右雙旋 } else if(X > T->Data ){ // 插入 T 的右子樹 T->Right = Insert(T->Right , X); // 如果需要右旋 if(GetHeight(T->Left ) - GetHeight(T->Right )== -2) if(X > T->Right ->Data) T = SingleRightRotation(T); //右單選 else T = DoubleRightLeftRotation(T); //右-左雙旋 } // else X==T->Data 無需插入 //更新樹高 T->Height = max(GetHeight(T->Left ),GetHeight(T->Right )) + 1; return T; }View Code
完整測試:
#include<iostream> #include<cstdio> #include<queue> using namespace std; typedef int ElementType; typedef struct AVLNode * AVLTree; struct AVLNode{ ElementType Data; AVLTree Left; AVLTree Right; int Height; }; int GetHeight(AVLTree T){ if(T) return max(GetHeight(T->Left ),GetHeight(T->Right )) + 1; else return 0; } AVLTree SingleLeftRotation(AVLTree A){ AVLTree B = A->Left ; A->Left = B->Right ; B->Right = A; A->Height = max(GetHeight(A->Left ), GetHeight(A->Right )) + 1; B->Height = max(GetHeight(B->Left ),A->Height ) + 1; return B; } AVLTree SingleRightRotation(AVLTree A){ AVLTree B = A->Right ; A->Right = B->Left ; B->Left = A; A->Height = max(GetHeight(A->Left ), GetHeight(A->Right )) + 1; B->Height = max(GetHeight(B->Right ),A->Height ) + 1; return B; } AVLTree DoubleLeftRightRotation(AVLTree A){ A->Left = SingleRightRotation(A->Left ); return SingleLeftRotation(A); } AVLTree DoubleRightLeftRotation(AVLTree A){ A->Right = SingleLeftRotation(A->Right ); return SingleRightRotation(A); } AVLTree Insert(AVLTree T, ElementType X){ if(! T){ T = (AVLTree)malloc(sizeof(struct AVLNode)); T->Data = X; T->Height = 1; T->Left = T->Right = NULL; } else if(X < T->Data ){ T->Left =Insert(T->Left , X); if(GetHeight(T->Left ) - GetHeight(T->Right )== 2) if(X <T->Left ->Data) T = SingleLeftRotation(T); else T = DoubleLeftRightRotation(T); } else if(X > T->Data ){ T->Right = Insert(T->Right , X); if(GetHeight(T->Left ) - GetHeight(T->Right )== -2) if(X > T->Right ->Data) T = SingleRightRotation(T); else T = DoubleRightLeftRotation(T); } T->Height = max(GetHeight(T->Left ),GetHeight(T->Right )) + 1; return T; } void LevelorderTravelsal(AVLTree BT){ queue<AVLTree> q; AVLTree T; if(!BT) return; q.push(BT); while(!q.empty()){ T=q.front(); q.pop(); cout<<T->Data <<" "; if(T->Left ) q.push(T->Left ); if(T->Right ) q.push(T->Right ); } } int main(){ int n; cin>>n; AVLTree T = NULL; for(int i=0;i<n;i++){ int x; cin>>x; T = Insert(T, x); } LevelorderTravelsal(T); }View Code