题目要求
给出一棵二叉树的中序序列和后序序列,确定一棵树,层序遍历这棵树并按之字形回路输出。
示例:
输入:
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!!!
直接用两个序列找出每层的结点然后输出即可!!
AC代码(C++)
```cpp
#include <bits/stdc++.h>
using namespace std;
int n,post[31],l=0,cnt=1,k;//post存后序序列,l表示层次,cnt统计已经遍历过的结点数目
bool vis[31]={0};//表示中序序列中哪些结点已经被访问过了
vector<int> ans,temp;//ans从左到右存放每层的所有结点
map<int,int> mp,mi;//mp、mi分别是后序和中序中各结点在序列中的位置
int main()
{
scanf("%d",&n);
for(int i=0;i<n;i++)
{
scanf("%d",&k);
mi[k]=i;
}
for(int i=0;i<n;i++)
{
scanf("%d",&post[i]);
mp[post[i]]=i;
}
ans.push_back(post[n-1]);//初始为根结点
vis[mi[post[n-1]]]=1;
printf("%d",post[n-1]);
while(cnt<n)
{
temp.clear();
for(int i=0;i<ans.size();i++)//遍历上一层每个结点,找出其左孩子和右孩子
{
int x=mi[ans[i]]-1,y=x+2,ln=0,rn=0;//ln、rn分别是ans[i]表示的结点所拥有的左子树、右子树大小
while(x>=0&&vis[x]==0)
{ ln++; x--; }
while(y<n&&vis[y]==0)
{ rn++; y++; }
x=mp[ans[i]]-1;
y=x-rn;
if(ln!=0&&rn!=0)
{
temp.push_back(post[y]);
temp.push_back(post[x]);
vis[mi[post[y]]]=1;
vis[mi[post[x]]]=1;
cnt+=2;
}
else if(!(ln==0&&rn==0))
{
temp.push_back(post[x]);
vis[mi[post[x]]]=1;
cnt++;
}
}
l++;
ans=temp;
for(int i=0;i<ans.size();i++)
{ printf(" %d",l%2==1?ans[i]:ans[ans.size()-1-i]); }
}
return 0;
}