1020 Tree Traversals (25)-PAT甲级真题

给定一棵二叉树的后序遍历和中序遍历,请你输出其层序遍历的序列

这里有个技巧,就是层序遍历二叉树中,各节点标号的关系,左子树和其父节点的关系:index=2*index_father,比如下图中1和2,2和4,3和6;右子树和其父节点的关系:index=2*index_father+1,比如下图中1和3,2和5,3和7。所以这里就不需要先构造二叉树再遍历这么麻烦了,递归函数增加一个参数index代表层序遍历的编号,每次记录当前的根节点,并于编号绑定(用map存储,还可自动排序),参考柳神AC代码如下:

         1
     2        3
4      5  6        7

#include<bits/stdc++.h>
using namespace std;
int n;
vector<int> post;
vector<int> in;
map<int,int> m;//<index,node_id>
//index用于标记层序遍历每个节点的标号(从1开始),root用于记录post_order中当前根的索引
//         1
//     2        3
// 4      5  6        7
void solve(int root,int in_start,int in_end,int index){
    if(in_start>in_end) return;//最后一层了
    m[index]=post[root];
    int i=in_start;
    for(;i<in_end&&in[i]!=post[root];i++);//i是在in_order中root的位置
    solve(root-(in_end-i+1),in_start,i-1,2*index);
    solve(root-1,i+1,in_end,2*index+1);
}

int main(){
    scanf("%d",&n);
    int num;
    for(int i=0;i<n;i++){
        scanf("%d",&num);
        post.push_back(num);
    }
    for(int i=0;i<n;i++){
        scanf("%d",&num);
        in.push_back(num);
    }
    solve(n-1,0,n-1,1);
    for(auto it=m.begin();it!=m.end();it++){
        printf(it==m.begin()?"%d":" %d",it->second);
    }
}

已知后序和中序,还能这样:

原文链接:https://blog.csdn.net/liuchuo/article/details/81436657

    private static Node build(int[] postOrder, int[] inOrder, int postStart, int postEnd, int inStart, int inEnd) {
        if (postStart > postEnd) {
            return null;
        }
        if (postStart == postEnd) {
            return new Node(postOrder[postStart]);
        }
        int root = postOrder[postEnd--];
 
        //find root in inOrder
        int inIndex = -1;
        for (int i = inStart; i <= inEnd; i++) {
            if (root == inOrder[i]) {
                inIndex = i;
                break;
            }
        }
        //recursion build
        int leftSize = inIndex - inStart;
        int rightSize = inEnd - inIndex;
        Node rootNode = new Node(root);
        rootNode.left = build(postOrder, inOrder,
                postStart, postStart + leftSize - 1,
                inStart, inIndex - 1);
        rootNode.right = build(postOrder, inOrder, postEnd - rightSize + 1, postEnd, inIndex + 1, inEnd);
        return rootNode;
    }

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值