题目描述
假设二叉树中的所有键值都是不同的正整数。唯一的二元树可以通过给定的后序和顺序遍历序列,或前序和顺序遍历序列来确定。但是,如果仅给出后序和前序遍历序列,则相应的树可能不再是唯一的。
现在给出一对后序和前序遍历序列,您应该输出树的相应的中序遍历序列。如果树不是唯一的,只需输出其中任何一个。
输入
每个输入文件包含一个测试用例。对于每种情况,第一行给出正整数N(≤30),即二叉树中的节点总数。第二行给出预订序列,第三行给出后序序列。一行中的所有数字都用空格分隔。
输出
对于每个测试用例,如果树是唯一的,则首先是行中的Yes,否则是No。然后在下一行中打印相应二叉树的中序遍历序列。如果解决方案不是唯一的,那么任何答案都可以。保证至少存在一种解决方案。一行中的所有数字必须用一个空格分隔,并且行的末尾不能有额外的空格。
样例输入 复制
7
1 2 3 4 6 7 5
2 6 7 4 5 3 1
样例输出 复制
Yes
2 1 6 4 7 3 5
#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;
const int maxn = 40;
int pos1[maxn], pos2[maxn];
int a1[maxn], a2[maxn];
int L[maxn], size[maxn], R[maxn];
bool book = false;
void dfs(int l, int r) {
if (l >= r)
return;
int root = a1[l];
int lroot = a1[l + 1];
int rroot = a2[pos2[root] - 1];
if (lroot == rroot) {
R[root] = rroot;
book = true;
dfs(l + 1, r);
return;
}
int lsize = pos1[rroot] - pos1[lroot];
L[root] = lroot;
R[root] = rroot;
dfs(l + 1, l + lsize);
dfs(l + lsize + 1, r);
}
void dfs3(int now) {
if (L[now])
dfs3(L[now]);
cout << now << " ";
if (R[now])
dfs3(R[now]);
if (now == a1[1])
cout << endl;
}
int main() {
int n;
cin >> n;
for (int i = 1; i <= n; i++) {
size[i] = 1;
cin >> a1[i];
pos1[a1[i]] = i;
}
for (int i = 1; i <= n; i++) {
cin >> a2[i];
pos2[a2[i]] = i;
}
dfs(1, n);
if (book)
cout << "No" << endl;
else
cout << "Yes" << endl;
dfs3(a1[1]);
return 0;
}
容易出现的问题:
- 缺少头文件
代码中应该加入 <cstdio>
和 <cstring>
头文件。
- 数组越界
代码中数组 pos1
和 pos2
的大小都只有 1010
,但是在输入中序遍历和后序遍历时,对应的数组应该定义为 maxn
。这样会导致后面调用这些数组时发生数组越界。
- 变量未初始化
代码中变量 book
未初始化,应为 false
。
- 递归越界
在 dfs
函数中,出现了 l+lsize+1
,其可达到的最大值为 n+1
。这个值超出了数组下标范围。需要用参数 r
代替。
- 换行符输出错误
在 dfs3
函数中,遍历完成后需要输出换行符。