Binary Tree Traversals
Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 2442 Accepted Submission(s): 1063
Problem Description
A binary tree is a finite set of vertices that is either empty or consists of a root r and two disjoint binary trees called the left and right subtrees. There are three most important ways in which the vertices of a binary tree can be systematically traversed or ordered. They are preorder, inorder and postorder. Let T be a binary tree with root r and subtrees T1,T2.
In a preorder traversal of the vertices of T, we visit the root r followed by visiting the vertices of T1 in preorder, then the vertices of T2 in preorder.
In an inorder traversal of the vertices of T, we visit the vertices of T1 in inorder, then the root r, followed by the vertices of T2 in inorder.
In a postorder traversal of the vertices of T, we visit the vertices of T1 in postorder, then the vertices of T2 in postorder and finally we visit r.
Now you are given the preorder sequence and inorder sequence of a certain binary tree. Try to find out its postorder sequence.
In a preorder traversal of the vertices of T, we visit the root r followed by visiting the vertices of T1 in preorder, then the vertices of T2 in preorder.
In an inorder traversal of the vertices of T, we visit the vertices of T1 in inorder, then the root r, followed by the vertices of T2 in inorder.
In a postorder traversal of the vertices of T, we visit the vertices of T1 in postorder, then the vertices of T2 in postorder and finally we visit r.
Now you are given the preorder sequence and inorder sequence of a certain binary tree. Try to find out its postorder sequence.

Input
The input contains several test cases. The first line of each test case contains a single integer n (1<=n<=1000), the number of vertices of the binary tree. Followed by two lines, respectively indicating the preorder sequence and inorder sequence. You can assume they are always correspond to a exclusive binary tree.
Output
For each test case print a single line specifying the corresponding postorder sequence.
Sample Input
9 1 2 4 7 3 5 8 9 6 4 7 2 1 8 5 9 3 6
Sample Output
7 4 2 8 9 5 6 3 1
Source
Recommend
lcy
題意:
給你一個前序遍歷和中序遍歷,要求后序。
可以由先序和中序的性質得到 : 先序的第一個借點肯定是當前子樹的根借點, 那么在
中序中找到這個結點, 則這個結點左邊的節點屬於左子樹, 右邊的屬於右子樹。然后遞歸遍歷就可以了。
#include<iostream> #include<cstdio> #include<cstring> #include<stack> using namespace std; const int N=1010; int n,pre[N],in[N]; //先序數組和后序數組 stack<int> st; //存放父節點 void build(int l1,int r1,int l2,int r2){ //l1,r1,是先序遍歷的數組的開始和末尾,l2,r2是中序遍歷的數組的開始和末尾 int i,j; st.push(pre[l1]); //父節點入棧 for(i=l2;i<=r2;i++) if(in[i]==pre[l1]) //找到父節點在中序遍歷的位置i break; j=l1+(i-l2+1); //確定左子樹和右子樹在先序遍歷的分界點j,即右子樹的父節點 if(j<=r1 && i+1<=r2) //求解右子樹 build(j,r1,i+1,r2); if(l1+1<=j-1 && l2<=i-1) //求解左子樹 build(l1+1,j-1,l2,i-1); } int main(){ //freopen("input.txt","r",stdin); while(~scanf("%d",&n)){ for(int i=0;i<n;i++) scanf("%d",&pre[i]); for(int i=0;i<n;i++) scanf("%d",&in[i]); build(0,n-1,0,n-1); while(!st.empty()){ printf("%d",st.top()); st.pop(); if(!st.empty()) printf(" "); } printf("\n"); } return 0; }
#include<iostream> #include<cstdio> #include<cstring> #include<stack> #include<cstdlib> using namespace std; const int N=1010; struct Tree{ Tree *l,*r; int x; }tree; Tree *root; Tree *Create(int *pre,int *in,int n){ Tree *tmp; for(int i=0;i<n;i++) if(pre[0]==in[i]){ //找到中序遍歷時的根節點 tmp=(Tree *)malloc(sizeof(Tree)); tmp->x=in[i]; tmp->l=Create(pre+1,in,i); //中序歷遍中在根節點左邊的都是左子樹上的 tmp->r=Create(pre+i+1,in+i+1,n-(i+1)); //在根節點右邊的,都是右子樹上的,右子樹需要從i+1開 return tmp; } return NULL; } void PostOrder(Tree *rt){ //后序歷遍 if(rt!=NULL){ PostOrder(rt->l); PostOrder(rt->r); if(rt==root) printf("%d\n",rt->x); else printf("%d ",rt->x); } } int main(){ //freopen("input.txt","r",stdin); int n,pre[N],in[N]; //先序數組和后序數組 while(~scanf("%d",&n)){ root=NULL; for(int i=0;i<n;i++) scanf("%d",&pre[i]); for(int i=0;i<n;i++) scanf("%d",&in[i]); root=Create(pre,in,n); Tree *rt=root; PostOrder(rt); } return 0; }