递归--从青蛙跳台阶说起

迭代与递归

迭代与递归从本质上讲,都是一种循环过程。迭代主要是在每一步中更新变量值来达到循环的目的,而递归则是在函数中调用自己来实现循环。迭代更直观,我们一眼能够看出程序执行过程,而递归则使得程序更加简洁紧凑。

三要素

对于迭代,我们给定一个循环指标、循环范围以及需要更新的变量就可以进行循环了,例如

for i in range(5):
	a = i + 1
	print(a)

在上面的Python程序中,i为循环指标,循环范围为 [ 0 , 4 ] [0,4] [0,4],变量为i + 1

对于递归,我们同样需要三个基本要素才行,即:

  • 功能函数(即这个函数需要做什么)
  • 基线条件(或结束条件,即递归什么时候结束)
  • 函数关系(即这个函数与下一个函数的关系)

例如:

def func(n): # 功能函数:求前n个正整数的和
	if n > 1:
		return n + func(n - 1) #函数关系
	else:
		return 1 #基线条件

对于迭代,我们可以清楚地看出程序执行的过程,即i从0并且以1为步长进行循环,直至i=4,循环结束。

但是对于递归,我们乍一看,看不出循环指标,而当我们仔细研究定义的函数之后,就会发现,定义的函数中自己调用了自己,只不过对于每一个n,调用了该函数对应于n-1的函数值,而每一个n-1,又调用了该函数对应于n-2的函数值,…,以此类推,直至满足基线条件,递归停止。我们以n=3为例,看一下递归中发生了什么。

func(3) = 3 + func(2)
func(3) = 3 + (2 + func(1))
func(3) = 3 + (2 + 1)
-->func(3) = 6

最终,我们得到了前三个正整数的和。

举两个🌰

让我们以计算阶乘为例,这也是各种教程中经常使用的例子。

阶乘(Factorial),是所有小于以及等于该数的正整数的积,并且定义0的阶乘为1。

def factorial(n):
	if n == 0 or n == 1:
		return 1
	if n > 1:
		return n * factorial(n - 1)

另一个常见的例子是斐波那契数列,这也是算法中经常会借鉴的数学基础。斐波那契数列是指,从第三项起,每一项为该项前两项之和,即:1、1、2、3、5、8、13、21…

很明显,这是一个递归问题,函数关系为 f ( n ) = f ( n − 1 ) + f ( n − 2 ) , n ≥ 3 f(n) = f(n-1) + f(n-2),n \ge 3 f(n)=f(n1)+f(n2)n3
我们来看一下Python的代码实现。

def fibonacci(n):
    if n <= 2:
        return 1
    return fibonacci(n - 1) + fibonacci(n - 2)

青蛙跳台阶

这也是一道经典的算法题,说的是有一只青蛙,每一次可以跳上 1 级台阶,也可以跳上2 级台阶,问该青蛙跳上一个n 级台阶,总共有多少种跳法。

我们先来分析一下,假设对于 n n n级台阶共有 f ( n ) f(n) f(n)中跳法,并且我们知道 n = 1 n = 1 n=1时,只有一种跳法, n = 2 n = 2 n=2时,有两种跳法,但是函数关系并没有显而易见,那么如何寻找函数关系呢?

如果青蛙第一次跳上了1级台阶,则剩余 n − 1 n-1 n1级还有 f ( n − 1 ) f(n-1) f(n1)种跳法,如果青蛙第一次跳上了2级台阶,则剩余 n − 2 n-2 n2级还有 f ( n − 2 ) f(n-2) f(n2)种跳法,因此 f ( n − 1 ) + f ( n − 2 ) f(n-1) + f(n-2) f(n1)+f(n2)就是 n n n级台阶的总跳法,也就等于 f ( n ) f(n) f(n),看,我们找到了函数关系 f ( n ) = f ( n − 1 ) + f ( n − 2 ) f(n) = f(n - 1) + f(n - 2) f(n)=f(n1)+f(n2)

准备撸代码了:

def leap(n):
    if (n <= 2):
        return n
    return leap(n - 1) + leap(n - 2)

搞定!

等等,如果这只青蛙肌肉发达,可以在n级台阶中跳上1级、2级、3级…n级台阶,那么有多少种跳法?

其实这还是递归,只不过 f ( n ) = f ( n − 1 ) + f ( n − 2 ) + f ( n − 3 ) + . . . + f ( 2 ) + f ( 1 ) f(n) = f(n - 1) + f(n - 2) + f(n - 3) + ... + f(2) + f(1) f(n)=f(n1)+f(n2)+f(n3)+...+f(2)+f(1)

对应的代码为:

def leap(n):
    if (n <= 2):
        return n
    num = 0
    for i in range(n):
        i += 1
        num += leap(n - i)
    return num

递归的基本思想就是这样,记住三要素:功能函数、基线条件、函数关系。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值