尾递归是怎么一回事?

作者: zhaoolee | 来源:发表于2018-03-23 16:22 被阅读120次

50%的算法问题都能通过递归来解决,倒不是说递归本身有多厉害,只是说明递归的思想让很多复杂的问题变得简单! 啥? 了解数据结构的人都知道, 树结构本身就是用递归定义的,所以解决树相关的问题会优先考虑递归

什么是尾递归?

众所周知, 递归会记录上一个函数的调用状态, 造成大量的资源占用, 为了尽量减少资源的占用, 有了为递归的玩法, 就是把递归操作放到 return 内, 由于return 是函数的最后一句, 所以, 就可以减少记录函数体的空间


两种递归方式

普通递归写法

function recursion(num){
    new_num = num + 1
    if (num >= 20000){
        return
    }
    console.log("普通递归|第",new_num,"次调用")
    recursion(new_num)
}

recursion(1)

尾递归写法 (直接将函数调用return出去 )

// 尾递归
function recursion2(num){
    new_num = num + 1
    if (num >= 20000){
        return
    }
    console.log("尾递归|第",new_num,"次调用")
    return recursion2(new_num)
}
recursion2(1)

尾递归节约了递归过程中压栈的内存消耗, 但这种玩法并不能突破递归栈的限制(python约为1000次, Chrome js环境约为20000次), 函数recursionreturn 自身之后 并没有析构释放空间,
为了验证以上说法,这里用Python举一个例子(js的析构很难写, 还是python好用...)

析构时机
class Recursion(object):
    def __init__(self, num):
        self.num = num
        print("对象obj",self.num, "建立")

    def __del__(self):
        print("对象obj", self.num-1, "析构")
    # 尾递归
    def add(self):
        print(">>尾递归|第",self.num,"次")
        self.num += 1
        if (self.num>10):
            return
        else:
            return Recursion(self.num).add()
    # 正常递归
    def add2(self):
        print(">>正常递归|第",self.num,"次递归")
        self.num += 1
        if (self.num>10):
            return
        else:
            Recursion(self.num).add2()  

def main():
    # 尾递归
    recu = Recursion(1)
    recu.add()
    # 正常递归
    recu2 = Recursion(1)
    recu2.add2()

if __name__ == '__main__':
    main()

相关文章

  • 尾递归是怎么一回事?

    50%的算法问题都能通过递归来解决,倒不是说递归本身有多厉害,只是说明递归的思想让很多复杂的问题变得简单! 啥? ...

  • Kotlin语言(九):特性

    1、尾递归优化 尾递归:函数在调用自己之后没有再执行其他任何操作就是尾递归 尾递归优化的原理就是将递归转换成迭代,...

  • python学习

    1:尾递归 解决递归调用栈溢出的方法是通过尾递归优化,事实上尾递归和循环的效果是一样的,所以,把循环看成是一种特殊...

  • 尾调用优化

    尾调用优化 尾递归 正常递归 尾递归 改写以上代码,使其只有一个参数: 总结一下,递归本质上是一种循环操作。纯粹的...

  • 理解装饰器的各种执行细节

    当装饰器遇上尾递归函数 如果一个尾递归函数套用了装饰器,那么当一次递归发生后,是尾递归内部的代码先执行,还是装饰器...

  • 斐波那契数列与Python的尾递归蹦床 连载【2】

    ……续上回 斐波那契数列与Python的尾递归蹦床连载【1】 4. 生成器式尾递归解法 前面尾递归是用的retur...

  • 尾递归

    尾递归就是操作的最后一步是调用自身的递归。 这是尾递归: (这个程序没什么意义,仅作为理解辅助之用)。 这不是尾递...

  • 递归&尾递归

    调用栈的特点,先进后出, FILO, 场景还原。 递归 有栈溢出的可能 stack overflow 尾递归 编译...

  • 9. 递归函数

    使用递归函数需要注意防止栈溢出解决递归调用栈溢出的方法是通过尾递归优化遗憾的是,大多数编程语言没有针对尾递归做优化...

  • 递归调用优化

    尾递归优化 函数调用自身,称为递归。如果尾调用自身,就称为尾递归。 递归非常耗费内存,因为需要同时保存成千上百个调...

网友评论

  • 王植尉Xavier:请楼主赐教,感觉这两种递归的效果都一样啊
    zhaoolee:@王植尉Xavier 同样是压栈,尾递归压栈需要的空间要小一些

本文标题:尾递归是怎么一回事?

本文链接:https://www.haomeiwen.com/subject/xvcxcftx.html