文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

什么是python尾递归

2024-04-02 19:55

关注

本篇内容主要讲解“什么是python尾递归”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“什么是python尾递归”吧!

递归是啥?

递归函数大家肯定写过,学校上课的时候,估计最开始的例子就是斐波拉契数列了吧。例如:

int Fibonacci(n) {     if (n < 2) return n;     return Fibonacci(n - 1) + Fibonacci(n - 2); }

递归函数简而言之就是在一个函数中,又“递归”调用自己。在写递归函数的时候,需要注意的地方就是递归函数的结束条件。用递归函数确实能简化很多算法的实现,比如常见的二叉树遍历等。但往往在写递归函数的时候,最容易出现的问题就是所谓的“栈溢出”。

为什么会有“栈溢出”呢?因为函数调用的过程,都要借助“栈”这种存储结构来保存运行时的一些状态,比如函数调用过程中的变量拷贝,函数调用的地址等等。而“栈”往往存储空间是有限的,当超过其存储空间后,就会抛出著名的异常/错误“StackOverflowError”。

我们以一个简单的加法为例,例如:

int sum(int n) {     if (n <= 1) return n;     return n + sum(n-1); }  std::cout << sum(100) << std::endl; std::cout << sum(1000000) << std::endl;

很简答,编译运行后,比较小的数字,能得到正确的答案,当数字扩大后,就会直接发生“segmentation fault”。

尾递归又是啥?

我得知这个概念,最开始还是因为很多年前一次面试,面试官问我“你知道什么是尾递归吗?”,我以为是“伪”递归,难道是假的递归???当初我也是懵逼状态(当初面试官忍住没笑也是厉害了)。从“尾”字可看出来即若函数在尾巴的地方递归调用自己。上面的例子写成尾递归,就变成了如下:

int tailsum(int n, int sum) {     if (n == 0) return sum;     return tailsum(n-1, sum+n); }

可以试试结果,计算从 1 加到 1000000,仍然是segmentation  fault。为什么呢?因为这种写法,本质上还是有多层的函数嵌套调用,中间仍然有压栈、出栈等占用了存储空间(只不过能比前面的方法会省部分空间)。

尾递归优化

当你给编译选项开了优化之后,见证奇迹的时刻到了,居然能算出正确结果。如图所示:

什么是python尾递归

C++ 默认 segmentation fault, 开启编译优化后,能正常计算结果。

原因就是因为编译器帮助做了尾递归优化,可以打开汇编代码看看(这里就不展示 C++的了)。后面我用大家比较熟悉的 JVM based 语言 Scala  来阐述这个优化过程。(好像 Java 的编译器没做这方面的优化,至少我实验我本地 JDK8 是没有的,不清楚最新版本的有木有)(scala  本身提供了一个注解帮助编译器强制校验是否能够进行尾递归优化@tailrec)

object TailRecObject {     def tailSum(n: Int, sum: Int): Int = {         if (n == 0) return sum;         return tailSum(n-1, n+sum);    }     def main(args: Array[String]) {       println(tailSum(100, 0))       println(tailSum(1000000, 0))    }  }

结果如下图所示,默认情况下 scalac 做了尾递归优化,能够正确计算出结果,当通过 -g:notailcalls 编译参数去掉尾递归优化后,就发生了  Exception in thread "main" java.lang.StackOverflowError了。

什么是python尾递归

默认启用尾递归优化正常计算结果,禁用尾递归优化则“StackOverflow”。

我们来看看生成的字节码有什么不同。

什么是python尾递归

包含尾递归优化的字节码,直接 goto 循环。

什么是python尾递归

禁用尾递归优化的字节码,方法调用。

从上面可以看出,尾递归优化后,变成循环了(前面的 C++ 类似)。

到此,相信大家对“什么是python尾递归”有了更深的了解,不妨来实际操作一番吧!这里是编程网网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     807人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     351人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     314人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     433人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     221人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯