Bootstrap

二叉树遍历(已知前序和后序遍历,求中序遍历的可能的序列数)

题目描述 Description

    我们都很熟悉二叉树的前序、中序、后序遍历,在数据结构中常提出这样的问题:已知一棵二叉树的前序和中序遍历,求它的后序遍历,相应的,已知一棵二叉树的后序遍历和中序遍历序列你也能求出它的前序遍历。然而给定一棵二叉树的前序和后序,你却不能确定其中序遍历序列,考虑如下图中的几棵二叉树:

 

    所有这些二叉树都有着相同的前序遍历和后序遍历,但中序遍历却不相同。

输入描述 Input Description

    输入文件共2行,第一行表示该树的前序遍历结果,第二行表示该树的后序遍历结果。输入的字符集合为{a-z},长度不超过26。

输出描述 Output Description

    输出文件只包含一个不超过长整型的整数,表示可能的中序遍历序列的总数。

样例输入 Sample Input

abc

cba

样例输出 Sample Output

4

解题思路:

    在求解这题之前得先了解一些基础知识:

    前序遍历:根结点 ---> 左子树 ---> 右子树

    中序遍历:左子树---> 根结点 ---> 右子树

    后序遍历:左子树 ---> 右子树 ---> 根结点

    由以上的前中后遍历顺序可以看出在已知前序遍历和后序遍历的情况下,中序遍历不是唯一确定的。而且中序遍历的不确定性是由一个节点(只有一边子树)的左右子树的不确定性决定的。例如前序遍历ab,后序遍历ba,a为根,b为子树,在中序遍历中如果b为左子树,则中序遍历为ba;如果b为右子树,则中序遍历为ab。所以当这种节点有n个时,中序遍历的可能性就有:2^n;

    那么问题就转变为如果确定这种节点的数量。可以总结出一个规律,如上例。前序遍历为ab,后序遍历为ba,此时无法确定b是为左子树还是右子树,那么就产生了一个特殊节点。所以规律就是(此时a,b分别为前序遍历和后序遍历的字符串):a[i]==b[j]时,a[i+1]==b[j-1]则产生一个特殊节点

代码如下:

#include<stdio.h>

#include<string.h>

#define M 30

int count=0;

int power(int ans);

int main()

{

	 char a[M],b[M];
	
	 int i=0,j=0;
	 
	 int lengthA=0,lengthB=0;
	
	 gets(a);
	
	 gets(b);
	
	 lengthA=strlen(a),lengthB=strlen(b);
	
	 for(i=0;i<lengthA;i++)
	
	  for(j=1;j<lengthB;j++)
	
	   if(a[i]==b[j]&&a[i+1]==b[j-1])
	
	    count++;
	
	 printf("%d\n",power(count));
	 return 0;
}

int power(int ans)
{
	int sum=1;
	while(--ans>=0) sum*=2;
	return sum;
}

 

;