二叉树-先序+中序序列,输出后序遍历序列 C++代码实现

这里洛谷的题目提交不了,于是在山东理工大学的ACMOJ上找到了一个类似的题目,不过不是让输出后续遍历的结果,而是输出二叉树的深度。
其实我们把二叉树已经构造好的前提下,输出深度或者后序其实都很easy!

洛谷提交地址

山东理工ACM系统提交地址

思路
(可能说的不清楚,你可以根据题目给的前序和中序样例进行手算)

1、题目中已经给出了前序和中序遍历的结果,分别定义为a和b
根左右 左根右

2、我们先看前序遍历的结果字符串a,第一个字符一定是根节点。
同时在中序列字符串b中找到根节点的下标,那么在这个下标的左边,一定都是
左子树,而右边直至b末尾的字符一定都是右子树(因为中序遍历为 左-根-右)

3、那么这里我们可以将a进行划分成两个片段
从根节点往后数k个(这里的k大小=根节点在b中的下标),这是第一个片段,和b中根节点的左边【对应】
然后其余的直至末尾是第二个片段,和b中根节点的右边【对应】

4、那么新形成的两对字符一一对应,进行递归处理。
还有很重要的一点是,根节点的左右子节点,正好分别是a新划分的第一个片段的第一个字符

#include 
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;
}

你可能感兴趣的:(刷题+算法,#,思维+模拟,洛谷题单,c++,算法,开发语言)