单向递归和尾递归迭代,递归与非递归区别在哪,单向递归和尾递归迭代,递归与非递归区别是什么
一般递归
defnormal _ recursion(n):IFN==1:return 1 else:return normal _ recursion(n-1)运行:
正常_记录(5) 5正常_记录(4) 54正常_记录(3) 54正常_记录(2) 542正常_记录
随着递归深度的增加,创建的堆栈越来越多,导致爆炸堆栈:吊杆:
尾递归
尾递归基于函数的尾调用每个级别的调用都直接返回函数的返回值以更新调用栈,而不创建新的调用栈。像迭代实现一样,在时间和空间上都优化一般递归!
运行deftail_recursion(n,total=0):IFN==0:returntotalelse 3360 return tail _ recursion(n-1,total):
尾递归(5(5(5)尾递归)4,5尾递归)3,9)尾递归(2,12)TTT辅助
深入理解尾递归诶,所以呢?还觉得不够吗。谁说不需要通过尾部递归调用建立新的堆栈呢?
还是去底层看看吧
inttail_recursion(intn,int total)if)n==0){ return total;}else{returntail_recursion(n-1,共n);}intmain(void ) { int total=0,n=4;tail_recursion(n,总计返回0;}反汇编
$ gcc-stail _ recursion。c-o正规_递归。s
$ gcc-s-O2 tail _ recursion。c-o尾_递归。镀锌板打开尾部递归优化
反汇编代码如下(ATT语法) ) )。
请注意,在打开尾部递归优化之前,已经使用呼叫调用函数创建了新的调用堆栈(LBB0_3)。
如果打开尾部递归优化,则不会生成新的调用栈,而是直接流行音乐
返回bp机机指定的_ tail _递归函数的地址(pushq %rbp),
使用的是同一个调用堆栈!
存在的问题尾部递归优化很好,但大蟒不支持尾部递归,如果递归深度超过1000,则会报告错误
实现运行时错误3360最大保留深度超过http://www.Sina.com/tail _调用_优化装饰件
#!/usr/ZL DBM/env python 2.4 # thiprogramshowsoffapythondecorator(#实现stailcalloptimization。它# doesthisbython它自己的grande,并捕捉这样的# exceptions来调用堆栈。importsysclasstailrecurseeexception 3360 def _ _ init _ init kwargs):self。args=args self。kwargs=kwargsdefail _ call _ optimized(g)))). 3360 thisfunctiondecoratesaafunctionwithtailcalloptimization。itdoesthisbythrowinganexceptionfitit 它的祖父级和父级ailcalloptimization。thisfunctionfailsifdecoratedfunctionrecurses在尾上下文中。func(args,**kwargs ) : f函数的默认一级递归是父调用,#尾部递归不希望生成新的函数调用)或:lcdwg调用(后面有动态图分析)的IFF。f _ backandf。f _ back。f _ back。f _包抛出异常RRR的kkwargs(else:while 1:try:returng)args,* * kwargs)exception、e: #捕获异常、参数获取、结束限定函数的递归调用堆栈args=e.args kwargs=e.kwargs func ._ _ doc _ _ g . _ _ doc _ _ return func @ tail _ call来自urnACCreturnfactorial(n-1,n*acc)打印阶乘)10000)
打开尾部递归优化前的调用堆栈
打开尾部递归优化后(tail _ call _优化装饰器)的调用堆栈
通过pudb右栏的堆栈,可以清楚地看到调用堆栈的变化。
计算机编程语言也不报告运行时错误:maximumrecurversiondepthexceeded错误,因为尾部递归没有调用栈嵌套。
下面介绍系统._getframe()函数:
系统._ get frame([Depth]):returnframeobjectfromthecallstack。ifoptionalintegerdepthisgiven,returntheframeobjectthamanycallsblowtopofthestack。ifhatisdeeperthanthecallstack,valueefrorisraised。defaulttforded返回theframeatttopofthecallstack。也就是说,这是返回深度调用的堆栈帧对象importsysdefget _ cur _ info(3360 printsys ._获取帧).当前文件名打印系统. getframe _ getframe
来自:https://段fault.com/a/119000007641519
郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。