1119 Pre- and Post-order Traversals (30 分)
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 Specification:
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 Specification:
For each test case, first printf in a line Yes if the tree is unique, or No if 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
思路分析: 还是熟悉的构造树型题目,相信大家之前都刷过了其他类似的题目,比如前中序建树,或者中后序建树。这个题要求用一个前序和一个后序建树,但我们大家都知道,缺少中序建出来的树是有可能不唯一的,因为在递归分治的时候,会出现一个节点在左结点成立,在右节点也成立的情况,那在本题,这种情况我们就把结点设在右边,然后用一个flag标记就可以了。然后我们再来说下,这棵树要怎么分治才能建好。
首先,对于前序中的每一个根节点,在后序中去找这个根节点和前序中第二个根节点的位置,靠着这个第二个结点为分界划分,在后序中,如果第一个结点位置在第二个结点位置右边并且二者之间有元素,说明之间的元素都属于第一个结点的右子树,第二个结点位置及以前的元素都属于第一个结点的左子树。
我们用下面这个例子来解释:
前序 :1 2 3 4 6 7 5
后序 :2 6 7 4 5 3 1
1.1为后序中index7,2为后序中index1;
2.index7>index1并且二者之间有元素,即7-1-1=5>0。所以2是1的左子树,6、7、4、5、3属于1的右子树;
3.3为后序中index6;
4.index1<index6,此时并不满足2的位置在3的右边,这是说明3并不属于2为根节点的树,而属于另外一颗子树中
后面就是接着上面的思路一直递归
最后附上代码
#include<bits/stdc++.h>
using namespace std;
const int N = 35;
int post[N],pre[N],n;
bool flag = 1;
typedef struct node *Tree;
struct node{
int data;
Tree l,r;
};
Tree BuildTree(int prel,int prer,int postl,int postr)
{
Tree root;
root = new node;
root -> data = pre[prel];
root -> l = root -> r = NULL;
if(prel == prer) return root;
int i = postl;
for (i = postl; post[i] != pre[prel + 1] ;i ++ );
if(postr - i > 1) //能确定结点在左节点还是右节点
{
int len = i - postl + 1;
root -> l = BuildTree(prel + 1,prel + len,postl,i);
root -> r = BuildTree(prel + len + 1,prer,i + 1 , postr - 1);
}
else //无法确定结点在哪边,就把节点挂右边
{
flag = 0;
root -> r = BuildTree(prel + 1,prer,postl,postr - 1);
}
return root;
}
void inorderprint(Tree root)
{
if(!root) return ;
inorderprint(root -> l);
if(flag){
printf("%d", root -> data);
flag = 0;
}else printf(" %d", root -> data);
inorderprint(root -> r);
}
int main()
{
cin >> n;
for (int i = 1 ;i <= n; i++ ) cin >> pre[i];
for (int i = 1 ;i <= n; i++ ) cin >> post[i];
Tree root = BuildTree(1,n,1,n);
if(!flag) printf("No\n");
else printf("Yes\n");
flag = 1;
inorderprint(root);
cout<<endl;
return 0;
}