递归函数
递归函数
1. 什么是递归函数
在函数内部,可以调用其他函数,如果一个函数在内部调用自身本身,这个函数就是递归函数。记住哦--> 在函数内部调用其他函数不是函数的嵌套,而在函数内部定义子函数才是函数的嵌套
递归的特性:
- 递归函数必须有一个明确的结束条件
- 每进入更深一层的递归时,问题规模相当于上一次递归都应减少
- 相邻两次重复之间有紧密的联系,前一次要为后一次做准备(通常前一次的输出就作为后一次的输入)。
- 递归效率不高,递归层次过多会导致栈溢出(在计算机中,函数调用就是通过栈(stack) 这种数据结构实现的,每当进入一个函数调用,栈就会加一层栈帧,每当函数返回,栈就会减一层栈帧。由于栈的大小不是无限的,所以,递归调用的次数过多,会导致栈溢出)
一个关于实现叠加的两种方法的例子:
importimport sys # 通过循环来实现叠加 def sum1(n): ''' 1 to n, the sum fucntion ''' sum = 0 for i in range(1, n + 1): sum += i return sum # 通过函数的递归来实现叠加 def sum2(n): ''' 1 to n, the sum function ''' if n > 0: return n + sum2(n - 1) # 调用函数自身 else: return 0 print("循环叠加-->", sum1(100)) # 5050 print("递归叠加-->",sum2(100)) # 5050
从上述例子中可以看出,两者都实现叠加的效果。那么后者相对于前者有什么优缺点呢?
2、递归函数有啥优缺点
递归函数的有点: 定义简单,逻辑清晰。理论上,所有递归函数都可以写成循环的方式,但循环的逻辑不如递归清晰。
递归函数的缺点:==使用递归函数需要注意防止栈溢出==。在计算机中,函数调用时通过栈`(stack)`这种数据结构实现的,每当进入一个函数调用,栈就会加一层栈帧。每当函数返回,栈就会减一层栈帧。由于栈的大小不是无线的,所以,递归调用的次数过多,会导致栈溢出!
把上面的递归求和函数的参数改成10000就导致栈溢出!
当然也可以通过尾递归来对递归的栈溢出进行优化。
尾递归调用时,如果做了优化,栈不会增长,因此,无论多少次调用也不会导致栈溢出。
遗憾的是,大多数编程语言没有针对尾递归做优化,Python解释器也没有做优化,所以,即使把上面的fact(n) 函数改成尾递归方式,也会导致栈溢出。Python标准的解释器没有针对尾递归做优化,任何递归函数都存在栈溢出的问题。
3、通过实例来介绍函数递归:
下面我们通过一个问路的例子,更好的理解递归:
# 假如街上有那么一群人,我想问知道长沙的小吃街在哪,其中只有狗叫峰知道在哪 names = ['我', '吴彦祖', '郭富城', '迪丽热巴', '胡歌', '狗叫峰', '彭于晏'] # 问路 def ask_way(lis): # 街上就我一个人的情况下 if len(lis) == 1: return "没有人知道这个地方在哪" # 街上不止我一个人的情况下,先问第一个人 name = lis.pop(0) # 如果这个人时狗叫峰,那么问道路, 递归结束 if name == '狗叫峰': return "狗叫峰说: 长沙的小吃街在天心区南门口" # 如果这个人不知道路,就去问下一个人,一下个就会把好把结果告诉这个人 print("<%s>问:你[%s]好,请问你知道长沙的小吃街在哪吗" % (name, lis[0])) print("不好意思,我帮你问一下%s,他可能会知道!\n"%lis[0]) res = ask_way(lis) if name != '我': print("《%s》说: %s" % (name, res)) return res res1 = ask_way(names) 输出结果为: """ <我>问:你[吴彦祖]好,请问你知道长沙的小吃街在哪吗 不好意思,我帮你问一下吴彦祖,他可能会知道! <吴彦祖>问:你[郭富城]好,请问你知道长沙的小吃街在哪吗 不好意思,我帮你问一下郭富城,他可能会知道! <郭富城>问:你[迪丽热巴]好,请问你知道长沙的小吃街在哪吗 不好意思,我帮你问一下迪丽热巴,他可能会知道! <迪丽热巴>问:你[胡歌]好,请问你知道长沙的小吃街在哪吗 不好意思,我帮你问一下胡歌,他可能会知道! <胡歌>问:你[狗叫峰]好,请问你知道长沙的小吃街在哪吗 不好意思,我帮你问一下狗叫峰,他可能会知道! 《胡歌》说: 狗叫峰说: 长沙的小吃街在天心区南门口 《迪丽热巴》说: 狗叫峰说: 长沙的小吃街在天心区南门口 《郭富城》说: 狗叫峰说: 长沙的小吃街在天心区南门口 《吴彦祖》说: 狗叫峰说: 长沙的小吃街在天心区南门口 """
递归值得返回时返回到上一层,而其他的层在执行的过程中,均处于等待答案的过程中
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?