目录
1,题目描述
Sample Input:
8
12 11 20 17 1 15 8 5
12 20 17 11 15 8 5 1
Sample Output:
1 11 5 8 17 12 20 15
题目描述
在中序+后序=》层次的基础上更进了一步,偶数层从左向右,奇数层从右向左;
2,思路
类似于这一题@&再见萤火虫&【PAT_甲级_1020 Tree Traversals (25分) (C++)【树的遍历】】中序+后序=》层次;
关于如何根据后序遍历的特点(最后一个节点为根节点),将中序遍历序不断递归分割的方法,上面这篇文章已经讲的很详细了,这里就不再重复了哟(^U^)ノ~YO
这里变化的一点就是,除了记录index(index并不一定连续,只是为了标明层次遍历的输出顺序),还要记录层数(偶数层从左向右,奇数层从右向左)。
在排序函数cmp1中,层数小的优先输出,层数相同的看是奇数层还是偶数层,奇数层index大的先输出,偶数层index小的先输出:
3,AC代码
#include<bits/stdc++.h>
using namespace std;
struct node{
int key, level, index;
};
int N, in[35], post[35];
vector<node> ans;
bool cmp1(node a, node b){
if(a.level != b.level) //层数小的在前面
return a.level < b.level;
else{
if(a.level % 2 == 0) //偶数层 从左向右
return a.index < b.index;
else //奇数层 从右向左
return a.index > b.index;
}
}
//root后序遍历中的根节点 left/right中序遍历左右端点 dep树的深度 index正常层次遍历输出顺序
void levelOrder(int root, int left, int right, int dep, int index){
if(left > right){ // !!!不是if(left >= right)
return;
}
ans.push_back({post[root], dep, index});
int i = left;
while(i <= right && in[i] != post[root])
i++;
levelOrder(root-(right-i)-1, left, i-1, dep+1, 2*index); // !!!不是levelOrder(root-(right-i), left, i-1, dep+1, 2*dep);
levelOrder(root-1, i+1, right, dep+1, 2*index+1); // !!!不是levelOrder(root-1, i+1, right, dep+1, 2*dep+1);
}
int main(){
#ifdef ONLINE_JUDGE
#else
freopen("1.txt", "r", stdin);
#endif // ONLINE_JUDGE
cin>>N;
for(int i = 0; i < N; i++){
scanf("%d", &in[i]);
}
for(int i = 0; i < N; i++){
scanf("%d", &post[i]);
}
levelOrder(N-1, 0, N-1, 1, 1);
sort(ans.begin(), ans.end(), cmp1);
for(int i = 0; i < ans.size(); i++)
printf("%d%c", ans[i].key, i!=N-1 ? ' ':'\n');
return 0;
}
4,解题过程
一发入魂