浙江大学数据结构MOOC-课后习题-第四讲-树5 Root of AVL Tree

题目汇总
浙江大学数据结构MOOC-课后习题-拼题A-代码分享-2024

题目描述

AVL树是一种自平衡的二叉搜索树。在AVL树中,任何节点的两个子树的高度之差最多为一;如果任何时候它们的高度之差超过一,就会进行重新平衡以恢复这一特性。图1至图4展示了旋转规则。
在这里插入图片描述
在这里插入图片描述

现在,给定一系列插入操作,你需要告诉我生成的AVL树的根是什么。

输入规范:
每个输入文件包含一个测试案例。对于每个案例,第一行包含一个正整数N(不超过20),这是要插入的键的总数。然后在下一行给出N个不同的整数值。一行中的所有数字由空格分隔。

输出规范:
对于每个测试案例,打印出生成的AVL树的根节点。

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


/*	
*	树节点结构:值、左&右孩子指针、左右子树高度差绝对值
	建立一个根节点
	插入节点(递归插入)
	判断根节点左右是否平衡——>怎么判断?——>左右子树高度差是否大于1
	——>怎么求出左右子树高度差?——>递归求出左右子树高度,然后相减
	
	不平衡怎么办?——>调整为平衡二叉树——>怎么调整?——>根据实际情况进行旋转
	
*/
#include <iostream>
struct treeNode
{
	int value;
	treeNode* left, * right;
	int height;
};
typedef treeNode* tree;

/* 获取最大值*/
int Max(int a, int b)
{
	return a > b ? a : b;
}
/* 创建新节点 */
tree newNode(int V)
{
	tree T = (tree)malloc(sizeof(treeNode));
	T->value = V;
	T->left = NULL;
	T->right = NULL;
	T->height = 0;

	return T;
}
/* 获取树的高度 */
int getHeight(tree T)
{
	int lh, rh;
	if (!T)
	{
		return 0;
	}
	else
	{
		lh = getHeight(T->left);
		rh = getHeight(T->right);
		return Max(lh, rh) + 1;
	}
}



/* LL旋转调整 */
tree singleLeftRotation(tree T)
{
	tree A = T;
	tree B = T->left;
	A->left = B->right;
	B->right = A;
	A->height = Max(getHeight(A->left), getHeight(A->right)) + 1;
	B->height = Max(getHeight(B->left), getHeight(B->right)) + 1;

	return B;
}

/* RR旋转调整 */
tree singleRightRotation(tree T)
{
	tree A = T;
	tree B = T->right;
	A->right = B->left;
	B->left = A;
	A->height = Max(getHeight(A->left), getHeight(A->right)) + 1;
	B->height = Max(getHeight(B->left), getHeight(B->right)) + 1;

	return B;
}
/* LR旋转调整 */
tree doubleLeftRightRotation(tree T)
{
	if (!T->left) return NULL;
	T->left = singleRightRotation(T->left);
	return singleLeftRotation(T);
}

/* RL旋转调整 */
tree doubleRightLeftRotation(tree T)
{
	if (!T->right) return NULL;
	T->right = singleLeftRotation(T->right);
	return singleRightRotation(T);
}

/* 插入结点 */
tree insert(tree T, int V)
{	
	if (!T)
	{
		T = newNode(V);
	}
	else if (V > T->value)
	{
		T->right = insert(T->right, V); 
		//出现了不均衡
		if(getHeight(T->left) - getHeight(T->right) == -2)
		{	
			//RL类型
			if (V < T->right->value)
			{
				T = doubleRightLeftRotation(T);
			}
			//RR类型
			else
			{
				T = singleRightRotation(T);
			}
		}

	}
	else 
	{
		T->left = insert(T->left, V);
		//出现了不均衡
		if (getHeight(T->left) - getHeight(T->right) == 2)
		{
			//判断不均衡类型
			//LR类型
			if (V > T->left->value)
			{
				T = doubleLeftRightRotation(T);
			}
			//LL类型
			else
			{
				T = singleLeftRotation(T);
			}
		}
	}
	T->height = Max(getHeight(T->left), getHeight(T->right)) + 1;
	return T;
}
int main()
{
	int N, V;
	std::cin >> N >> V;

	/* 建立根节点 */
	tree T = newNode(V);
	/* 插入节点 */
	for (int i = 1; i < N; i++)
	{
		std::cin >> V;
		T = insert(T, V);
	}
	std::cout << T->value << std::endl;
	return 0;	
}
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值