pat甲级1020 Tree traversals (后序+中序 ->层序)

第一次做不出来,学习了柳神的解法

pre函数的参数 root:根节点在后序中的位置;

start:子树在中序中开始位置序号;end:子树在中序中结束的位置序号

index:从0开始,每个节点的序号 左边是2*index+1,右边是2*index;

层序遍历即可按照index从小到大的顺序输出

#include <iostream>
#include "map"
#include "vector"
#include "algorithm"
using namespace std;
vector<int> pos,in;
map<int,int> m;
void pre(int root,int start,int end,int index){
    if (start>end) return;
    int i = start;
    while (i<end && in[i]!=pos[root]) i++;
    m[index] = pos[root];
    pre(root-1-end+i,start,i-1,2*index+1);
    pre(root-1,i+1,end,2*index+2);
}
int main() {
    int mm,temp;
    scanf("%d\n",&mm);
    pos.resize(mm);
    in.resize(mm);
    for (int i = 0; i < mm; ++i) {
        scanf("%d",&pos[i]);
    }
    for (int i = 0; i < mm; ++i) {
        scanf("%d",&in[i]);
    }
    pre(mm-1,0,mm-1,0);
    auto i = m.begin();
    printf("%d",i->second);
    while (++i != m.end()) printf(" %d",i->second);
}

这样结合算法笔记上的代码好像更好理解一些:

[postL,postR]当前二叉树的后序序列区间,[inL,inR]当前二叉树的中序序列区间,index表示当前元素序号
#include <iostream>
#include "map"
#include "vector"
#include "algorithm"
using namespace std;
vector<int> pos,in;
map<int,int> m;
//void pre(int root,int start,int end,int index){
//    if (start>end) return;
//    int i = start;
//    while (i<end && in[i]!=pos[root]) i++;
//    m[index] = pos[root];
//    pre(root-1-end+i,start,i-1,2*index+1);
//    pre(root-1,i+1,end,2*index+2);
//}
//[postL,postR]当前二叉树的后序序列区间,[inL,inR]当前二叉树的中序序列区间,index表示当前元素序号
void pre(int postL,int postR,int inL,int inR,int index){
    if(inL > inR) return;
    int i = inL;
    while (i<=inR && in[i]!=pos[postR]) i++;
    m[index] = pos[postR];
    int numleft = i - inL;
    pre(postL,postL+numleft-1,inL,i-1,2*index+1);
    pre(postL+numleft,postR-1,i+1,inR,2*index+2);
}
int main() {
    int mm,temp;
    scanf("%d\n",&mm);
    pos.resize(mm);
    in.resize(mm);
    for (int i = 0; i < mm; ++i) {
        scanf("%d",&pos[i]);
    }
    for (int i = 0; i < mm; ++i) {
        scanf("%d",&in[i]);
    }
    pre(0,mm-1,0,mm-1,0);
    auto i = m.begin();
    printf("%d",i->second);
    while (++i != m.end()) printf(" %d",i->second);
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值