PAT A1119 Pre- and Post-order Traversals [seeking sequence in the preamble sequence]

Title Description

Link
number of a given tree node n, and its front and rear sequence preorder traversal, in order traversal its output, if the preorder No outputs are not unique, and wherein one of the output sequence can, If the only inorder traversal outputs Yes, and outputs it in order

analysis

  • Analysis of the title given positive and negative examples can be found, after the last recursion into a single sub-tree, its roots are left, right, it is also the root, not the unique. In this case, the child can easily specify the right or left as a child
  • Specifically, looking from front to back of the first order, for the order from the back to find to find the root of the left and right subtree, to determine the scope of the left and right subtrees recursively
  • When recursion somewhere, found that the current node! ! Roots and root right subtree of the left subtree overlap \ (i == prel + 1 \ ) , then ( \ (I \) is the root of the right subtree, \ (Prel \) is the current root node, \ (prel + 1 \) is the root of the left subtree), the recursive down, just to the right sub-tree recursively
  • Also note that recursion in the end, only one node that is \ (Prel == PreR \) , direct return root, and no longer the downward recursion
  • FIG lower painted, like simulation
#include<bits/stdc++.h>
using namespace std;

const int maxn = 40;
int pre[maxn],post[maxn];
int n;
struct node{
    int data;
    node *lchild,*rchild;
};
//root为后序序列的根结点,st,ed为先序的范围
vector<int> ans;
bool flag = true;
node *create(int prel, int prer, int postl, int postr){
    if(prel > prer) return NULL;
    //建立此状态下的根结点
    node *root = new node;
    root->data = pre[prel];
    root->lchild = NULL;
    root->rchild = NULL;
    if(prel==prer){
        return root;
    }
    //找左右子树的范围
    //在先序里面找到右子树根节点的位置
    int i;
    for(i=prel;i<=prer;i++){
        if(post[postr-1] == pre[i]){
            break;
        }
    }
    if(i - prel > 1){
        //左子树的范围: prel+1,i-1, 长度i-1-prel 
        root->lchild = create(prel+1,i-1,postl,postl+i-prel-2); //左子树的范围
        //右子树的范围: 
        root->rchild = create(i, prer, postl+i-prel-1, postr-1);
    }else{ //i==prel+1 即左右子树的根节点重合了
        flag = false;
        root->rchild = create(i, prer, postl+i-prel-1, postr-1); //就当成右子树
    }
    return root;
}

void inorder(node *root){
    if(!root) return;
    inorder(root->lchild);
    ans.push_back(root->data);
    inorder(root->rchild);
}

int main(){
    cin>>n;
    for(int i=0;i<n;i++) cin>>pre[i];
    for(int i=0;i<n;i++) cin>>post[i];
    node *root = create(0,n-1,0,n-1);
    inorder(root);
    if(flag) printf("Yes\n");
    else printf("No\n");
    for(int i=0;i<ans.size();i++){
        if(i==0)printf("%d",ans[i]);
        else printf(" %d",ans[i]);
    }
    printf("\n");
}

Guess you like

Origin www.cnblogs.com/doragd/p/11290774.html