PAT甲级 A1066 Root of AVL Tree (25point(s))

题目:  传送门

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 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<bits/stdc++.h>  
using namespace std;

struct node{
	int data, h;     //h表示树的高度
	node*lc, *rc;
};
 
int geth(node*root){       //得到树的高度
	if(!root) return 0;
	return root->h; 
}


//更新树的高度
void update(node* root){
	root->h = max(geth(root->lc), geth(root->rc)) + 1;
}

//得到平衡因子
int getfac(node* root){
	return geth(root->lc) - geth(root->rc);
}


//左旋(让右子树的左子树成为根的右子树,让右子树成为根)
void L(node* &root){
	node* temp = root->rc;
	root->rc = temp->lc;
	temp->lc = root;
	update(root);      //此时的root在下面,temp在上面,从下到上更新高度
	update(temp);
	root = temp;
}


//右旋(让左子树的右子树成为根的左子树,让左子树成为根)
void R(node* &root){
	node* temp = root->lc;
	root->lc = temp->rc;
	temp->rc = root;
	update(root);
	update(temp);
	root = temp;
}


//插入元素
void insert(node* &root, int x){
	if(!root){         //空树直接插就行
		node* temp = new node;
		temp->data = x, temp->h = 1;
		temp->lc = temp->rc = NULL;
		root = temp;
		return;
	}
	
	if(root->data == x) return;       //已有,不插
	else if(root->data < x)       
		insert(root->rc, x);
	else
		insert(root->lc, x);
	
    //插完之后,更新树高
	update(root);
	if(getfac(root) == 2)         
		if(getfac(root->lc) == 1)      //根的因子为2,左子树的因子为1,为LL型
			R(root);              //直接对根右旋
		else{                    //根的因子为2,左子树的因子为-1, 为LR
			L(root->lc);       //先对左子树左旋
			R(root);           //再对根右旋
		}
	else if(getfac(root) == -2)         //同上
		if(getfac(root->rc) == -1)        //RR
			L(root);
		else{
			R(root->rc);
			L(root);
		}	
}

int main(){
    //这两行代码加快cin和cout的速度,详见https://blog.csdn.net/qq_45472866/article/details/108686116
	ios::sync_with_stdio(false);
	cin.tie(0);
    
	int n, x;
	cin >> n;
	node*root = NULL;        //初始为空树,root为NULL
	for(int i = 0; i < n; i++){
		cin >> x;
		insert(root, x);
	} 
	cout << root->data << endl;
	
	return 0;
}

 

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值