PAT 1123. Is It a Complete AVL Tree (30) 平衡树构建+ 完全二叉树判断

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<queue>
#include<string.h>
#include<cmath>

using namespace std;

//80min
//耗时于写,改指针bug
/*************************
题意:
构建二叉平衡树
并水平输出
并判断是否为完全二叉树
*************************/

/************************
求解要点:
1.完全二叉树判断:
按广度遍历时
给每个点附上一个树状数组坐标
左树坐标=2*i,右树为2*i+1
然后当水平输出时,若坐标不为连续,说明不是完全二叉。

************************/

/***********************
笔记:

*********************/
#define RH -1
#define LH 1
#define EH 0
#define TRUE 1
#define FALSE 0


typedef struct BST
{
	int data;
	int bf;
	struct BST *lchild,*rchild;
	int i;
}BSNode;


//右旋
//即p的左根lc 要和 p 交换
//lc换上来之前,需要先处理lc的右子树,否则会丢失
//如lc的右子树交给p左,然后再移动上来
void R_Rotate(BSNode * &p)
{
	BSNode *lc=p->lchild;
	p->lchild=lc->rchild;
	lc->rchild=p;
	p=lc;
}

void L_Rotate(BSNode *&p)
{	
	BSNode *rc=p->rchild;
	p->rchild=rc->lchild;
	rc->lchild=p;
	p=rc;
}


//已知左子树T不平衡,需要进行旋转
//但是该旋转有LL和LR之分。
//并且旋转后会改变平衡因子bf
void Left_Balance(BSNode * &T)
{
	BSNode *lc;
	BSNode *rd;
	lc = T->lchild;
	//要检查到底是
	switch(lc->bf){
		case LH:
			T->bf=lc->bf=EH;
			R_Rotate(T);break;
		case RH:
			rd=lc->rchild;
			switch(rd->bf){
			case LH: 
				T->bf=RH;lc->bf=EH;break;
			case EH:
				T->bf=lc->bf=EH;break;
			case RH:
				T->bf=EH;lc->bf=LH;break;
			}
		rd->bf=EH;
		L_Rotate(T->lchild);
		R_Rotate(T);
	}

}

//对称写法,l改成r,L改成R,E改成L/R
void Right_Balance(BSNode * &T)
{
	BSNode *rc;
	BSNode *ld;
	rc = T->rchild;
	//要检查到底是
	switch(rc->bf){
		case RH:
			T->bf=rc->bf=EH;
			L_Rotate(T);break;
		case LH:
			ld=rc->lchild;
			switch(ld->bf){
			case LH: 
				T->bf=EH;rc->bf=RH;break;
			case EH:
				T->bf=rc->bf=EH;break;
			case RH:
				T->bf=LH;rc->bf=EH;break;
			}
		ld->bf=EH;
		R_Rotate(T->rchild);
		L_Rotate(T);
	}

}

int insertAVL(BSNode * &T,int element,int &taller)
{
	int e;
	e=element;
	if(T==NULL)
	{
		T=new BSNode;
		T->data=element;
		T->lchild=T->rchild=NULL;
		T->bf=0;
		taller=TRUE; //插入新节点,增高了
		return 1;
	}

	//有相同值,不可插入
	if(e==T->data)
	{
		taller=FALSE;
		return 0;
	}

	if(e<T->data)
	{
		if(insertAVL(T->lchild,e,taller)==0)
			return 0;

		if(taller==TRUE){ //左子树变高
			switch(T->bf)
			{
			case LH:Left_Balance(T);taller=FALSE;break;
			//原本相等,左树加1后变LH,增高
			case EH:T->bf=LH;taller=TRUE;break;
			//原本为RH,左树加1后变相等,未增高
			case RH:T->bf=EH;taller=FALSE;break;
			}
		}
	}
	else{
		if(insertAVL(T->rchild,e,taller)==0)
			return 0;
		if(taller==TRUE){ //插入右树,若右树变高
			switch(T->bf)
			{
			//原本LH,右树+1,平衡
			case LH:T->bf=EH;taller=FALSE;break;
			//原本相等,右树加1后变RH,增高
			case EH:T->bf=RH;taller=TRUE;break;
			//原本为RH,右树加1后不平衡,右平衡
			case RH:Right_Balance(T);taller=FALSE;break;
			}
		}
	}
	return 1;
}

vector<int> ans;
int ansi=1;
bool flag=true;
void levelprint(BSNode *root)
{
	queue<BSNode *>q;
	BSNode *T;
	T=root;
	T->i=1;
	q.push(T);
	while(!q.empty())
	{
		T=q.front();
		q.pop();

		//判断完全二叉树,即输出的树数组序号为顺序的
		if(T->i!=ansi)
			flag=false;
		ans.push_back(T->data);
		ansi++;

		if(T->lchild!=NULL)
		{
			T->lchild->i=(T->i)*2;
			q.push(T->lchild);
		}
		if(T->rchild!=NULL)
		{
			T->rchild->i=(T->i)*2+1;
			q.push(T->rchild);
		}
	}


	int i;
	cout<<ans[0];
	for(i=1;i<ans.size();i++)
		printf(" %d",ans[i]);
	cout<<endl;
	if(flag==true)
		cout<<"YES"<<endl;
	else cout<<"NO"<<endl;
}

int main()
{
	int n,i,num;
	scanf("%d",&n);
	int tdata;
	int taller;
	BSNode *root=NULL;
	for(i=0;i<n;i++)
	{
		scanf("%d",&tdata);
		insertAVL(root,tdata,taller);
	}
	levelprint(root);
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值