58.Python的递归函数
文章目录
- 58.Python的递归函数
- 1.递归的形象解释
- 2.定义
- 3.步骤
- 4.终止条件
- 5.优点
- 6.缺点
- 7.调用深度
- 8.课堂实例
- 9.计算n的阶乘
- 9.1什么是阶乘
- 9.2计算5!
1.递归的形象解释
我们首先看一段视频,来形象理解什么是递归。
视频作者:pipi的奇思妙想
大家可以网上搜一下该作者的视频,搜不到的可以联系我!
【目标任务】
电影院里,小玩偶想知道自己的位置在第几排。
2.定义
一个函数是可以调用另一函数的。
作为特例,如果一个函数调用了自己,那我们称这个函数为递归函数。
【示例】
f(x)=f(x+1)+x
f(x)和f(x+1)的函数名都是f
,只是参数不同,一个是x,一个是x+1。
像这样自己调用自己的表达式就是一个递归函数。
3.步骤
递归通常可以分为两步:先递后回归。
视频中的小玩偶从后往前询问前一个小玩偶的坐位数,就是一个递推的过程。
小玩偶从前往后告诉后一个小玩偶的它座位数,就是一个回归的过程。
4.终止条件
递归函数必须有终止条件。
编程中,函数的调用要占用名叫栈(stack)的内存空间。
调用函数时,程序会将相关的数据存储到计算机的栈里。
当函数运行结束时数据会从栈里取出。
如果函数调用永远不停止,栈会被塞满,数据就没地方存储。
我们将这种情况称为栈溢出。
栈溢出,程序会被操作系统强行终止。
因此,递归函数必须有终止条件。
5.优点
递归函数自己调用自己,代码相对简单。
6.缺点
递归函数每调用一次都会开相应的内存空间,因此递归函数的缺点就是占用内存较多。
7.调用深度
递归调用的次数,我们称之为调用深度。
递归函数调用深度是有限制的,超出会有溢出。
8.课堂实例
我们用一个简单的例子来体验递归函数:
def f(x) :
return f(x-1)+x
print(f(3))
【代码解析】
-
定义函数f,参数是x,注意自定义函数语句以英文冒号
:
结尾; -
自定义函数要实现的功能是:返回
f(x-1)+x
f(x)和f(x-1)函数名相同,只是参数不同。
因此,在自定义函数f(x)中,它自己调用了自己。
- 最后是调用函数,调用函数的语法为
函数名(参数)
这里的函数名是f,要传入的实际参数为3。
【参数传递过程】
当参数等于3
的时候,函数的返回值是f(2)+3
3
是确定的数值,f(2)
的值无法确定,需要继续调用函数。
当参数等于2
的时候,函数的返回值是f(1)+2
当参数等于1
的时候,函数的返回值是f(0)+1
当参数等于0
的时候,函数的返回值是f(-1)+0
我们发现,函数每次都会无条件的调用自己。
f(x)永远不会有具体的值,函数调用永远不会停止。
要解决这个问题,我们必须给函数加入一个终止条件。
我们再代码中加入一个判断语句:
如果x>0,函数就调用自己。
否则,直接返回0。
def f(x) :
if x>0:
return f(x-1)+x
else:
return 0
print(f(3))
【终端输出】
6
分析程序执行的过程:
【递推的过程】
f(3)=f(2)+3
f(2)=f(1)+2
f(1)=f(0)+1
f(0)=0
【回归的过程】
f(0)=0
f(1)=f(0)+1=0+1=1
f(2)=f(1)+2=1+2=3
f(3)=f(2)+3=3+3=6
因此,程序终端输出的结果是6。
9.计算n的阶乘
9.1什么是阶乘
一个正整数的阶乘(factorial)是所有小于及等于该数的正整数的积。
0的阶乘为1。
自然数n的阶乘写作n!
n!=1×2×3×…×n
阶乘可以用递归方式定义:0!=1,n!=(n-1)!×n。
【示例】
1!=1
2!=1!×2=1×2=2
3!=2!×3=2×3=6
4!=3!×4=6×4=24
5!=4!×5=24×5=120
9.2计算5!
def f(n) :
if n == 1 :
return 1
else:
return n*f(n-1)
print(f(5))
【终端输出】
120
-
定义函数f,参数是n,注意自定义函数语句以英文冒号
:
结尾; -
递归函数的终止条件:如果n=1,返回值为1
-
自定义函数要实现的功能是
n*f(n-1)
f(n)和f(n-1)函数名相同,只是参数不同。
因此,在自定义函数f(n)中,它自己调用了自己。
- 最后是调用函数,调用函数的语法为
函数名(参数)
这里的函数名是f,要传入的实际参数为5。
【参数传递过程】
当参数等于5
的时候,函数的返回值是5×f(4)
当参数等于4
的时候,函数的返回值是4×f(3)
当参数等于3
的时候,函数的返回值是3×f(2)
当参数等于2
的时候,函数的返回值是2×f(1)
当参数等于1
的时候,函数的返回值是1
,即f(1)=1
【程序的执行过程】
【递推的过程】
f(5)=5×f(4)
f(4)=4×f(3)
f(3)=3×f(2)
f(2)=2×f(1)
f(1)=1
【回归过程】
f(1)=1
f(2)=2×f(1)=2×1=2
f(3)=3×f(2)=3×2=6
f(4)=4×f(3)=4×6=24
f(5)=5×f(4)=5×24=120
【总结】
很多同学会觉得写代码比计算更复杂,耗费时间更多。
那是因为我们要计算的阶乘数比较简单。
那如果我们要计算的是40!,大家观察下面的代码的输出结果,看看是否还能自己计算呢?
def f(n) :
if n == 1 :
return 1
else:
return n*f(n-1)
print(f(40))
【终端输出】
815915283247897734345611269596115894272000000000