HDU1710 Binary Tree Traversals(二叉树重建模板609)

来源:互联网 发布:网络棋牌类游戏 编辑:程序博客网 时间:2024/04/30 04:31

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.

这里写图片描述

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

题意:给出前序和中序序列,求后序序列

解题思路:二叉树重建

仔细观察前序中序后序序列,可以发现很多规律:
1.前序是根左右(根在左右的前面)又叫先序
中序是左根右(根在左右的中间)
后序是左右根(根在左右的后面)
2.观察这棵树:

前序:ABDGHECFI
中序:GDHBEAFIC
后序:GHDEBIFCA

中序是根在左右子树的中间,左边是左子树右边是右子树

G D H B E A F I C
左 根 右 根 右 根 根 右 根

AC代码:

#include<stdio.h>#include<string.h>int pre[1010],in[1010],post[1010];void build(int l1,int r1,int l2,int r2)//前序、中序序列的左边界(l1,l2),右边界(r1,r2){    if(l1>r1) return;//如果左边界大于右边界说明树中没有结点     int s=0;    while(in[l2+s]!=pre[l1])//在中序序列中找到根结点的位置         s++;    build(l1+1,l1+s,l2,l2+s-1);//找左子树:在前序遍历的左边界+1,右边界+s。在中序遍历的左边界还是在最左边,右边界变为l2+s-1     build(l1+1+s,r1,l2+s+1,r2);//找右子树:在前序遍历的左边界变为l1+1+s,右边界就是最右边。在中序遍历的左边界变为l2+s+1,右边界就是最右边     printf("%d",pre[l1]);//前序是根左右,中序是左根右,后序是左右根。所以在根求出左右子树后输出。注意只能前+中求后或者后+中求前。     if(l1!=0) printf(" ");}int main(){    int n;    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);        printf("\n");    }    return 0;}