题目
题目大意
给出一棵树的中序和后序遍历,要求按层序输出这棵树,但是按照从左到右,再从右到左,再从左到右的顺序。
思路
由中序遍历和后序遍历可以构造出一棵二叉树。观察题目中要求的输出顺序,发现层数为奇数的都是逆序输出(层数从1开始),层数为偶数的顺序输出。因此构建好二叉树后,可以按照普通的层序遍历进行,只不过队列元素还需要和层数绑定,子节点的层数 = 父节点的层数 + 1。然后用一个二维数组存储各个层数的节点,需要逆序输出的层用reverse()翻转即可。
最后的输出要求不能有多余的空格,所以又加了一个res数组,存储要输出的结果。
代码
#include <iostream>
#include <vector>
#include <queue>
#include <algorithm>
using namespace std;
int n;
vector<int> in;
vector<int> post;
vector<vector<int>> v; // 存放相同层数的节点
struct node{
int id;
node * lchild, * rchild;
int level; // 每个节点的层数,在bfs中用
};
void buildTree(node * &root, int il, int ir, int pl, int pr){
if (il > ir || pl > pr){
return;
}
root = new node();
root->id = post[pr];
int pos;
for (int i = 0; i < n; i++){
if (in[i] == root->id){
pos = i;
break;
}
}
root->lchild = root->rchild = nullptr;
buildTree(root->lchild, il, pos - 1, pl, pl + (pos-1-il));
buildTree(root->rchild, pos + 1, ir, pl + (pos-il), pr - 1);
}
void bfs(node * root){
queue<node *> q;
root->level = 1;
q.push(root);
v[root->level].push_back(root->id);
while (!q.empty()){
node * now = q.front();
q.pop();
if (now->lchild){
now->lchild->level = now->level + 1;
q.push(now->lchild);
v[now->lchild->level].push_back(now->lchild->id);
}
if (now->rchild){
now->rchild->level = now->level + 1;
q.push(now->rchild);
v[now->rchild->level].push_back(now->rchild->id);
}
}
}
int main(){
cin >> n;
in.resize(n);
post.resize(n);
v.resize(n + 1);
for (int i = 0; i < n; i++){
cin >> in[i];
}
for (int i = 0; i < n; i++){
cin >> post[i];
}
node * root = nullptr;
buildTree(root, 0, n - 1, 0, n - 1);
bfs(root);
vector<int> res;
for (int i = 1; i <= n; i++){
if ((int)v[i].size() == 0){
break;
}
if (i % 2 == 1){
reverse(v[i].begin(), v[i].end());
} // 第奇数层是逆序
for (int j = 0; j < (int)v[i].size(); j++){
res.push_back(v[i][j]);
}
}
for (int i = 0; i < (int)res.size(); i++){
cout << res[i];
if (i != (int)res.size() - 1){
cout << " ";
}
}
cout << endl;
return 0;
}