其他分享
首页 > 其他分享> > 【剑指紫金港】1119 Pre- and Post-order Traversals 全网最易懂的非递归版

【剑指紫金港】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);
    return ;
}

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;
}

标签:Pre,pre,int,Traversals,tree,maxn,1119,line,节点
来源: https://blog.csdn.net/qq_43561345/article/details/113799424