计算二叉树的个数

说明

给定二叉树的节点个数来计算能够构成多少种不同的二叉树。

操作

采用的是递归的思想来解决这类问题。

1、因为采用递归的思想,我们的结束条件就是当节点个数为0.此时节点个数为0的情况,这时候构成的树的情况为空树,即二叉树的个数是1.

2、因为是二叉树,我们只需要分为两边来计算。即满足这样的条件,从根节点下来,能够成左边的情况的个数乘以右边的个数的情况想乘,就得到此时这种情况的个数。例如:总共有3个节点,左边分配2个(能构成的情况为2),右边分配1个节点(能构成的情况为1),即本次分配的情况总数为2*1=2

3、实际上节点数为1的时候,构成的情况也是1,和0是一样的,所以递归的条件,就是当节点数为0就结束。所以每次的结果都会递归到0。

代码实现:

'''
计算二叉树的个数
'''
def count(n):
    # root : 1
    # left : k [0,n-1]
    # right : n - 1 - k

    if n == 0:
        return 1
    sum = 0
    for k in range(n):
        sum += count(k) * count(n-1-k)
    return sum

用一张图来表示调用栈的变化以及程序的执行过程。我们以n=3为例,其他的(n更大)的情况都是一样的计算。

二叉树递归计数

上图,详细解释了每一步的执行过程。上述调用栈的过程遵从左到右、从上到下的过程。执行过程遵从,从右到做、从下到上的顺序。

总结

在上述的代码中,有一个很大的缺点,在调用栈中就体现得很明确,当我们第一步执行count(0)和count(2)后,发现后面还会用到这些,会被重复的在调用栈中执行,在时间和空间上都是很大的浪费。

解决方法,我们可以建立一个缓存机制,使得每次执行过的count()被保存在缓存中,这样的话,当我们下次执行到ciunt()时,如果已经在缓存中,就直接从缓存中取(时间复杂度为O(1)),如果不存在我们才会递归。

其代码如下:

'''
添加缓存的方式来实现时间复杂度下降
'''
def count_tree(n):
    # root : 1
    # left : k [0,n-1]
    # right : n - 1 - k

    sum = count_tree.cache.get(n,0)
    if sum:
        return sum
    for k in range(n):
        sum += count_tree(k) * count_tree(n-1-k)
    return sum
count_tree.cache = {0:1}

 

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值