目录
1,题目描述
Sample Input:
7
2 3 1 5 7 6 4
1 2 3 4 5 6 7
Sample Output:
4 1 6 3 5 7 2
题目大意
根据给出的二叉树的postorder(后序遍历) and inorder(中序遍历),输出level(层次遍历)
2,思路
参考柳神的思路。
学过数据结构的同学可能比较清楚,通过树的中序和后序遍历,可以构建一颗完整的二叉树,根据得出的二叉树并利用队列,可以得到层次遍历。
在这里,可以利用中序和后续遍历推出先序遍历,只需要在先序遍历过程中记录节点的下标,按下标排序后,输出的值即为层次遍历的输出结果。
树的遍历
由中序和后序遍历如何推出二叉树,可以参考这篇文章@那记忆微凉 【已知中序遍历和后序遍历,画出此二叉树】
- 先序遍历:根左右
- 中序遍历:左根右
- 后序遍历:左右根
数据结构
- struct node{int index, value;}:index按层次遍历时输出的先后顺序,value输出的值;
- vector<int> in, post:存放树的两种遍历顺序;
- vector<node> ans:存放最终答案
关键点
以题目中所给例子为参考:
postOrder:2 3 1 5 7 6 4
inOrder:1 2 3 4 5 6 7
- 后序遍历的最后一个节点(4)为二叉树的根节点。这个根节点将整棵树(中序遍历中)分成了左右两棵子树,左子树节点为1 2 3、右子树节点为5 6 7;
- 在后序遍历(2 3 1 5 7 6 4)中可以看出,左子树的根节点为1,右子树的根节点为6;(将一棵大树,划分为两棵小树,这就是递归的原理)
- 具体实现时,以后序遍历为准,在中序遍历找到根节点位置得出左右子树的节点数目,确定后序遍历新的始末位置,进行递归;
- 显然在遍历过程中,先确定根节点,然后确定左右子树的根节点……这便是层次遍历的输出顺序,因此,在遍历时,只需加上index值,使其在向下遍历时不断递增(左子树:2*index+1, 右子树:2*index+2),然后按照index排序,输出value值即可;
- pre(root-(end-i)-1, start, i - 1, 2 * index + 1)(递归求左子树)这里说明一下,左子树的根节点如何确定:root(原根节点在后序遍历中的位置),i(根节点在中序遍历中的位置),end-i(右子树节点数目),-1(即左子树根节点在后序遍历中的位置);
3,代码
#include<iostream>
#include<stdio.h>
#include<vector>
#include<map>
#include<algorithm>
using namespace std;
struct node{
int index, value;
};
bool cmp(node a, node b){
return a.index < b.index;
}
vector<node> ans;
vector<int> in, post;
//root start end均指后序遍历时的下标
void pre(int root, int start, int end, int index){ //递归实现
if(start > end) return;//
int i = start;
while(i <= end && in[i] != post[root]) i++; //找到根节点(后序遍历的最后一个节点)在中序遍历序列中的位置
ans.push_back({index, post[root]}); //根节点入栈
pre(root-(end-i)-1, start, i - 1, 2 * index + 1); //递归处理左右两棵子树 并更新index(index可能不连续)
pre(root - 1, i + 1, end, 2 * index + 2);
}
int main(){
//#ifdef ONLINE_JUDGE
//#else
// freopen("1.txt", "r", stdin);
//#endif
int n;
scanf("%d", &n);
in.resize(n);
post.resize(n);
for(int i = 0; i < n; i++) scanf("%d", &post[i]);
for(int i = 0; i < n; i++) scanf("%d", &in[i]);
pre(n-1, 0, n-1, 0);
sort(ans.begin(), ans.end(), cmp);
printf("%d", ans[0].value);
for(int i = 1; i < ans.size(); i++){
printf(" %d", ans[i].value);
}
return 0;
}