题目: 戳这里
题意:已知后序、中序遍历,求层序遍历。
解题思路:
需要抓住后序、中序的遍历顺序。
后序:左右根,则根一直在最后面。
中序:左根右,则根的左边为左子树,右边为右子树。
通过后序遍历锁定根的位置;
在中序遍历中找到根,则其左边的为左子树,右边的为右子树,于是我们得到了左右子树的长度;
在后序遍历中,根的左边就是右子树的根,整个长度减去右子树的长度和跟,就是左子树,且左子树的根在最右边。
通过以上思路,进行树的遍历,在用一个index记录每个节点在树中的位置(在数组中,我们可以用root, root<<1, root<<1|1的关系描述根与左右子树的位置关系),将得到的所有点根据index的大小进行排序,即可得到答案。
代码:
#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e4 + 10;
const int maxe = 1e2+10;
const int inf = 0x3f3f3f3f;
typedef long long ll;
int post[maxn], in[maxn];
struct nod {
int index;
int val;
}level[maxn];
bool cmp(nod a, nod b) {
return a.index < b.index;
}
int cnt = 0;
void build(int root, int bg, int ed, int index) {
if(bg > ed) return;
int i = bg;
while(i <= ed && post[root] != in[i]) ++i;
level[cnt].index = index; level[cnt++].val = post[root];
//printf("%d %d\n", index, post[root]);
build(root - (ed - i + 1),bg, i-1, index<<1);
build(root - 1, i+1, ed, index<<1|1);
}
int main() {
int n;
scanf("%d", &n);
for(int i = 1; i <= n; ++i) {
scanf("%d", &post[i]);
}
for(int i = 1; i <= n; ++i) {
scanf("%d", &in[i]);
}
build(n, 1, n, 1);
sort(level, level + cnt, cmp);
printf("%d", level[0].val);
for(int i = 1; i < cnt; ++i) {
printf(" %d", level[i].val);
}
return 0;
}