题目描述:根据给定的一棵二叉树的后序遍历和中序遍历结果,输出该树的先序遍历结果。
输入格式:
第一行给出正整数N(≤30),是树中结点的个数。随后两行,每行给出N个整数,分别对应后序遍历和中序遍历结果,数字间以空格分隔。题目保证输入正确对应一棵二叉树。
输出格式:
在一行中输出Preorder: 以及该树的先序遍历结果。数字间有1个空格,行末不得有多余空格。
输入样例:
7
2 3 1 5 7 6 4
1 2 3 4 5 6 7
输出样例:
Preorder: 4 1 3 2 6 5 7
后序遍历确定根 中序遍历确定左右子树
用哈希表记录中序遍历对应节点的下标
先构造再遍历
#include<iostream>
#include<vector>
#include<queue>
#include<unordered_map>
using namespace std;
const int N = 35;
int postorder[N], inorder[N];
unordered_map<int, int> l, r; //存左右子树
unordered_map<int, int> pos; //存中序对应下标
vector<int> res;
int n;
int build(int il, int ir, int pl, int pr){ //中序遍历的左右区间和后序遍历的左右区间
int root = postorder[pr]; //找到根节点
int t = pos[root]; //找到根节点在中序的下标
if(t > il) l[root] = build(il, t-1, pl, t-1-il+pl); //左子树不为空 t-1-il = x-pl
if(t < ir) r[root] = build(t+1, ir, pr+t-ir, pr-1); //右子树不为空 ir-t-1 = pr-1-x
return root;
}
void preorder(int root){
res.push_back(root); //根
if(l.count(root)) preorder(l[root]); //左
if(r.count(root)) preorder(r[root]); //右
}
int main(){
cin >> n;
for(int i = 0; i < n; ++ i) cin >> postorder[i];
for(int i = 0; i < n; ++ i){
cin >> inorder[i];
pos[inorder[i]] = i; //记录中序遍历对应节点的下标
}
int root = build(0, n-1, 0, n-1); //构造二叉树
preorder(root); //前序遍历递归 层序遍历可以用bfs
printf("Preorder: %d", res[0]);
for(int i = 1; i < n; ++ i) cout << ' ' << res[i]; //行末不能有空格
return 0;
}