【二叉树】 二叉树的计数(由先序和后序遍历得二叉树可能形状个数)

 二叉树的计数(count-tree)

题目描述
输入
第1行:二叉树的前序遍历顺序

第2行:后序遍历顺序

输出
第1行:1个整数,表示所有可能的二叉树的数量

样例输入1
ABC
CBA

样例输出1
4

样例输入2
ABCEDFGH
ECDBHGFA

样例输出2
8

 

分析:

首先很容易得出3个性质:

1,若后序输出只有两个结点,那么这棵树的形态有2种可能

2,若只有一个结点,只有一种可能

3,在先序遍历中,A的右边第一个字母一定是A的左儿子(若左树不为空)

4,在后序遍历中,A的左右儿子一定在A的左侧

根据性质3与性质4,可以把一颗二叉树分为左子树和右子树

根据乘法原理,二叉树所有可能的情况 = 左子树可能的情况 * 右子树可能的情况

由此则可以递归,递归边界便是性质1,2

但是还要注意一点,若二叉树的其中一个子树为空,那么因为后序遍历的性质,不为空的子树既可以为左子树,也能为右子树

so,性质5:若递归的当前结点数=0,返回2

例如样例1:先找到B是A的左儿子,再找到后序中B的坐标,把A的左右子树分为 CB--空 =2*2=4

再例如样例2:结合性质3与性质4把A的左右子树分为 ECDB--HGF 。ECDB-->  EC--D =2*1 =2;  HGF -->  HG--空 =2*2=4 ; ECDB * HGF =2*4=8。

代码如下:

#include<cstdio>
#include<cstring>
char a[100],b[100];
int xmy(int x,int y,int q,int w)//x,y为此树在后序遍历中的坐标,q,w为此树在先序遍历中的坐标
{
	if(w-q<0) return 2;
	if(w-q<2) return w-q+1;
	int p=strchr(b,a[q+1])-b;//找左儿子
	return xmy(x,p,q+1,q+1+p-x)*xmy(p+1,y-1,q+2+p-x,w);//拆分
}
int main()
{
	//freopen("count-tree.in","r",stdin);
	//freopen("count-tree.out","w",stdout);
	scanf("%s%s",a,b);
	int n=strlen(a);
	printf("%d",xmy(0,n-1,0,n-1));
}



 

  • 6
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值