神奇的递归!一文读懂函数递归(python实现)

递归是指函数在定义中调用函数自身的方式,是数学归纳法思维的编程体现

是不是有点晕,来看例1:

在上式对阶乘的定义中,计算n!需要知道(n-1)!,计算(n-1)!需要知道(n-2)!......以此类推,一直到计算2!需要知道1!,而从上面的定义中可知1!=1。那么,2!就可以算出来了,3!, 4! ......这样反向进行运算,最后就可以得到n!了。

从这个例子可以看出,递归有两个关键特征:

  1. 链条:计算过程存在链条,例1中的链条是n! = n(n-1)!
  2. 基例:存在一个或多个不需要再次递归的基例,例1的基例是1! = 1
def fact(n):
    if n == 0:
        return 1  # 基例
    else:
        rturn n*fact(n-1)  # 链条

从这段简单的代码可以得到递归实现的一般套路:函数+分支语句

  • 递归本身是个函数,需要通过函数定义方式描述
  • 在函数内部,采用分支语句对输入参数进行判断,针对基例和链条分别编写对应代码

在上述代码中,5!的阶乘是怎么实现的呢?递归先重复的复制自身并不断代入更小的参数,就是下图蓝色箭头所示;当输入参数下降到基例n=0时,将基例的值代入再不断往前推最终得到n=5的阶乘,如下图红色箭头所示。

 

再来看看其它几个例子:

# 例2:字符串反转( 不准用s[::-1]哈哈哈)

def rvs(s):
    if s == '':
        return s  # 基例
    else:
        return rvs(s[1:]) + s[0]  # 链条
# 例3:斐波那契数列

def f(n):
    if n == 1 or n == 2:
        return 1
    else:
        return f(n - 1) + f(n - 2)

for i in range(1, 31):
    print(f(i))
# 例4:汉诺塔问题
# 问题描述:
# 将一摞从小到大堆放的圆盘从src(source)杆移动到dst(destination)杆
# 可以利用mid(middle)杆,一次移动一个,小的在上面

count = 0  # 移动次数

def hanoi(n, src, dst, mid):  # n 圆盘数量;src 原杆; dst 目标杆; mid 中间杆
    global count  # 全局变量声明
    if n == 1:
        print('{}:{}->{}'.format(n, src, dst))
        count += 1
    else:  # 递归链条,调用了两次自身函数
        hanoi(n-1, src, mid, dst)  # 把n-1个从src移动到mid
        print('{}:{}->{}'.format(n, src, dst))   # 把第n个圆盘从src移动到dst
        count += 1
        hanoi(n-1, mid, dst, src)  # 把mid上的n-1个圆盘移动到dst

参考:嵩天老师python公开课

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值