PAT甲级 1020 Tree Traversals (25 分)

题目: 戳这里

题意:已知后序、中序遍历,求层序遍历。

解题思路:
需要抓住后序、中序的遍历顺序。
后序:左右根,则根一直在最后面。
中序:左根右,则根的左边为左子树,右边为右子树。
通过后序遍历锁定根的位置;
在中序遍历中找到根,则其左边的为左子树,右边的为右子树,于是我们得到了左右子树的长度;
在后序遍历中,根的左边就是右子树的根,整个长度减去右子树的长度和跟,就是左子树,且左子树的根在最右边。
通过以上思路,进行树的遍历,在用一个index记录每个节点在树中的位置(在数组中,我们可以用root, root<<1, root<<1|1的关系描述根与左右子树的位置关系),将得到的所有点根据index的大小进行排序,即可得到答案。

代码:

#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e4 + 10;
const int maxe = 1e2+10;
const int inf = 0x3f3f3f3f;
typedef long long ll;
int post[maxn], in[maxn];
struct nod {
    int index;
    int val;
}level[maxn];
bool cmp(nod a, nod b) {
    return a.index < b.index;
}
int cnt = 0;
void build(int root, int bg, int ed, int index) {
    if(bg > ed) return;
    int i = bg;
    while(i <= ed && post[root] != in[i]) ++i;
    level[cnt].index = index; level[cnt++].val = post[root];
    //printf("%d %d\n", index, post[root]);
    build(root - (ed - i + 1),bg, i-1, index<<1);
    build(root - 1, i+1, ed, index<<1|1);
}
int main() {
    int n;
    scanf("%d", &n);
    for(int i = 1; i <= n; ++i) {
        scanf("%d", &post[i]);
    }
    for(int i = 1; i <= n; ++i) {
        scanf("%d", &in[i]);
    }
    build(n, 1, n, 1);

    sort(level, level + cnt, cmp);
    printf("%d", level[0].val);
    for(int i = 1; i < cnt; ++i) {
        printf(" %d", level[i].val);
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值