利用尾递归减少栈空间的消耗
首先,需要给出一个定义,什么是尾递归。在《算法精解》中给出的定义如下:
如果一个函数中所有递归形式的调用都出现在函数的末尾,我们称这个递归函数是尾递归的。当递归调用是整个函数体中最后执行的语句且它的返回值不属于表达式的一部分时,这个递归调用就是尾递归的。尾递归函数的特点是在回归过程中不用做任何操作,这个特性很重要,因为大多数编译器会利用这个特点自动生成优化的代码。
看完上面这段描述,是不是觉得和没说差不多,看不明白。好吧,那就看看下面这张图吧。
这张图的左面是正常的递归,我们可以看到,越往深一层(即函数自身被调用一次),栈就要被多消耗掉一部分空间。而右边这张图,只有两次递归需要用到不同的栈空间,其余都是上次的空间被直接覆盖掉。
下面,我们利用普通的递归和尾递归计算一个表达式:
1 + 1/2 + 1/3 + 1/4 + .... + 1/n
代码如下:
#include <stdio.h>double pi(double n);
double pitail(double n, double a);int main(int argc, char *argv[])
{printf("%lf\n", pi(5));printf("%lf\n", pitail(5, 0));return 0;
}double pi(double n)
{if (n == 0) {return -1;} else if (n == 1) {return n;} else if (n > 1) {return pi(n-1) + 1/n;}
}double pitail(double n, double a)
{if (n == 0) {return -1;} else if (n == 1) {return a + 1;} else if (n > 1) {return pitail(n-1, a + 1/n);}
}
两种方法得到的结果当然是相同的。
利用尾递归减少栈空间的消耗相关推荐
- 在代码段中安排自己定义的栈空间
如何定义自己的栈(通过系统分配的内存) 完成下面的程序,利用栈.将程序中定义的数据逆序存放. 我们之前是如何安排自己的栈? 设置SS:SP(SS为栈顶的段地址存放处,栈顶偏移地址存放在SP) 我们如何 ...
- 栈空间和堆空间的区别
栈空间用于存储函数参数和局部变量,所需空间由系统自动分配,回收也由系统管理,无需人工干预:堆空间用于存储动态分配的内存块,分配和释放空间均由程序员控制,有可能产生内存泄漏. 栈空间作为一个严格后进先出 ...
- g++ linux 编译开栈_使用g++编译器扩大程序可用栈空间
如题,在写一些程序的时候我们有时会开一个比较大的数组或进行层数较多的dfs.这时候,程序常常会报错,于是就很无奈. 其实,虽然Windows给程序的默认栈空间比较小,我们还是有办法去扩大这个程序运行栈 ...
- 汇编中esp和ebp在函数栈空间的保存和变化 call的参数和局部变量的关系详解
目录 esp ebp 上一层ebp和本层ebp的保存方法 call 函数的参数在栈中的位置 总结函数参数和局部变量 od中查看 栈空间的返回到子程序的情况 esp call执行跳入子程序以后栈顶寄存器 ...
- 关闭compactos_HOWTO: 利用 CompactOS 减少 Windows 10 磁盘占用量
HOWTO: 利用 CompactOS 减少 Windows 10 磁盘占用量 gOxiA 今天要与大家分享的内容与 Windows 10 系统文件占用的磁盘容量有关,虽然现在大容量硬盘已经相当普及, ...
- 【编程基础】堆空间与栈空间
在 C 语言中,内存分布的部分情况如下图所示: 有些部分并没有在图中表示出来,实际上内存分布的功能划分从高地址到低地址依次是: 内核空间:应用程序不允许访问的部分,只能由内核进行操作,操作系统的内核程 ...
- java:栈空间,堆空间,方法区
栈空间: 1. 栈是方法执行的内存模型,用栈存储方法执行的信息是再合适不过了.每个方法被调用都会创建一个栈帧(存储局部变量,操作数,方法出口等). 2. JVM为每一个线程创建一个栈,用于存放该线程执 ...
- 汇编: 在代码中安排自己定义的数据,栈空间
assume cs:codecode segmentdw 1,2,3,4,5,6,7,8 ; 我们自定义的数据 不是我们自定义的指令; d:define w:wordstart: mov bx,0mo ...
- FreeRTOS 查询任务 剩余的栈空间的 方法
FreeRTOS 源码下载地址 1.官方文档提供了 函数 用来查询 任务 剩余 栈 空间,首先是看官方的文档解释(某位大神 翻译 的 官方文档.) 参数解释: xTask:被查询任 ...
最新文章
- GPT-2仅是“反刍”知识,真正理解语言还要改弦更张
- eruke注册中心搭建
- Halcon初学者知识 【13】如何在MFC中调用Halcon代码
- 在Centos7安装mysql
- Citrix虚拟化技术之一XenServer6.2安装
- Authorization object where used list in tcode SUIM
- 开源开放 | 熵简科技 AI Lab 开源金融领域中文预训练语言模型 FinBERT
- Python的安装(源码编译安装,IDE安装)
- [Java] 蓝桥杯ALGO-10 算法训练 集合运算
- [.NET 4.5] ADO.NET / ASP.NET 使用 Async 和 Await 异步 存取数据库
- (二)元学习算法MAML简介及代码分析
- Android反编译软件android killer教程
- 转-----EasyCHM制作教程
- 拖库 洗库 撞库的概念
- 华为推送服务(Push)
- 幽灵蛛(pholcus)(五)--json解析学习资料
- 2018-2019-2 20189221 《网络攻防技术》第八周作业
- 你知道h5游戏是什么吗,怎么制作一款h5案例?
- 小僧尽知他的备细出 水浒
- 快对作业超级计算机,快对作业2020