5-6 Root of AVL Tree (25分) (二叉平衡树的旋转操作)

5-6 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.

 

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 NN (\le 2020) which is the total number of keys to be inserted. Then NN 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 
#include 

struct AVLNode{
	int num;/*结点数据*/
	struct AVLNode * left;/*指向右子树*/
	struct AVLNode * right;/*指向左子树*/
	int height;/*树的高度*/
};
typedef struct AVLNode * AVLTree;

int Max(int a, int b)
{
	return a > b ? a : b;
}

int Getheight(AVLTree T)/*得到树的高度*/
{
	if(T == NULL)
	{
		return -1;
	}
	else
	{
		return T->height;
	}
}

AVLTree SingleLeftRotation(AVLTree A)/*左旋转*/ 
{
	/*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;
}

AVLTree SingleRightRotation(AVLTree A)/*右旋转*/
{/*A必须有一个右结点B*/ 
	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必须有一个左结点B,而且B必须有一个右结点C*/ 

	A->left = SingleRightRotation(A->left);/*B与C做右旋转,返回的是C那个根结点*/
	
	A = SingleLeftRotation(A);/*A与C做左旋转,返回的是C那个根结点*/
	
	return A;/*返回的是C*/ 
}

AVLTree DoubleRightLeftRotation(AVLTree A)
{/*A必须有一个右结点B,而且B必须有一个左结点C*/ 

	A->right = SingleLeftRotation(A->right);
	
	A = SingleRightRotation(A);
	
	return A;
}

AVLTree insert(AVLTree T,int number)
{
	if(T == NULL)/*如果T为NULL,就新建一个结点的树*/ 
	{
		T = (AVLTree)malloc(sizeof(struct AVLNode));
		T->height = 0;
		T->num = number;
		T->left = T->right = NULL;
	}
	else if(number < T->num)
	{
		T->left = insert(T->left,number);
		
		if(Getheight(T->left) - Getheight(T->right) == 2)/*当该树左子树与右子树的差为2时,则要做旋转*/
		{
			if(number < T->left->num)/*如果要插入的数小于该树左子树的数,则做左旋转,不是就做左-右旋转*/
			{						 /*实际就是数插在该树的左子树的左边还是右边,分别做不同的旋转*/ 
				T = SingleLeftRotation(T);
			}
			else
			{
				T = DoubleLeftRightRotation(T);
			}
		}
	}
	else if(number > T->num)
	{
		T->right = insert(T->right,number);
		
		if(Getheight(T->right) - Getheight(T->left) == 2)
		{
			if(number > T->right->num)
			{
				T = SingleRightRotation(T);
			}
			else
			{
				T = DoubleRightLeftRotation(T);
			}
		}
	}
	
	
	T->height = Max(Getheight(T->left),Getheight(T->right)) + 1;/*更新高度,每次先下增加结点的时候,对于根结点来说,T->height会+1*/
	return T;
}


int main(void)
{
	AVLTree T = NULL;/*要将T置为空指针*/
	int n,number;
	scanf("%d",&n);
	for(int i = 0; i < n; i++)
	{
		scanf("%d",&number);
		T= insert(T,number);
	}
	if(T)
	printf("%d",T->num);
}


你可能感兴趣的:(数据结构学习)