我的编程空间,编程开发者的网络收藏夹
学习永远不晚

什么是python尾递归

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

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

什么是python尾递归

本篇内容主要讲解“什么是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

什么是python尾递归

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

Python怎么开启尾递归优化

这篇文章主要讲解了“Python怎么开启尾递归优化”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Python怎么开启尾递归优化”吧!一般递归与尾递归一般递归:def normal_recur
2023-06-30

python怎么实现尾递归优化

小编给大家分享一下python怎么实现尾递归优化,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!说明1、尾递归是指在函数返回时调用自身,return语句不能包含表达
2023-06-20

C++ 函数尾递归优化的条件是什么?

c++++ 中尾递归优化 (tco) 的条件如下:尾递归调用必须是函数的最后一个动作。函数的参数和局部变量在尾递归调用中必须保持不变。编译器必须支持 tco。实战案例中,使用 tco 将阶乘计算函数的尾递归调用转换为 while 循环,提高
C++ 函数尾递归优化的条件是什么?
2024-04-11

python中什么是递归算法

本篇文章为大家展示了python中什么是递归算法,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。python主要应用领域有哪些1、云计算,典型应用OpenStack。2、WEB前端开发,众多大型网站均
2023-06-14

Javascript尾递归编程怎么实现

本篇内容介绍了“Javascript尾递归编程怎么实现”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!尾递归编程思想递归是编程中必不可少的一环
2023-07-02

python中的递归函数是什么

这篇文章将为大家详细讲解有关python中的递归函数是什么,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。Python的优点有哪些1、简单易用,与C/C++、Java、C# 等传统语言相比,Python对代
2023-06-14

java中什么是递归

什么是递归递归做为一种算法在程序设计语言中广泛应用,它是指函数/过程/子程序在运行过程中直接或间接调用自身而产生的重入现象。递归算法一般用于解决三类问题:a.数据的定义是按递归定义的。(Fibonacci(斐波那契)函数)b.问题解法按递归算法实现。(回溯)c
java中什么是递归
2016-03-23

python递归优化的方法是什么

在Python中,递归函数的优化方法主要有以下几种:1、尾递归优化尾递归是指递归函数在递归调用时,最后一个操作是函数调用本身,可以通过尾递归优化来避免递归深度过大的问题。尾递归优化可以通过改写递归函数,将中间变量传递到下一次递归调用中,避免
2023-05-13

Python函数的递归方法是什么

本篇内容介绍了“Python函数的递归方法是什么”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!函数调用自身的 编程技巧 称为递归。1.1、递
2023-06-22

python递归函数的特点是什么

Python递归函数的特点包括:1. 函数可以调用自身:递归函数可以在函数体内直接调用自身,从而实现对问题的重复求解。2. 递归函数必须有一个终止条件:为了避免无限递归,递归函数必须有一个终止条件,当满足该条件时,递归函数将不再调用自身。3
2023-08-29

php递归函数是什么

这篇文章将为大家详细讲解有关php递归函数是什么,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。递归就是一个函数在它的函数体内调用它自身。执行递归函数将反复调用其自身,每调用一次就进入新的一层。递归函数必须
2023-06-14

什么是递归存储过程以及为什么 MySQL 限制递归?

如果存储过程调用自身,则该存储过程称为递归。基本上,这个概念称为递归。 MySQL限制了递归,因此错误不会那么严格。我们可以借助以下查询来检查此限制 -mysql> Show variables LIKE %recur%;+-------
2023-10-22

PHP中递归函数是什么

这期内容当中小编将会给大家带来有关PHP中递归函数是什么,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。什么是递归函数:递归就是某个函数直接或间接地调用了自身,这种调用方式叫做递归调用。说白了,还是函数调用
2023-06-15

Python中使用装饰器来优化尾递归的示例

尾递归简介 尾递归是函数返回最后一个操作是递归调用,则该函数是尾递归。 递归是线性的比如factorial函数每一次调用都会创建一个新的栈(last-in-first-out)通过不断的压栈,来创建递归, 很容易导致栈的溢出。而尾递归则使用
2022-06-04

Java二叉树的递归和非递归遍历方法是什么

本篇内容主要讲解“Java二叉树的递归和非递归遍历方法是什么”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Java二叉树的递归和非递归遍历方法是什么”吧!前言二叉树的遍历方法分为前序遍历,中序遍
2023-06-30

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录