PTA || 04-树5 Root of AVL Tree

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.

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 NNN (≤20\le 2020) 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;
} 

猜你喜欢

转载自blog.csdn.net/qq_26565435/article/details/83348408