数据结构和算法 函数调用栈和递归
2023-09-14 09:15:03 时间
现代高级语言编译的程序几乎总是使用堆栈帧来存储每个过程或函数调用的工作内存。当任何过程或函数被调用时,一些栈帧被压入程序栈。当过程或函数返回时,这帧数据会从堆栈中弹出。
![](https://img-blog.csdnimg.cn/e896b43a1d8749c4a00723263d311c82.png?x-oss-process=image/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBAYmFzaGVuZGl4aWU1,size_18,color_FFFFFF,t_70,g_se,x_16)
1、栈有两种操作:压缩和弹出。
2、所有函数调用都进入调用栈。
3、调用栈可能很长,这将占用大量内存。
4、普通递归每次函数调用,计算机都将为其在栈中分配内存。优化方法
(1)重新编写代码,转而使用循环。
(2)使用尾递归,但是并非所有语言都支持尾递归。
5、尾递归的定义:如果一个函数中所有递归形式的调用都出现在函数的末尾,我们称这个递归函数是尾递归的。当递归调用是整个函数体中最后执行的语句且它的返回值不属于表达式的一部分时,这个递归调用就是尾递归。尾递归函数的特点是在回归过程中不用做任何操作,这个特性很重要,因为大多数现代的编译器会利用这种特点自动生成优化的代码。
6、尾递归的原理:当编译器检测到一个函数调用是尾递归的时候,它就覆盖当前的活动记录而不是在栈中去创建一个新的。编译器可以做到这点,因为递归调用是当前活跃期内最后一条待执行的语句,于是当这个调用返回时栈帧中并没有其他事情可做,因此也就没有保存栈帧的必要了。通过覆盖当前的栈帧而不是在其之上重新添加一个,这样所使用的栈空间就大大缩减了,这使得实际的运行效率会变得更高。
参考代码
int calc(int n, int res)
{
if (n < 0)
return 0;
else if(n == 0)
return 1;
else if(n == 1)
return res;
else
return calc(n - 1, n *res);
}
7、python递归深度有限制,Python标准的解释器没有针对尾递归做优化,任何递归函数都存在栈溢出的问题。
相关文章
- 大数据必学Java基础(五十一):什么是算法和数据结构
- 算法步步为营(1)-两数之和
- 非局部均值滤波算法[通俗易懂]
- 滴滴新算法让你应对女友?道翰天琼认知智能机器人平台API接口大脑为您揭秘-64
- 产品能力|算法基础-哈夫曼树14天阅读挑战赛
- 【算法竞赛 - 数据结构】数据分割
- AVX图像算法优化系列二: 使用AVX2指令集加速查表算法。
- C++算法与数据结构之map
- 算法与数据结构之图
- 《算法竞赛进阶指南》0x23 剪枝
- 【数据结构】24种常见算法题
- Go 数据结构和算法篇(九):二分查找
- Go 数据结构和算法篇(十一):字符串匹配之 BF 算法
- 数据结构和算法面试常见题必考以及前端面试题
- 算法初学者的第一个数据结构,数组和vector
- 人脸检测和对齐算法MTCNN
- java数据结构和算法(二)
- java数据结构和算法(三)
- 自动泊车之停车位检测算法(角点检测/语义分割)
- PTA 数据结构与算法题目集(中文)7-7 六度空间 (30分) 题解
- 算法刷题-二叉树的锯齿形层序遍历、用栈实现队列 栈设计、买卖股票的最佳时机 IV
- 【算法数据结构专题】「延时队列算法」史上手把手教你针对层级时间轮(TimingWheel)实现延时队列的开发实战落地(下)
- 医疗图像方向硕士,焦虑发论文毕业,咨询好的CV算法方向,与同门如何合作?
- 一种求离散数学传递闭包的算法java实现详解编程语言
- Java数据结构和算法(九)——高级排序详解编程语言
- java 数据结构与算法—递归详解编程语言
- 分布式ID生成分布式系统中替代Redis雪花算法的ID生成策略(redis雪花算法类似的)
- 使用PHP实现二分查找算法代码分享
- php实现简单洗牌算法
- java数据结构和算法学习之汉诺塔示例
- 马尔可夫链算法(markov算法)的awk、C++、C语言实现代码