Root of AVL Tree (25 分)

n 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 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

题目分析:

这道题的题意是给n个元素,让你输出其二叉平衡树的根节点数据。其实考察的就是二叉平衡树的旋转。一共有四种旋转,LL,LR,RR,RL。然后依据插入的节点是否破坏了平衡,以及破坏平衡的位置与根节点的关系进行调整。

代码如下:

#include <iostream>
#include <new>
#include <string>
using namespace std;

typedef struct AVLTreeNode* AVLTree;
struct AVLTreeNode{
	int height;    //记录树高
	int number;
	AVLTree left, right;
};

AVLTree RightRightRotation(AVLTree T);   //RR旋转
AVLTree LeftLeftRotation(AVLTree T);     //LL旋转
AVLTree LeftRightRotation(AVLTree T);    //LR旋转
AVLTree RightLeftRotation(AVLTree T);    //RL旋转
AVLTree CreateAVLTreeNode(int v);         //建树
AVLTree DeleteAVLTreeNode(AVLTree T,AVLTree v);   //删除树,这里用不着
AVLTree InsertAVLTreeNode(AVLTree T, int v);   //插入新的节点
int GetAVLTreeHeight(AVLTree T);     //获取树的高度
int Max(int a, int b);   //比较左子树高度和右子树高度,取高的那个。

int main()
{
	int n, i, v;
	AVLTree T;

	cin >> n;
	if( n == 0)    //当输入n等于0
		cout << 0 << endl;
	else {
		cin >> v;     //先用一个节点建树
		T = CreateAVLTreeNode(v);
		for( i=1; i<n; i++) {    //后面n-1个插入当中去。
			cin >> v;
			T = InsertAVLTreeNode(T, v);
		}
		cout << T->number << endl;
	}
    return 0;
}

AVLTree InsertAVLTreeNode(AVLTree T, int v)
{
	AVLTree Tree;
	if( T == NULL ) {    //找到插入的位置了,建立节点进行插入。
		T = CreateAVLTreeNode(v);
		/*if( Tree == NULL ) {
			cout << "未分配内存" << endl;
			return NULL;
		}*/
	} else if( v < T->number ) {   //当小于时,在左子树插入
		T->left = InsertAVLTreeNode(T->left, v);   
		if( GetAVLTreeHeight(T->left) - GetAVLTreeHeight(T->right) == 2) {   //插入之后,如果破坏了平衡,进行旋转
			if( v > T->left->number )   //当插入的节点在左子树的右子树上,进行LR旋转
				T = LeftRightRotation(T);
			else                       //当插入的节点在左子树的左子树上,进行LL旋转
				T = LeftLeftRotation(T);
		}
	} else if( v > T->number ) {    //当大于时,在右子树插入。
		T->right = InsertAVLTreeNode(T->right, v);    //递归查找位置插入
		if( GetAVLTreeHeight(T->right) - GetAVLTreeHeight(T->left) == 2) {   //插入之后,如果破坏了平衡,进行旋转
			if( v > T->right->number )    //当插入的节点在右子树的右子树上,进行RR旋转
				T = RightRightRotation(T);
			else                            //当插入的节点在右子树的左子树上,进行RL旋转
				T = RightLeftRotation(T);
		}
	} /*else {
		cout << "请不要添加相同节点!" << endl;
	}*/

	T->height = Max(GetAVLTreeHeight(T->left), GetAVLTreeHeight(T->right)) + 1;    //更新树高。这里叶节点是1,因为结果有2个节点
	/*cout << "The Root is " << T->number << endl << T->height << endl;*/    //根节点的高度应该是1,因为一边是0.所以叶节点也得是1.
	return T;
}

AVLTree RightRightRotation(AVLTree T)  //RR旋转,自己画个图可能更好理解一点。
{
	AVLTree temp;

	temp = T->right;
	T->right = temp->left;
	temp->left = T;

	T->height = Max(GetAVLTreeHeight(T->left), GetAVLTreeHeight(T->right)) + 1;
	temp->height = Max(T->height, GetAVLTreeHeight(temp->right)) + 1;

	return temp;
}

AVLTree LeftLeftRotation(AVLTree T)  //LL旋转
{
	AVLTree temp;

	temp = T->left;
	T->left = temp->right;
	temp->right = T;

	T->height = Max(GetAVLTreeHeight(T->left), GetAVLTreeHeight(T->right)) + 1;
	temp->height = Max(T->height, GetAVLTreeHeight(temp->left)) + 1;

	return temp;
}

AVLTree LeftRightRotation(AVLTree T)  //LR旋转,实际上就是左子树先进行RR旋转,再然后进行一次LL旋转。
{
	T->left = RightRightRotation(T->left);

	return LeftLeftRotation(T);
}

AVLTree RightLeftRotation(AVLTree T)//RL旋转,实际上就是右子树先进行LL旋转,再然后进行一次RR旋转。
{
	T->right = LeftLeftRotation(T->right);

	return RightRightRotation(T);
}

int Max(int a, int b)   //求左右子树当中高的那个。
{
	return (a>b)?a:b;
}

int GetAVLTreeHeight(AVLTree T)   //求树的高度
{
	int n;
	if( T== NULL)  //当没有儿子的时候,为0,即叶节点。
		n = 0;
	else
		n = T->height;

	return n;
}

AVLTree CreateAVLTreeNode(int v)   //建立节点
{
	AVLTree T = new (struct AVLTreeNode);
	T->left = T->right = NULL;
	T->height = 0;
	T->number = v;

	return T;
}

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值