PTA 5-6 Root of AVL Tree (25) - 树 - 平衡二叉树
题目:http://pta.patest.cn/pta/test/16/exam/4/question/668
PTA - Data Structures and Algorithms (English) - 5-6
An AVL tree is a self-balancing binary search tree. In an AVL tree, the heights of the two child subtrees of any node differ by at most one; if at any time they differ by more than one, rebalancing is done to restore this property. Figures 1-4 illustrate the rotation rules.
LL:RR:
RL:
LR:
Now given a sequence of insertions, you are supposed to tell the root of the resulting AVL tree.
Input Specification:
Each input file contains one test case. For each case, the first line contains a positive integer N (≤20) which is the total number of keys to be inserted. Then N distinct integer keys are given in the next line. All the numbers in a line are separated by a space.
Output Specification:
For each test case, print the root of the resulting AVL tree in one line.
Sample Input 1:
5
88 70 61 96 120
Sample Output 1:
70
Sample Input 2:
7
88 70 61 96 120 90 65
Sample Output 2:
88
分析:
1. 树的结点结构
typedef struct node { int data; node* left; node* right; int height; }AVLTreeNode,*AVLTree;
2. 函数声明
int GetHeight(AVLTree A) //获取当前树高 int Max(int x,int y) //用于更新树高 //以下操作返回调整后的AVL树 AVLTree SingleL_Rotation(AVLTree A) //左单旋:LL AVLTree SingleR_Rotation(AVLTree A) //右单旋:RR AVLTree DoubleLR_Rotation(AVLTree A) //右左双旋:RL AVLTree DoubleRL_Rotation(AVLTree A) //左右双旋:LR AVLTree AVL_Insertion(int x,AVLTree T) //将x插入AVL树T中
3. 函数实现 (以左旋为例):
//左单旋:LL AVLTree SingleL_Rotation(AVLTree A) { //!注:A必须有一个左子节点B //!左单旋后,更新A和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; } //左右双旋;LR AVLTree DoubleLR_Rotation(AVLTree A) { //!注:A必须有一个左子结点B,且B必须有一个右子节点C //!做两次单旋,返回新的根节点:C A->left=SingleR_Rotation(A->left); //!B和C做右单旋,返回C return SingleL_Rotation(A); //!A和做左单旋,返回C }
完整代码:
#include <iostream> using namespace std; typedef struct node { int data; node* left; node* right; int height; }AVLTreeNode,*AVLTree; int GetHeight(AVLTree A) { if(A==NULL)return -1; return A->height; } int Max(int x,int y) { return (x>y)?x:y; } //!左单旋:LL AVLTree SingleL_Rotation(AVLTree A) { //!注:A必须有一个左子节点B //!左单旋后,更新A和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; } //!右单旋:RR AVLTree SingleR_Rotation(AVLTree A) { AVLTree C=A->right; A->right=C->left; C->left=A; A->height=Max(GetHeight(A->left),GetHeight(A->right))+1; C->height=Max(A->height,GetHeight(C->right))+1; return C; } //!左右双旋;LR AVLTree DoubleLR_Rotation(AVLTree A) { //!注:A必须有一个左子结点B,且B必须有一个右子节点C //!做两次单旋,返回新的根节点:C A->left=SingleR_Rotation(A->left); //!B和C做右单旋,返回C return SingleL_Rotation(A); //!A和做左单旋,返回C } //!右左双旋:RL AVLTree DoubleRL_Rotation(AVLTree A) { A->right=SingleL_Rotation(A->right); return SingleR_Rotation(A); } //!将x插入AVL树T中,并且返回调整后的AVL树 AVLTree AVL_Insertion(int x,AVLTree T) { if(!T) //!若插入空树,则新建包含一个节点的树 { T=new AVLTreeNode; T->data=x; T->height=0; T->left=T->right=NULL; } else if(x<T->data) //!插入T的左子树 { T->left=AVL_Insertion(x,T->left); if(GetHeight(T->left)-GetHeight(T->right)==2) { //!需左旋 if(x<T->left->data) T=SingleL_Rotation(T); //!左单旋:LL else T=DoubleLR_Rotation(T); //!左右双旋:LR } } else if(x>T->data) //!插入T的右子树 { T->right=AVL_Insertion(x,T->right); if(GetHeight(T->left)-GetHeight(T->right)==-2) { //!需右旋 if(x>T->right->data) T=SingleR_Rotation(T); //!右单旋:RR else T=DoubleRL_Rotation(T); //!右左双旋:RL } } else //! x==T->data, 无需插入 return T; //!更新树高 T->height=Max(GetHeight(T->left),GetHeight(T->right))+1; return T; } int main() { int n,x; cin >> n; AVLTree root=NULL; for(int i=0;i<n;i++) { cin >> x; root=AVL_Insertion(x,root); } cout << root->data << endl; return 0; }