天梯赛 L2-006 树的遍历 (25 分)
题目
给定一棵二叉树的中序遍历和前序遍历,请你先将树做个镜面反转,再输出反转后的层序遍历的序列。所谓镜面反转,是指将所有非叶结点的左右孩子对换。这里假设键值都是互不相等的正整数
输入格式
输入第一行给出一个正整数 N ( ≤ 30 ) N(≤30) N(≤30),是二叉树中结点的个数。第二行给出其中序遍历序列。第三行给出其前序遍历序列。数字间以空格分隔。
输出格式:
在一行中输出该树反转后的层序遍历的序列。数字间以1个空格分隔,行首尾不得有多余空格。
测试样例
输入样例:
7
1 2 3 4 5 6 7
4 1 3 2 6 5 7
输出样例:
4 6 1 7 5 3 2
简单分析:
和L2-006几乎一模一样,都是使用静态数组建立树,然后做一个bfs即可。
代码
静态结构体实现
#include <iostream>
#include <algorithm>
#include <queue>
using namespace std;
const int N = 10010, INF = -1e9;
int n;
int in[N], pre[N];
int head;
struct Node {
int l, r, v; // v是当前节点的数值
}node[N]; // 树,下标从1开始
void build(int l, int r, int n) {
if (l >= r) {
node[n].v = INF;
return;
}
int root = pre[head++]; // 节点值
node[n] = { 2 * n, 2 * n + 1, root }; // 树的左右儿子以及数值
int x = find(in, in + r, root) - in; // 查找根节点,也可以用for循环实现
build(l, x, 2 * n); // 递归建立左子树
build(x + 1, r, 2 * n + 1); // 递归建立右子树
}
void bfs() {
queue<int> q;
q.push(1);
while (q.size()) {
auto t = q.front();
q.pop();
if (node[t].v != INF) {
if (t == 1) cout << node[t].v;
else cout << " " << node[t].v;
q.push(node[t].r); // 依题意,要镜像,颠倒左右儿子入队顺序即可
q.push(node[t].l);
}
}
}
int main() {
cin >> n;
for (int i = 0; i < n; i++) cin >> in[i];
for (int i = 0; i < n; i++) cin >> pre[i];
head = 0;
build(0, n, 1); // 树下标从1开始
bfs();
return 0;
}
感悟与收获
想着一通百通呢~