【Python】递归函数——阶乘、汉诺塔、尾递归优化

在Python中,如果一个函数在调用时直接或间接地调用了本身,就称为函数的递归调用,该函数称为递归函数。

求阶乘

首先根据阶乘公式:

f(n) = n != 1 * 2 * 3 * ... * (n - 1) * n = (n - 1)!*n = f(n - 1) * n

然后很简单的就能编写出求阶乘的代码:

def func(n):
    if n == 1:
        return 1
    return n * func(n - 1)


n = int(input("请输入n的值:"))
print(func(n))

汉诺塔

def move(n, a, b, c):
    """
    有三根杆(编号A、B、C),在A杆自下而上、由大到小按顺序放置n个圆盘
    游戏的目标:把A杆上的圆盘全部移到C杆上,并仍保持原有顺序叠好。
    操作规则:每次只能移动一个盘子,并且在移动过程中三根杆上都始终保持大盘在下,
    小盘在上,操作过程中盘子可以置于A、B、C任一杆上。
    :param n: 圆盘个数
    :param a: 第一个杆子
    :param b: 第二个杆子
    :param c: 第三个杆子
    :return: 每次移动的路径
    """
    if n == 1:
        print(a, '-->', c)
        return
    else:
        move(n - 1, a, c, b)  # 首先需要将(n-1)个圆盘移动到b杆子上
        move(1, a, b, c)  # 将a杆子上的最后一个圆盘移动到c杆子上
        move(n - 1, b, a, c)  # 再将b杆子上的(n-1)个圆盘移动到c杆子上


move(3, 'A', 'B', 'C')

防止栈溢出

我们在使用递归函数时要注意防止栈溢出、因为在计算机中,函数调用是通过栈来实现的,每当执行一次函数调用时,栈就会增加一层栈帧,每当函数返回时,就会对应减少一个栈帧,因为栈的大小是有限的,所以如果递归调用的次数太多,就会导致栈溢出。

比如说 递归调用求阶乘的那个函数,将n设置为1000,就会造成栈溢出的现象。

会产如下报错 :RecursionError: maximum recursion depth exceeded in comparison(提示执行出现异常,超过最大递归深度)

出现栈溢出的问题如何解决呢?

可以用过尾递归优化的方法来解决递归调用栈溢出的问题。

尾递归就是指在函数返回时调用函数本身,并且return语句不能包含表达式,这样的话,编译器和解释器就可以对尾递归进行优化,使得递归本身无论调用多少次,都只占用一个栈帧,就不会出现栈溢出的情况。

# 尾递归优化
def f1(num, product):
    if num == 1:
        return product
    return f1(num - 1, num * product)


def f(n):
    return f1(n, 1)


n = int(input("请输入n的值:"))
print(f(n))

但是呵呵,Python的解释器并不支持尾递归优化,so,n=1000时还是会报错。

但是格局要大,只是Python不支持,咱可以用到别的编程语言中。

编程语言千千万,掌握思想是好汉。

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

二琳爱吃肉

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值