这里洛谷的题目提交不了,于是在山东理工大学的ACMOJ上找到了一个类似的题目,不过不是让输出后续遍历的结果,而是输出二叉树的深度。
其实我们把二叉树已经构造好的前提下,输出深度或者后序其实都很easy!
洛谷提交地址
山东理工ACM系统提交地址
思路:
(可能说的不清楚,你可以根据题目给的前序和中序样例进行手算)
1、题目中已经给出了前序和中序遍历的结果,分别定义为a和b
根左右 左根右
2、我们先看前序遍历的结果字符串a,第一个字符一定是根节点。
同时在中序列字符串b中找到根节点的下标,那么在这个下标的左边,一定都是
左子树,而右边直至b末尾的字符一定都是右子树(因为中序遍历为 左-根-右)
3、那么这里我们可以将a进行划分成两个片段
从根节点往后数k个(这里的k大小=根节点在b中的下标),这是第一个片段,和b中根节点的左边【对应】
然后其余的直至末尾是第二个片段,和b中根节点的右边【对应】
4、那么新形成的两对字符一一对应,进行递归处理。
还有很重要的一点是,根节点的左右子节点,正好分别是a新划分的第一个片段的第一个字符
#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define sf(x) scanf("%d", &x);
#define de(x) cout << x << " ";
#define Pu puts("");
string a, b;
struct E {int l, r;
} e[75];
void fun(string a, string b, char ch, int op) {if (op == 1)e[ch - 'A'].l = a[0] - 'A';else if (op == 2)e[ch - 'A'].r = a[0] - 'A';int t = b.find(a[0]);if (t != 0) { // 左fun(a.substr(1, t), b.substr(0, t), a[0], 1);}if (t != b.size() - 1) { // 右fun(a.substr(t + 1), b.substr(t + 1), a[0], 2);}
}
int getDep(int x) { // 得到深度if (x == -1)return 0;if (e[x].l == -1 && e[x].r == -1)return 0;return max(getDep(e[x].l), getDep(e[x].r)) + 1;
}
int main() {int T;while (cin >> T) {cin >> a >> b;for (int i = 0; i < 70; i++) {e[i].l = e[i].r = -1; // 初始化,便于后序遍历输出}int t = b.find(a[0]);if (t != 0) { // 左fun(a.substr(1, t), b.substr(0, t), a[0], 1);}if (t != b.size() - 1) { // 右fun(a.substr(t + 1), b.substr(t + 1), a[0], 2);}de(getDep(a[0] - 'A') + 1);Pu;}return 0;
}