PAT : 04-树3. 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 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 ythe 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树的,结果发现在最重要的调节平衡的旋转上发现无从下手,如果是用树的话直接就可以把一棵子树放到某个节点下,根本不用管哪个节点移到数组的什么位置,用数组构造AVL树在我看来是太难完成甚至可能是不可能完成的任务,因为实在是太过于复杂了
因为是第一次手动建树,所以还看了一下别人是怎么做的(再次不要脸的承认了),结果看完之后写出来的代码简直和看的代码没啥区别,不过我还是把代码贴出来了,因为我认为这个代码还是有亮点的。我认为这个代码的优秀之处在于通过递归的方法巧妙地实现了在添加节点的同时计算每个节点深度的工作还顺便进行了旋转,不需要在加完节点之后判断是不是多了一层还是没多一层,如果多了一层除新增节点之外还要将每个节点的深度加1,这又牵涉到遍历的问题巴拉巴拉,一个递归解决了这么多问题,确实让我这个新手佩服得不行
#include <stdio.h>
#include <stdlib.h>

#define MAX(a,b) ((a)>(b)?(a):(b))

typedef struct AVLTreeNode
{
	int data;
	AVLTreeNode *left;
	AVLTreeNode *right;
	int depth;
}*AVLTree;

int getDepth(AVLTree t)
{
	if(!t)
		return 0;
	else
		return t->depth;
}

AVLTree LLrotate(AVLTree t)
{
	AVLTree a = t->left;
	t->left = a->right;
	a->right = t;

	t->depth = MAX(getDepth(t->left), getDepth(t->right)) + 1;
	a->depth = MAX(getDepth(a->left), t->depth) + 1;

	return a;
}

AVLTree RRrotate(AVLTree t)
{
	AVLTree a = t->right;
	t->right = a->left;
	a->left = t;
	
	t->depth = MAX(getDepth(t->left), getDepth(t->right)) + 1;
	a->depth = MAX(getDepth(a->left), t->depth) + 1;
	
	return a;
}

AVLTree LRrotate(AVLTree t)
{
	t->left = RRrotate(t->left);
	return LLrotate(t);
}

AVLTree RLrotate(AVLTree t)
{
	t->right = LLrotate(t->right);
	return RRrotate(t);
}

AVLTree add (AVLTree t, int num)
{
	if(!t)
	{
		t = (AVLTree) malloc (sizeof(AVLTreeNode));
		t->data = num;
		t->left = t->right = NULL;
	}
	else if(num < t->data)
	{
		t->left = add(t->left, num);
		if(getDepth(t->left) - getDepth(t->right) >= 2)
		{
			if(num < t->left->data)
				t = LLrotate(t);
			else
				t = LRrotate(t);
		}
	}
	else if(num > t->data)
	{
		t->right = add(t->right, num);
		if(getDepth(t->right) - getDepth(t->left) >= 2)
		{
			if(num > t->right->data)
				t = RRrotate(t);
			else
				t = RLrotate(t);
		}
	}
	t->depth = MAX(getDepth(t->left), getDepth(t->right)) + 1;

	return t;
}

int main()
{
	AVLTree t = NULL;
	int n;
	scanf("%d", &n);
	int i, num;

	for(i = 0; i < n; i++)
	{
		scanf("%d", &num);
		t = add(t, num);
	}

	printf("%d\n", t->data);

	return 0;
}


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值