PAT_A1127
PAT甲级1127.
目录
A1127
题目
样例
输入:
8
12 11 20 17 1 15 8 5
12 20 17 11 15 8 5 1
输出:
1 11 5 8 17 12 20 15
思路和坑点
思路:
先使用中序和后序序列递归建树,然后对建成的树进行层序遍历并保存层序遍历的结果,统计每一层的节点数量,然后对偶数层的节点序列进行逆转,就是最后需要的输出序列。
AC代码
#include<bits/stdc++.h>
using namespace std;
typedef struct node{ //二叉树的结点定义
int data;
struct node *left,*right;
}Node,*Tree;
int n;
int post[31]; //后序遍历序列
int in[31]; //中序遍历序列
int layercnt[31]={0}; //统计每层的元素个数
vector<int> layer; //存放层序遍历序列
Node *creat(int pl,int pr,int il,int ir);//由中序和后序建树的函数
int layorder(Tree root); //层序遍历
int main(){
#ifdef ONLINE_JUDGE
#else
freopen("1.txt", "r", stdin);
#endif
scanf("%d",&n); //读入序列
for(int i=0;i<n;i++)
scanf("%d",&in[i]);
for(int i=0;i<n;i++)
scanf("%d",&post[i]);
Tree root=creat(0,n-1,0,n-1); //建树
int layern=layorder(root); //层序遍历,并返回最大的层数
int sum=1; //已经处理过的结点个数,根不需要处理,直接跳过,所以初始化为1
for(int i=1;i<=layern;i++){ //偶数层进行反转
if(i%2==0)
reverse(layer.begin()+sum,layer.begin()+sum+layercnt[i]);
sum+=layercnt[i]; //累加处理过的结点个数
}
for(int i=0;i<layer.size();i++){//输出最终的序列
if(i) putchar(' ');
printf("%d",layer[i]);
}
return 0;
}
Node *creat(int pl,int pr,int il,int ir)
{
if(pl>pr) return NULL;
Node *root=new node;
root->data=post[pr];
int k;
for(k=il;k<=ir;k++){
if(in[k]==post[pr]) break;
}
int leftnum=k-il;
root->left=creat(pl,pl+leftnum-1,il,k-1);
root->right=creat(pl+leftnum,pr-1,k+1,ir);
return root;
}
int layorder(Tree root)
{
int maxlayer=0,cnt=0; //maxlayer记录层数,cnt记录每一个层的元素个数
queue<Node*> q;
Node * last=root,*tail=root; //last记录当前层的最后一个,tial记录下一层的最后一个位置
q.push(root);
while(!q.empty()){
Node * now=q.front();
q.pop();
layer.push_back(now->data); //加入层序遍历序列
cnt++;
if(now->left) q.push(tail=now->left); //孩子入队并更新tail
if(now->right) q.push(tail=now->right);
if(now==last){ //如果当前层已经处理完毕
layercnt[maxlayer++]=cnt; //统计当前层节点数量,并重置计数器
cnt=0;
last=tail; //更新last
}
}
return maxlayer; //返回树的最大层数
}