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.
Input Specification:
Each input file contains one test case. For each case, the first line contains a positive integer NNN (≤20\le 20≤20) which is the total number of keys to be inserted. Then NNN 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
#include <stdio.h>
#include <stdlib.h>
#define ElementType int
//AVL树结点定义
typedef struct AVLNode *Position;
typedef Position AVLTree;//AVL树的类型
struct AVLNode {
ElementType Data;//结点数据
AVLTree Left;
AVLTree Right;
int Height;
};
/**************************************************************
1.插入新结点,判断树是否为空,若为空则建立以新节点为根的新AVL树 ;
2.若不为空,将新结点与现有结点比较后递归插入左或右子树 ;
3.判断树高,若破坏平衡,则根据树高判断进行以下哪种旋转:
(1)SingleLeftRotation
(2)SingleRightRotation
(3)DoubleLeftRightRotation
(4)DoubleRightLeftRotation
**************************************************************/
AVLTree Insert(AVLTree A, ElementType X);//结点插入AVL树
int GetTreeHeight(AVLTree A);//得到树的高度
AVLTree SingleLeftRotation(AVLTree A);//左单旋
AVLTree SingleRightRotation(AVLTree A);//右单旋
AVLTree DoubleLeftRightRotation(AVLTree A);//左-右双旋
AVLTree DoubleRightLeftRotation(AVLTree A);//右-左双旋
int Max(int a, int b);//获取左右子树高度最大值
//主体程序框架
int main()
{
AVLTree A;
int N, i;
int x;
A = (AVLTree)malloc(sizeof(struct AVLNode));
scanf("%d\n", &N);
scanf("%d", &x);
A->Data = x;
A->Left = A->Right = NULL;
A->Height = 1;
for (i=1; i<N; i++){
scanf("%d", &x);
A = Insert(A, x);
}
printf("%d\n", A->Data );
return 0;
}
AVLTree Insert(AVLTree A, ElementType X)
//结点插入AVL树
{
if (!A){ //树为空
A = (AVLTree)malloc(sizeof(struct AVLNode));
A->Data = X;
A->Left = A->Right = NULL;
A->Height = 1;
}
//树不空
else if (X < A->Data ){
//插入A的左子树
A->Left = Insert(A->Left , X);
if (GetTreeHeight(A->Left ) - GetTreeHeight(A->Right ) == 2){
//如果需要进行左旋
if (X < A->Left->Data )//左单旋
A = SingleLeftRotation(A);
else //左-右双旋
A = DoubleLeftRightRotation(A);
}
}
else if (X >A->Data ){
//插入A的右子树
A->Right = Insert(A->Right , X);
if (GetTreeHeight(A->Left ) - GetTreeHeight(A->Right ) == -2){
//如果需要进行右旋
if (X > A->Right->Data ) //右单旋
A = SingleRightRotation(A);
else //右-左双旋
A = DoubleRightLeftRotation(A);
}
}//X = A->Data不用插入
A->Height = Max(GetTreeHeight(A->Left ), GetTreeHeight(A->Right )) + 1;//更新树高
return A;
}
int GetTreeHeight(AVLTree A)
//递归得到树的高度
{
int HL, HR, H;
if (!A) return 0;
else{
HL = GetTreeHeight(A->Left );
HR = GetTreeHeight(A->Right );
H = Max(HL, HR);
return (H+1);
}
}
AVLTree SingleLeftRotation(AVLTree A)
//左单旋,A必须有一个左子结点B
//左旋时,A的左子结点B的左子树不动,A的右子树不动
{
AVLTree B = A->Left ;
A->Left = B->Right ;
B->Right = A;
A->Height = Max(GetTreeHeight(A->Left ),GetTreeHeight(A->Right )) + 1;
B->Height = Max(GetTreeHeight(B->Left ),A->Height )+ 1;
return B;
}
AVLTree SingleRightRotation(AVLTree A)
//右单旋,A必须有一个右子结点B
//右旋时,A的右子结点B的右子树不动,A的左子树不动
{
AVLTree B = A->Right ;
A->Right = B->Left ;
B->Left = A;
A->Height = Max(GetTreeHeight(A->Left ),GetTreeHeight(A->Right )) + 1;
B->Height = Max(GetTreeHeight(B->Right ),A->Height) + 1;
return B;
}
AVLTree DoubleLeftRightRotation(AVLTree A)
//左-右双旋,A必须有一个左子结点B,B必须有一个右子结点C
{
//B与C做一次右单旋,C被返回
AVLTree B = A->Left ;
AVLTree C = B->Right ;
A->Left = SingleRightRotation(B);
//A与C做一次左单旋,C被返回
return SingleLeftRotation(A);
}
AVLTree DoubleRightLeftRotation(AVLTree A)
//右-左双旋,A必须有一个右子结点B,B必须有一个左子结点C
{
//B与C做一次左单旋,C被返回
AVLTree B = A->Right ;
AVLTree C = B->Left ;
A->Right = SingleLeftRotation(B);
//A与C做一次右单旋,C被返回
return SingleRightRotation(A);
}
int Max(int a, int b)
//比较大小,返回最大值
{
return a > b ? a : b;
}