04-树5 Root of AVL Tree (25分)
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 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
题目思路:实际上就是AVL树的具体实现
#include<stdio.h>
#include<stdlib.h>
#define MaxNum 20
#define ElementType int
/*题意:将输入调整为平衡二叉树(AVL),输出根结点元素
解题思路:判断插入结点对现有结点的平衡因子的影响,进而进行LL,LR,RL,RR旋转
假设三个结点连接关系为A->B->C,C为新插入结点并使得A的平衡因子==2
若C在A的左孩子的左子树上,则对A与B进行LL旋转
若C在A的左孩子的右子树上,则对A,B,C进行LR旋转,可分解为首先对B与C进行RR旋转,再对A与C进行LL旋转
若C在A的右孩子的右子树上,则对A与B进行RR旋转
若C在A的右孩子的左子树上,则对A,B,C进行RL旋转,可分解为首先对B与C进行LL旋转,再对A与C进行RR旋转
*/
typedef struct TreeNode *BinTree;
struct TreeNode{
ElementType Data;
BinTree left;
BinTree right;
int height;//记录高度为平衡二插树做准备
};
BinTree AVLInsert(BinTree BST, ElementType X);
BinTree SingleLeftRotation(BinTree BST);
BinTree SingleRightRotation(BinTree BST);
BinTree DoubleLeftRotation(BinTree BST);
BinTree DoubleRightRotation(BinTree BST);
int GetAVLtreeHeight(BinTree BST);
int Max(int height1,int height2);
int main()
{
BinTree T;
int data,N;
//freopen("test.txt", "r", stdin);
scanf("%d",&N);//Read TreeNode Num
for(int i = 0; i < N; i++){
scanf("%d",&data);
T = AVLInsert(T,data);
}
printf("%d",T->Data);
return 0;
}
BinTree AVLInsert(BinTree BST, ElementType X)
{
if(!BST){//若原树为空,生成并返回一个节点的二插搜索树
BST = (BinTree)malloc(sizeof(struct TreeNode));
BST->Data = X;
BST->left = NULL;
BST->right = NULL;
BST->height = 0;
}
else{//开始要插入元素
if(X < BST->Data){
BST->left = AVLInsert(BST->left,X);//递归插入左子树
if(GetAVLtreeHeight(BST->left) - GetAVLtreeHeight(BST->right)==2){
//左边发现不平衡了,包括了单边不平衡的情况
if( X < BST->left->Data){
//麻烦节点在左子树的左边且采用LL旋转
BST = SingleLeftRotation(BST);
}
else{
//麻烦节点在左子树的右边且采用LR旋转
BST = DoubleLeftRotation(BST);
}
}
}
else if(X > BST->Data){
BST->right = AVLInsert(BST->right,X);//递归插入右子树
if(GetAVLtreeHeight(BST->right) - GetAVLtreeHeight(BST->left)==2){
//右边发现不平衡了, 包括了只有一边单边不平衡的情况
if( X > BST->right->Data){
//麻烦节点在右子树的右边且采用RR旋转
BST = SingleRightRotation(BST);
}
else{
///麻烦节点在右子树的左边且采用RL旋转
BST = DoubleRightRotation(BST);
}
}
}
//else X已经存在,什么都不做
}
BST->height = Max( GetAVLtreeHeight(BST->right) , GetAVLtreeHeight(BST->left) )+1;
//树的高度是左子树和右子树的高度中较大的那一个高度+1
return BST;
}
BinTree SingleLeftRotation(BinTree BST)
{
BinTree BT = BST->left;
BST->left = BT->right;
BT->right = BST;
BST->height = Max( GetAVLtreeHeight(BST->right) , GetAVLtreeHeight(BST->left) )+1;
BT->height = Max( GetAVLtreeHeight(BT->left) , BST->height )+1;
return BT;
}
BinTree SingleRightRotation(BinTree BST){
BinTree T = BST->right;
BST->right = T->left;
T->left = BST;
BST->height = Max( GetAVLtreeHeight(BST->right) , GetAVLtreeHeight(BST->left) )+1;
T->height = Max( GetAVLtreeHeight(BST->right) , BST->height )+1;
return T;
}
BinTree DoubleLeftRotation(BinTree BST){
BST->left = SingleRightRotation(BST->left);
return(SingleLeftRotation(BST));
}
BinTree DoubleRightRotation(BinTree BST){
BST->right = SingleLeftRotation(BST->right);
return(SingleRightRotation(BST));
}
int GetAVLtreeHeight(BinTree BST)
{
int height;
if(!BST){
height = 0;
}
else{
height = BST->height;
}
return height;
}
int Max(int height1,int height2){
if(height1 >= height2){
return height1;
}
else{
return height2;
}
}