原题目: 1020 Tree Traversals (25 分)
题意
给出二叉树结点数N以及后序和中序序列(无重复值),
👉输出层序序列。
分析
&1 法一:建树法
- 用DFS递归建树。
- 用BFS按层序遍历顺序输出。
&2 法二:无需建树法⭐
用DFS中序后序转先序的方法,但是先序序列除了存data以外,多存一个按完全二叉树标准存放的 index。
实现思路:
- DFS的参数多一个 index,表示在完全二叉树中的下标——递归式中,往左子树递归则 2×index,往右子树递归则 2×index+1。
- 先序序列的元素为结构体类型——含data数据域和index下标。
- 含index成员的先序序列转层序序列——用sort+cmp按index递增排列即可。
知识点
- 不要局限队列或序列的元素类型,也不要局限结构体类型变量包含的成员。
- 无需建树的中序后序转层序——① 中序后序转先序,先序元素含data和在完全二叉树中的index;② 先序序列按index递增排序即得层序序列(复习sort和cmp 👉传送门:算法入门之排序(《算法笔记》)。
CODE
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
int n;
vector<int> post, in;
struct node{
int index; //在二叉树中的下标(按完全二叉树)
int data;
};
vector<node> ans;
bool cmp(node a, node b){
return a.index<b.index;
}
void DFS(int postl, int postr, int inl, int inr, int index); //index为在完全二叉树存放标准下的下标
int main()
{
cin >> n;
post.resize(n+1), in.resize(n+1);
for ( int i=1; i<=n; i++ ) cin >> post[i];
for ( int i=1; i<=n; i++ ) cin >> in[i];
//层序序列
DFS(1, n, 1, n, 1);
sort(ans.begin(), ans.end(), cmp);
//输出
cout << ans[0].data;
for ( int i=1; i<n; i++ )
printf(" %d", ans[i].data);
return 0;
}
void DFS(int postl, int postr, int inl, int inr, int index){ //中序后序转先序
if ( inl>inr ) return;
//找根结点的中序下标
int k = inl;
while( in[k]!=post[postr] ) k++;
//访问根结点:入ans数组
ans.push_back(node{index, post[postr]});
//左右子树
DFS(postl, postl+(k-inl)-1, inl, k-1, 2*index); //按完全二叉树的下标规律
DFS(postl+k-inl, postr-1, k+1, inr, 2*index+1);
}