04-树5 Root of AVL Tree

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.

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

题目思路:实际上就是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;
	}
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值