Sicily 1210 二叉树 (Binary tree)

题目的大意是,给出一颗二叉树的前序和后序遍历,求符合遍历的不同形态的二叉树的数目。

 

为什么已知一棵二叉树的前序和后序遍历,不一定能重建唯一的二叉树呢?原因在于,当一个根只有一颗子树时,通过前序遍历和后序遍历,无法确定该子树是这个根的左子树还是右子树。如下图所示两颗树,前序遍历均为ab,后序遍历均为ba。

 

观察上面的两棵树,我们可以发现如下规律:当一个根(a)只有一棵子树时,前序遍历在该单子树的根(b)的前一个元素(a)必然与后序遍历在该单子树的根(b)的后一个元素(a)相同。

 

另外,单子树既可以是左子树,也可以是右子树,因此总的可能情况应该是2 的单子树个数次方。

 

综上,解题思路可以如下:先求出单子树的个数,最终结果为 2 的单子树个数次方。

Other Tips:

1:前序遍历第一个元素是根,后序遍历最后一个元素是根  

2:前序遍历第二个元素是某子树的根,但左右不确定  

3:在后序遍历中找到前序遍历的第二个元素,那么以这个元素为基准,可以划分新的左右子树  

4:当前序遍历的第二个元素出现在后序遍历的倒数第二位,以后序遍历倒数第三位起向左数都是子树的元素,但是左右不确定,因此有2种情况  

5:可使用递归或非递归方法实现。

 

1 /************************************************************************/
2  /* Sicily 1210 Binary Tree. Plutoyang.2010-12-15 */
3  /************************************************************************/
4 #include <stdio.h>
5 #include <string.h>
6
7  #define MAXLEN 10000
8
9  //traverse list
10  typedef struct
11 {
12 int root; //root of a subtree
13   char order[MAXLEN]; //traverse sequence
14 }traList;
15
16 traList pre, post; //define pre-order list and post-order list
17
18 int main()
19 {
20 int len, cnt = 1;
21
22 scanf("%s%s",&pre.order, &post.order); //read in pre-order list and post-order list
23 len = strlen(pre.order); //calculate the number of the node
24
25 if(len == 1) //special case: a tree with only one node
26 {
27 printf("%d",cnt);
28 return 0;
29 }
30
31 for(pre.root = 1; pre.root < len; pre.root++) //for each subroot in preoder list
32 { //find this subroot in post-order list
33 post.root = len - 2;
34 while(pre.order[pre.root] != post.order[post.root])
35 {
36 post.root --;
37 }
38
39 /* 一开始是这样,然后就错了
40 if(pre.order[pre.root + 1] == post.order[post.root - 1])
41 */
42 //now val[pre.root] == val[post.root], test whether the tree is a single tree or binary tree
43 if(pre.order[pre.root - 1] == post.order[post.root + 1])
44 cnt *= 2;
45 }
46
47 printf("%d", cnt);
48 return 0;
49 }
posted @ 2010-12-16 09:36  普兒  阅读(2195)  评论(0编辑  收藏  举报