Binary Tree Traversals
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
解题思路:
本题给二叉树的结点数量,之后第一行给出二叉树的先序遍历,第二行给出二叉树的中序遍历,根据前序遍历的性质,先序遍历的首位为根结点,以该点为根结点建树,从中序遍历中寻找该点,假设找到新的位置为k,则从中序遍历首位到k-1,为左子树中序遍历的范围,从k+1到中序遍历末位为右子树中序范围,,这样我们就可以得知左子树长度,右子树长度,进而获得左子树与右子树的前序遍历。对获得的左子树右子树的前序遍历中序遍历进行同样的操作,便可以建立该树。
1 #include <bits/stdc++.h> 2 using namespace std; 3 typedef int typeData; 4 const int maxn = 1100; 5 int pre[maxn]; //记录前序遍历 6 int in[maxn]; //记录中序遍历 7 struct node{ 8 typeData data; 9 node* leftChild; 10 node* rightChild; 11 node(){ 12 leftChild = NULL; 13 rightChild = NULL; 14 } 15 }; 16 17 void postorder(node *root, node *flag){ //输出后序遍历 18 if(root == NULL) 19 return; 20 postorder(root->leftChild, flag); 21 postorder(root->rightChild, flag); 22 23 printf("%d", root->data); 24 if(root != flag) 25 printf(" "); 26 } 27 //传入先序遍历起始位置,中序遍历起始位置 28 node* create(int preL, int preR, int inL, int inR){ 29 if(preL > preR) //如果前序遍历中没有数值返回NULL 30 return NULL; 31 node* root = new node(); //建立新结点,其权值为,当前先序遍历的首位,即当前树根结点 32 root->data = pre[preL]; 33 int k; //k记录根结点在中序遍历中的位置 34 for(k = inL; k < inR; k++){ //在中序遍历中寻找根结点位置 35 if(pre[preL] == in[k]) 36 break; 37 } 38 int numLeft = k - inL; //计算左子树长度 39 root->leftChild = create(preL + 1, preL + numLeft, inL, k - 1); //递归建立左子树 40 //先序遍历中左子树区域为根结点的下一位到左子树起始点加左子树长度 41 //中序遍历中左子树区域为中序遍历首位到根结点之前 42 root->rightChild = create(preL + numLeft + 1, preR, k + 1, inR); //递归建立右子树 43 //先序遍历中右子树区域为左子树末尾的下一位到先序遍历末位 44 //中序遍历中右子树区域为根结点后一位到中序遍历末位 45 return root; 46 } 47 int main() 48 { 49 int n; 50 while(cin >> n){ 51 memset(pre, 0, sizeof(pre)); 52 memset(in, 0, sizeof(in)); 53 for(int i = 0; i < n; i++){ 54 scanf("%d", &pre[i]); //输入先序遍历 55 } 56 for(int i = 0; i < n; i++){ //输入中序遍历 57 scanf("%d", &in[i]); 58 } 59 node* root = create(0, n - 1, 0, n - 1); //建树 60 postorder(root, root); //输出后序遍历 61 printf(" "); 62 } 63 }