一步一步写算法(之递归和堆栈)
【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing @163.com】
看过我前面博客的朋友都清楚,函数调用主要依靠ebp和esp的堆栈互动来实现的。那么递归呢,最主要的特色就是函数自己调用自己。如果一个函数调用的是自己本身,那么这个函数就是递归函数。
我们可以看一下普通函数的调用怎么样的。试想如果函数A调用了函数B,函数B又调用了函数C,那么在堆栈中的数据是怎么保存的呢?
函数A ^
函数B | (地址递减)
函数C |
如果是递归函数呢,举一个简单的递归函数为例:
int iterate(int value)
{
if(value == 1)
return 1;
return value + iterate(value -1);
}
下面我们使用一个函数进行调用,看看会发生什么情况?
void process()
{
int value = iterate(6);
}
看看此时内存堆栈是什么样的?
iterate(int 1) line 96
iterate(int 2) line 97 + 12 bytes
iterate(int 3) line 97 + 12 bytes
iterate(int 4) line 97 + 12 bytes
iterate(int 5) line 97 + 12 bytes
iterate(int 6) line 97 + 12 bytes
process() line 102 + 7 bytes
main() line 108
mainCRTStartup() line 206 + 25 bytes
KERNEL32! 7c817067()
大家也看到了上面的代码,递归函数和普通的函数也没有什么差别。除了自己调用本身之外,他就是一个普通的函数。那么这个函数递归到什么时候返回呢?这就是递归函数的关键了。我们看到iterate函数到1就停止了,所以上面的堆栈在(value == 1)即return。所以一个递归函数最关键的部分就是两点:(1)递归策略;(2)函数出口。
看到这里,大家可能感到递归函数不过如此,事实上也是这样。但是,还有一点大家需要牢记在心,递归的深度是我们必须考虑的一个问题。只有递归深度在一个可控的范围内,那么整个递归过程都是可控的。那什么时候不可控呢?那就是递归深度超过了一定的数字?这个数字和具体的线程堆栈长度有关?等到堆栈溢出了,那么获得的数据已经失去了真实性,所以也就没有意义了。
我们把上面的问题推广一下,如何用自己定义的堆栈模拟上面的递归调用呢?这样既能满足递归的属性,又能确保函数深度可控。
大家可以先写一下自己的方案,下面只是我个人的一个思路。
int iterate(int value)
{
int count = 0;
int number =0;
push(value);
while(-1 != (number = pop()))
{
if(1 != number)
push(number -1);
count += number;
}
return count;
}
【预告: 下面一篇博客介绍算法和内存】
一步一步写算法(之递归和堆栈)相关推荐
- 一步一步写算法(之函数堆栈显示)
[ 声明:版权所有,欢迎转载,请勿用于商业用途. 联系信箱:feixiaoxing @163.com ] 在继续图的讨论之前,我们今天开个小差,讨论一下函数堆栈的基本原理.有过编程经验的朋友都知道, ...
- 一步一步写算法(之线性堆栈)
[ 声明:版权所有,欢迎转载,请勿用于商业用途. 联系信箱:feixiaoxing @163.com] 前面我们讲到了队列,今天我们接着讨论另外一种数据结构:堆栈.堆栈几乎是程序设计的命脉,没有堆栈 ...
- 一步一步写算法(之循环和递归)
[ 声明:版权所有,欢迎转载,请勿用于商业用途. 联系信箱:feixiaoxing @163.com] 其实编程的朋友知道,不管学什么语言,循环和递归是两个必须学习的内容.当然,如果循环还好理解一点 ...
- 一步一步写算法(之循环和递归)(转)
其实编程的朋友知道,不管学什么语言,循环和递归是两个必须学习的内容.当然,如果循环还好理解一点,那么递归却没有那么简单.我们曾经对递归讳莫如深,但是我想告诉大家的是,递归其实没有那么可怕.所谓的递归就 ...
- 一步一步写算法(开篇)
[ 声明:版权所有,欢迎转载,请勿用于商业用途. 联系信箱:feixiaoxing @163.com] 算法是计算机的生命.没有算法,就没有软件,计算机也就成了一个冰冷的机器,没有什么实用价值.很多 ...
- 一步一步写算法(之图结构)
原文:一步一步写算法(之图结构) [ 声明:版权所有,欢迎转载,请勿用于商业用途. 联系信箱:feixiaoxing @163.com] 图是数据结构里面的重要一章.通过图,我们可以判断两个点之间是 ...
- 一步一步写算法(之prim算法 中)
原文:一步一步写算法(之prim算法 中) [ 声明:版权所有,欢迎转载,请勿用于商业用途. 联系信箱:feixiaoxing @163.com] C)编写最小生成树,涉及创建.挑选和添加过程 MI ...
- 一步一步写算法(之寻找丢失的数)
一步一步写算法(之寻找丢失的数) 原文:一步一步写算法(之寻找丢失的数) [ 声明:版权所有,欢迎转载,请勿用于商业用途. 联系信箱:feixiaoxing @163.com] 假设我们有一个1亿个 ...
- 一步一步写算法(之克鲁斯卡尔算法 中)
一步一步写算法(之克鲁斯卡尔算法 中) 原文:一步一步写算法(之克鲁斯卡尔算法 中) [ 声明:版权所有,欢迎转载,请勿用于商业用途. 联系信箱:feixiaoxing @163.com] 前面说到 ...
- 一步一步写算法(之prim算法 下)
[ 声明:版权所有,欢迎转载,请勿用于商业用途. 联系信箱:feixiaoxing @163.com] 前两篇博客我们讨论了prim最小生成树的算法,熟悉了基本的流程.基本上来说,我们是按照自上而下 ...
最新文章
- vue下轻松解决模拟微信视频缩略图拖拽→吸附窗口边界的功能
- 移动端自动化测试(一)appium环境搭建
- 计算机基础算法棋盘覆盖,分治算法求解棋盘覆盖问题互动教学过程.doc
- Could not find codec parameters for stream 0 (Video: h264, none)
- Java实现算法导论中Miller-Rabin随机性素数测试
- 将ListT集合用DataGridView展示
- java swing总结,Java 实用经验总结 Swing 篇
- MKMapView的Span和Region深入分析
- 汇编烧程序进单片机要什么软件_单片机编程语言及应用技巧解析
- 地铁 java_怎么用Java编写一个地铁售票机的程序?
- leetcode 1202 python
- [UVa11995] I Can Guess the Data Structure!
- 大规模均衡分割与层次聚类
- 第107章 SQL函数 $PIECE
- MacOS解压rar文件
- deny后加to do还是doing_常见的后面只能接to do的词组(不能接doing)有哪些
- react 页面跳转(下一页,返回上一页)
- 深圳软件测试培训:Pytest+Appium+Allure 做 UI 自动化的那些事
- Matlab 断供哈工大,国产替代软件挺身而出,霸气!
- MFC-Toolbar(24位真彩色)