求出栈序列,二叉树,二叉搜索树的计数问题


#include <iostream>
using namespace std;
const long long INF=1000000007;
long long a[1001];
void init(int n)
{
for(int i=0;i<n;i++)
a[i]=0;
a[0]=1;
a[1]=1;
for(int i=2;i<=n;i++){
for(int j=0;j<i;j++)
{
a[i]+=a[j]*a[i-j-1];
a[i]%=INF;
}
}
}
void func()
{
init(1000);
int n;
while(cin>>n)
{
if((n&1)==0)
cout<<a[n/2]<<endl;// n/2的原因是栈操作个数是栈元素的2倍
else
cout<<0<<endl;
}
}
int main(int argc, char *argv[])
{
//printf("Hello, world\n");
func();
return 0;
}
二叉树的的计数
二叉树的计数所有递推关系:具有n个结点的二叉树可以视为由一个根结点,一棵具有i个结点的左子树和一棵具有n-i-1的右子树构成
于是
当n=0时 b=1
当n=1时显然b=1
类似问题:
类似问题:
树的计数
一棵树可以转换成唯一的一棵没有右子树的二叉树,反过来亦成立
因此,n 个结点的树的数目t(n)和n-1个结点的二叉树数目相同
出栈序列
栈的计数与二叉树计数性质一样,原因是二叉树中序遍历时需要栈,每一个中序形态对应了栈的进栈出栈序列,而前序与中序可以构成唯一的二叉树,所以给定n个数据的出栈序列计数与二叉树的计数是一致的
二叉搜索树
二叉搜索树的计数递推有两种方式理解:
1搜索树都可以由同等结构,按其值递增的二叉树转化而来(转化过程查阅相关文章)
2假设搜索树的值为1,2,3....n,设根结点值为i+1,则左子树为1,2,3....i,右子树为i+2,i+3.....n,
于是
当n=0时 b=1
当n=1时显然b=1
最后该递推式都可以根据数学中的生成函数得到公式
递推关系的解为:
h(n)=C(2n,n)/(n+1) (n=0,1,2,...)
递推关系的另类解为:
h(n)=c(2n,n)-c(2n,n-1)(n=1,2,...)
即为卡特兰数