A1123 Is It a Complete AVL Tree (30分)

#include<cstdio>
#include<string>
#include<iostream>
#include <algorithm>//含有fill()等 
#include <cmath>
#include<queue>
#include<unordered_set>
#include<set> 
#include<map>
#include<vector>
#include<unordered_map>
#include <cstdlib>//含有free,malloc等;含有NULL 
using namespace std;

//A1141 :unordered_map 

const int INF=1e9; //fill(map[0],map[0]+maxn*maxn,INF); 
const int maxn=30;
//需要打印排名列表 
struct node{
	int val;
	node *left,*right;
};

int getHeight(node* tree){
	if(tree==NULL) return 0;
	int l=getHeight(tree->left);
	int r=getHeight(tree->right);
	return max(l,r)+1;//返回左右子树中最高的高度+本身节点的高度 
	
}
node* LL(node* tree){
	//对节点进行右旋操作 
	node* temp=tree->left;
	tree->left=temp->right;
	//由于要将原先根变为当前根节点的右子树:所以原来左子树根节点的右子树
	//要换到原先根节点的左子树上 
	temp->right=tree;
	return temp; 
}
node* RR(node* tree){
	//对节点进行左旋 :和LL相反即可 
	node* temp=tree->right;//temp是新的树的根节点 
	tree->right=temp->left;
	temp->left=tree;
	return temp;
	
} 
//注意可以复用!右旋和左旋的方法:看清楚调用的是哪个 
node* RL(node* tree){
	//对节点的右子树右旋,对节点左旋
	tree->right=LL(tree->right);
	return RR(tree); 
} 
node* LR(node* tree){
	//先对节点的左子树进行左旋,再对节点进行右旋
	tree->left=RR(tree->left);
	return LL(tree); 
}

node* insert(node* tree,int val){//注意参数传的是指针 
	if(tree==NULL){
		tree=new node();
		tree->val=val;
	}else if(tree->val>val){
		//左子树走
		tree->left=insert(tree->left,val);//AVL树是BST
		//计算该节点的平衡因子:判断是否需要旋转
		//由于插入的是左子树:所以如果失衡只能是左边大于右边两个 
		int l=getHeight(tree->left),r=getHeight(tree->right);
		if(l-r>=2){
			//判断插入的是LR还是LL
			if(val<tree->left->val){
				//LL:tree整体做LL变换 
				tree=LL(tree); 
			}else{
				//LR
				tree=LR(tree);
			}
		} 
	}else{
		//插入根节点的右子树
		tree->right=insert(tree->right,val); 
		int l=getHeight(tree->left),r=getHeight(tree->right);
		if(r-l>=2){
			//判断是RR还是RL
			if(val>tree->right->val)tree=RR(tree);
			else tree=RL(tree); 
		}
	}
	return tree;//只是插入的操作 
}
vector<int> path;
int isComplete=1,after=0;
//层次遍历并且判断是否是完全二叉树 
void level(node* tree){
	queue<node*>q;
	q.push(tree);
	while(!q.empty()){
		node* now=q.front();
		q.pop();
		//在pop输出的时候:加入层次遍历(注意位置) 
		path.push_back(now->val); 
		
		if(now->left!=NULL){
			if(after)isComplete=0;
			q.push(now->left);
		}else{
			after=1;//说明缺孩子节点的节点存在 
		}
		if(now->right!=NULL){
			if(after)isComplete=0;
			q.push(now->right);
		}else{
			after=1;
		}
	}

}
int main(){
	int n,temp;
	scanf("%d",&n);
	node *tree =NULL;//根节点 
	for(int i=0;i<n;i++){
		scanf("%d",&temp);
		tree=insert(tree,temp);
	} 
	level(tree);
	for(int i=0;i<path.size();i++){
		printf("%d",path[i]);
		if(i!=path.size()-1){
			printf(" ");
		}else{
			printf("\n");
		}
	} 
	printf("%s",isComplete?"YES":"NO");
	return 0; 
	
} 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值