PAT.A1066 Root of AVL Tree

返回目录

在这里插入图片描述在这里插入图片描述

题意

构建一颗AVL树(平衡二叉排序树)。

样例(可复制)

5
88 70 61 96 120
//output
70
7
88 70 61 96 120 90 65
//output
88

注意点

  1. 本题难度较大,如果PAT考试的时候实在做不出来,可以直接输出中位数,7个测试点可以过5个,取得17分
  2. AVL树(平衡二叉排序树)需要满足:①是二叉排序树,即树的每个节点的左子树上所有节点都小于该节点,每个节点的右子树上所有节点都大于该节点②每个节点的左高度与右高度的差的绝对值不能超过1
  3. 平衡二叉树构建过程中,会出现4种需要旋转的情况:LL,LR,RR,RL。每种情况需要左旋或右旋看下面的参考代码。在手写模拟中,我们常用交换的方式,但实际代码里面,我们直接赋值即可。

直接中位数(17分)

#include<bits/stdc++.h>
using namespace std;

int main(){
	int n,data[25];
	cin>>n;
	for(int i=0;i<n;i++)scanf("%d",&data[i]);
	sort(data,data+n);
	printf("%d",data[n/2]);
    return 0;
}

AVL

#include<bits/stdc++.h>
using namespace std;
struct node{
	int v,height;
	node *lc,*rc;
}*root; 
node* newnode(int v){
	node* no=new node;
	no->v=v;
	no->height=1;
	no->lc=no->rc=NULL; 
	return no;
}
int getheight(node* root){
	if(root==NULL)return 0;
	return root->height;
}
int getbalancenum(node* root){
	return getheight(root->lc)-getheight(root->rc);
}
void L(node* &root){
	node* tmp=root->rc;//tmp为新的root 
	root->rc=tmp->lc;//把tmp->rc裁剪下来
	tmp->lc=root;
	//只有root和tmp的高度发生了变化 
	root->height=max(getheight(root->lc),getheight(root->rc))+1;
	tmp->height=max(getheight(tmp->lc),getheight(tmp->rc))+1;
	root=tmp;
}
void R(node* &root){
	node* tmp=root->lc;
	root->lc=tmp->rc;
	tmp->rc=root;
	root->height=max(getheight(root->lc),getheight(root->rc))+1;
	tmp->height=max(getheight(tmp->lc),getheight(tmp->rc))+1;
	root=tmp;
}
void insert(node* &root,int v){
	if(root==NULL){
		root=newnode(v);
		return;
	}
	if(v<root->v){
		insert(root->lc,v);
		root->height=max(getheight(root->lc),getheight(root->rc))+1;
		if(getbalancenum(root)==2){
			if(getbalancenum(root->lc)==1){//LL型 
				R(root);//右旋 
			}else if(getbalancenum(root->lc)==-1){//LR型 
				L(root->lc);//先左旋 
				R(root);//再右旋 
			}
		}
	}else{
		insert(root->rc,v);
		root->height=max(getheight(root->lc),getheight(root->rc))+1;
		if(getbalancenum(root)==-2){
			if(getbalancenum(root->rc)==-1){//RR型 
				L(root);//左旋 
			}else if(getbalancenum(root->rc)==1){//RL型 
			    R(root->rc);//先右旋 
				L(root);//再左旋 
			}
		}
	} 
}
int main(){
	int n,v;
	cin>>n;
	while(n--){
		cin>>v;
		insert(root,v);
	}
	printf("%d\n",root->v);
    return 0;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小怪兽会微笑

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值