PAT_甲级_1127 ZigZagging on a Tree (30point(s)) (C++)【中序+后序=》层次(高阶版)】

目录

1,题目描述

题目描述

2,思路

3,AC代码

4,解题过程


1,题目描述

Sample Input:

8
12 11 20 17 1 15 8 5
12 20 17 11 15 8 5 1

 

Sample Output:

1 11 5 8 17 12 20 15

题目描述

在中序+后序=》层次的基础上更进了一步,偶数层从左向右,奇数层从右向左;

 

2,思路

类似于这一题@&再见萤火虫&【PAT_甲级_1020 Tree Traversals (25分) (C++)【树的遍历】】中序+后序=》层次;

关于如何根据后序遍历的特点(最后一个节点为根节点),将中序遍历序不断递归分割的方法,上面这篇文章已经讲的很详细了,这里就不再重复了哟(^U^)ノ~YO

这里变化的一点就是,除了记录index(index并不一定连续,只是为了标明层次遍历的输出顺序),还要记录层数(偶数层从左向右,奇数层从右向左)。

在排序函数cmp1中,层数小的优先输出,层数相同的看是奇数层还是偶数层,奇数层index大的先输出,偶数层index小的先输出:

 

3,AC代码

#include<bits/stdc++.h>
using namespace std;
struct node{
    int key, level, index;
};
int N, in[35], post[35];
vector<node> ans;
bool cmp1(node a, node b){
    if(a.level != b.level)      //层数小的在前面
        return a.level < b.level;
    else{
        if(a.level % 2 == 0)    //偶数层 从左向右
            return a.index < b.index;
        else                    //奇数层 从右向左
            return a.index > b.index;
    }
}
//root后序遍历中的根节点 left/right中序遍历左右端点 dep树的深度 index正常层次遍历输出顺序
void levelOrder(int root, int left, int right, int dep, int index){
    if(left > right){   // !!!不是if(left >= right)
        return;
    }
    ans.push_back({post[root], dep, index});
    int i = left;
    while(i <= right && in[i] != post[root])
        i++;
    levelOrder(root-(right-i)-1, left, i-1, dep+1, 2*index);    // !!!不是levelOrder(root-(right-i), left, i-1, dep+1, 2*dep);
    levelOrder(root-1, i+1, right, dep+1, 2*index+1);           // !!!不是levelOrder(root-1, i+1, right, dep+1, 2*dep+1);
}
int main(){
#ifdef ONLINE_JUDGE
#else
    freopen("1.txt", "r", stdin);
#endif // ONLINE_JUDGE
    cin>>N;
    for(int i = 0; i < N; i++){
        scanf("%d", &in[i]);
    }
    for(int i = 0; i < N; i++){
        scanf("%d", &post[i]);
    }
    levelOrder(N-1, 0, N-1, 1, 1);
    sort(ans.begin(), ans.end(), cmp1);
    for(int i = 0; i < ans.size(); i++)
        printf("%d%c", ans[i].key, i!=N-1 ? ' ':'\n');
    return 0;
}

4,解题过程

一发入魂

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值