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

来源:互联网 发布:nginx 文件服务器 编辑:程序博客网 时间:2024/05/23 16:41
#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 0typedef 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之分。//并且旋转后会改变平衡因子bfvoid 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/Rvoid 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);}

原创粉丝点击