python静态递归函数_Python递归函数相关

本文介绍了Python中的递归函数,包括递归的调用机制和栈溢出问题。通过一个阶乘函数的例子,展示了如何使用循环和递归计算阶乘,并解释了当递归深度过大时可能导致的栈溢出。然后,文章阐述了尾递归的概念及其优化原理,以解决栈溢出问题,最后指出Python解释器并未对尾递归进行优化,即使使用尾递归也会出现栈溢出。

函数中调用其他函数是解决实际问题中常用方法,递归函数便是函数在运行过程中调用自身的函数。它像是循环的另一种表达方式,不过相较于写循环,递归函数封装性较好、可读性较强。在解决一些循环问题时,使用递归函数往往更简洁有效。以往提到递归函数时,理解仅仅到它比循环更简洁。今天读了博主程序员的人生A的博客后,学习到递归函数的调用机制以及通过尾递归优化解决栈溢出的问题,特留随笔,作温习记录用。

首先递归函数的调用是通过栈(stack)这一种数据结构实现,每多一次函数调用/返回,栈就增加/减少一层栈帧。既然提到它,不妨大致复习一下堆栈的相关。提栈就不得不提它的两个操作及一个性质:入栈(PUSH)和出栈(POP),他们按照先入后出、后入先出的顺序操作。进栈出栈就像往一个盒子里取放东西,先放的被后放的压在下面,要想取到下面的,自然要先拿出在上面的。栈之所以于程序有着至关重要的作用,是因为栈保存了一个程序调用时所需的维护信息,称为堆栈帧或活动记录。它一般包含几部分:1、函数的返回地址和参数;2、临时变量:包括函数的非静态局部变量以及编译器自动生成的其他临时变量。堆栈的实质是一种运算受限于一端的线性表。那既然是线性表,大小自然是有限的。因此,当递归函数调用次数过大(即参数过大时),便会出现“栈溢出”的现象。

解决“栈溢出”的方法则是“尾递归优化”。尾递归是指在函数返回的时候,调用自身且return语句中不能包含表达式。这样编译器就可以把尾递归做优化,使递归本身无论被调用多少次,都只占用一个栈帧,这样便不会出现栈溢出的情况。

用最简单的阶乘函数举例。

使用循环计算1*2*3*...*n:

n = int(input("输出一个数:"))

if n == 0:

sum = 0

else:

sum = 1

for i in range(1,n+1):

sum *= i

print("它的阶乘为:",sum)

使用递归函数计算:

def recursion(n):

if n==1:

return 1

return n * recursion(n - 1)

a = int(input("输入一个数:"))

print("它的阶乘为:", recursion(a))

但当a过大时,编译器便会因栈溢出而报错,这是就需要用到尾递归优化。

尾递归优化:

def recursion(n):

return fact_iter(n, 1)

def fact_iter(num, product):

if num == 1:

return product

return fact_iter(num - 1, num * product)

优化后,函数仅返回递归函数本身,这样栈帧中数据每一次使用后更新,栈不再增长,无论调用多少次都不会导致栈溢出。遗憾的是python解释器并没有针对尾递归做优化,因此用python时即使进行了尾递归优化,还是会导致栈溢出。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值