三——问题 F: 树的遍历

题目描述

假设二叉树中的所有键值都是不同的正整数。唯一的二元树可以通过给定的后序和顺序遍历序列,或前序和顺序遍历序列来确定。但是,如果仅给出后序和前序遍历序列,则相应的树可能不再是唯一的。

现在给出一对后序和前序遍历序列,您应该输出树的相应的中序遍历序列。如果树不是唯一的,只需输出其中任何一个。

输入

每个输入文件包含一个测试用例。对于每种情况,第一行给出正整数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;
}

容易出现的问题: 

  1. 缺少头文件

代码中应该加入 <cstdio> 和 <cstring> 头文件。

  1. 数组越界

代码中数组 pos1 和 pos2 的大小都只有 1010,但是在输入中序遍历和后序遍历时,对应的数组应该定义为 maxn。这样会导致后面调用这些数组时发生数组越界。

  1. 变量未初始化

代码中变量 book 未初始化,应为 false

  1. 递归越界

在 dfs 函数中,出现了 l+lsize+1,其可达到的最大值为 n+1。这个值超出了数组下标范围。需要用参数 r 代替。

  1. 换行符输出错误

在 dfs3 函数中,遍历完成后需要输出换行符。

猜你喜欢

转载自blog.csdn.net/mojingweng/article/details/131229540