您的位置:首页 > 其它

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

2017-09-17 00:18 441 查看
#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);
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: