L2-006 树的遍历 (25 分)
给定一棵二叉树的后序遍历和中序遍历,请你输出其层序遍历的序列。这里假设键值都是互不相等的正整数。
输入格式:
输入第一行给出一个正整数N(≤30),是二叉树中结点的个数。第二行给出其后序遍历序列。第三行给出其中序遍历序列。数字间以空格分隔。
输出格式:
在一行中输出该树的层序遍历的序列。数字间以1个空格分隔,行首尾不得有多余空格。
输入样例:
7
2 3 1 5 7 6 4
1 2 3 4 5 6 7
输出样例:
4 1 6 3 5 7 2
思路
- 建树:递归建树,后序数组的最后一个是根,在中序中找到根的位置,根前面的就是左子树,根后面的就是右子树,然后左右子树再重复同样的操作。
- 层次遍历输出:简单的BFS
AC代码
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <set>
#include <vector>
#include <queue>
using namespace std;
const int maxn = 100010;
struct Node {
int L, R;
}node[35];
int post[35], in[35], n, root;
vector<int> v;
//post:la...ra in:lb...rb
int buildtree(int la, int ra, int lb, int rb) {
if(la > ra)
return 0;
int t = post[ra];
int p = lb;
while(in[p] != t)
p++;
node[t].L = buildtree(la, la + p - lb - 1, lb, p - 1);
node[t].R = buildtree(la + p - lb, ra - 1, p + 1, rb);
return t;
}
void bfs() {
queue<int> q;
q.push(root);
while(!q.empty()) {
int t = q.front();
q.pop();
v.push_back(t);
if(node[t].L != 0)
q.push(node[t].L);
if(node[t].R != 0)
q.push(node[t].R);
}
}
int main() {
// freopen("in.txt", "r",stdin);
// freopen("out.txt", "w", stdout);
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]);
}
root = buildtree(1, n, 1, n);
bfs();
for(int i = 0; i < v.size() - 1; i++) {
printf("%d ", v[i]);
}
printf("%d\n", v[v.size() - 1]);
return 0;
}