【剑指紫金港】1119 Pre- and Post-order Traversals 全网最易懂的非递归版

A 1119 Pre- and Post-order Traversals

题目链接

Problem Description

Suppose that all the keys in a binary tree are distinct positive integers. A unique binary tree can be determined by a given pair of postorder and inorder traversal sequences, or preorder and inorder traversal sequences. However, if only the postorder and preorder traversal sequences are given, the corresponding tree may no longer be unique.

Now given a pair of postorder and preorder traversal sequences, you are supposed to output the corresponding inorder traversal sequence of the tree. If the tree is not unique, simply output any one of them.

Input

Each input file contains one test case. For each case, the first line gives a positive integer N (≤ 30), the total number of nodes in the binary tree. The second line gives the preorder sequence and the third line gives the postorder sequence. All the numbers in a line are separated by a space.

Output

For each test case, first printf in a line Yesif the tree is unique, or Noif not. Then print in the next line the inorder traversal sequence of the corresponding binary tree. If the solution is not unique, any answer would do. It is guaranteed that at least one solution exists. All the numbers in a line must be separated by exactly one space, and there must be no extra space at the end of the line.

Sample Input 1:

7
1 2 3 4 6 7 5
2 6 7 4 5 3 1

Sample Output 1:

Yes
2 1 6 4 7 3 5

Sample Input 2:

4
1 2 3 4
2 4 3 1

Sample Output 2:

No
2 1 3 4

题目大意

给出先序序列和后序序列,求中序序列,如果不唯一,任意输出一种即可。

解题思路

先要理解为什么已知先序和后序无法确定唯一的中序。观察一下先序根 左 右和后序左 右 根。对于先序序列中的某个节点k[i]来说,它的左儿子必然是k[i+1],然后到后序序列中找到这个i节点的位置a[j](即k[i]=a[j]),则i节点的右儿子必然是a[j-1]。当每一个i节点的k[i+1]和a[j-1]都不相等时,可以唯一确定一颗二叉树,当出现相等的情况时,可能k[i+1]和a[j-1]都是左儿子,也可能都是右儿子,这时中序序列不唯一。先建立一个结构体数组,通过以上规则更新每个节点的左右孩子节点,然后dfs得出中序序列,同时设立一个vis数组做标记,我们遍历先序序列时是把每个点都当成根节点来处理的,如果一个根节点的左孩子或右孩子比这个根节点还早作为根节点来处理,那么不需要更新当前根节点的左右孩子信息(保持都是-1)。

AC代码
题目只说了节点小于等于30没说节点编号小于等于30,maxn设置成35时有两个测试点有问题,设置成105时就AC了。还有如果最后不输出"\n"就导致格式错误,题目也没说,希望正规考试不会有这种情况

#include<bits/stdc++.h>
using namespace std;
const int maxn = 105;
int pre[maxn],pos[maxn],in[maxn],vis[maxn],n,ind=0,flag=1;
struct node{
    int l,r;
}tree[maxn];
void dfs(int x){
    if(tree[x].l!=-1) dfs(tree[x].l);
    in[ind++]=x;
    if(tree[x].r!=-1) dfs(tree[x].r);
}
int main(){
    for(int i=0;i<maxn;i++) tree[i].l=tree[i].r=-1;
    scanf("%d",&n);
    for(int i=0;i<n;i++) scanf("%d",&pre[i]);
    for(int i=0;i<n;i++) scanf("%d",&pos[i]);
    for(int i=0;i<n-1;i++){
        int root = pre[i];
        vis[root]=1;
        for(int j=1;j<n;j++){
            if(root==pos[j]){
                if(pre[i+1]==pos[j-1]){
                    flag=0;
                    if(!vis[pre[i+1]]) tree[root].l=pre[i+1];
                }else{
                    if(!vis[pre[i+1]] && !vis[pos[j-1]]){
                        tree[root].l=pre[i+1];
                        tree[root].r=pos[j-1];
                    }
                }
                break;
            }
        }
    }
    dfs(pre[0]);
    if(flag){
        printf("Yes\n");
    }else{
        printf("No\n");
    }
    for(int i=0;i<n;i++){
        if(i>0) printf(" ");
        printf("%d",in[i]);
    }
    printf("\n");
    return 0;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

征服所有不服

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值