函数递归解决n个结点可构成的二叉树数目问题(卡塔兰数)

看到这样一个问题,问n个结点可以组成多少个二叉树,正好自己在学,顺便写了一个函数来解决这个问题,然后一搜发现这个竟然是卡特兰数,好神奇~~~

思路分析

规定0个或者1个结点时,只有一种二叉树。那么对于n个结点,我们不妨向前想一想,利用n-1n-2甚至更前的情况来进行推理,假设n个结点有f\left ( n \right )种二叉树。

首先,我们先拿一个结点作为根结点,剩下了n-1个结点,此时我们不妨将这n-1个结点再一次分成两份,比如,0和n-1,那么这n-1个结点就会有f\left ( n-1 \right )种二叉树作为根结点的左子树或者右子树;同理,0个结点就会有f\left ( 0 \right )种(即1种)二叉树作为左子树或者右子树。那么就会有这种情况:

左子树的数目右子树的数目
f\left ( 0 \right )f\left ( n-1 \right )
f\left ( n-1 \right )f\left ( 0 \right )

进而,我们对n-1个结点进行多种这样的划分,每一次都会有对应的二叉树数目作为左子树或者右子树,就像这样

左子树的数目右子树的数目
f\left ( 1 \right )f\left ( n-2 \right )
f\left ( n-2 \right )f\left ( 1 \right )
f\left ( 2 \right )f\left ( n-3 \right )
f\left ( n-3 \right )f\left ( 2 \right )
.............
f(i)f(n-1-i)
f(n-1-i)f(i)

这时我们再去对n-1的奇偶性进行讨论。如果n-1为奇数,那么最后会有\frac{n}{2}\frac{n-2}2{},顺序进行互换就有两种了;如果n-1为偶数,那么最后就只有两个\frac{n}{2}这一种分法了。当顺序互换时,总的二叉树数目就等于左子树数目\times右子树数目\times2;针对两个\frac{n}{2}这种特殊情况,二叉树数目就不需要\times2了。

综上我们需要做的就是从0开始进行遍历,如果n-1为奇数就遍历到\frac{n-2}2{},每次\times2;如果n-1为偶数就遍历到\frac{n}{2},最后一个单独从循环中拿出来不用\times2即可。

代码实现

我是写了一个函数进行递归,供大家参考。

#include<stdio.h>

int numsofBinarytree(int n){
    int res=0;
    if(n==1||n==0){
        return 1;
    }
    else{
    if((n-1)%2==0){
        for(int i=0;i<(n-1)/2;i++){
            res+=numsofBinarytree(i)*numsofBinarytree(n-1-i)*2;
        }
        res+=numsofBinarytree((n-1)/2)*numsofBinarytree((n-1)/2);
    }
    else{
for(int i=0;i<=(n-1)/2;i++){
            res+=numsofBinarytree(i)*numsofBinarytree(n-1-i)*2;
        }

    }
 }

    return res;
}


int main(){
    int n;
    while(scanf("%d",&n)!=EOF){
        printf("%d\n",numsofBinarytree(n));
    }
   return 0;
}

欢迎大家在评论区提出更好的解法和思路,如果觉得有用,点个赞和收藏加关注再走吧~~~

  • 12
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值