【 声明:版权所有,欢迎转载,请勿用于商业用途。  联系信箱: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;
}

【预告: 下面一篇博客介绍算法和内存】

一步一步写算法(之递归和堆栈)相关推荐

  1. 一步一步写算法(之函数堆栈显示)

    [ 声明:版权所有,欢迎转载,请勿用于商业用途.  联系信箱:feixiaoxing @163.com ] 在继续图的讨论之前,我们今天开个小差,讨论一下函数堆栈的基本原理.有过编程经验的朋友都知道, ...

  2. 一步一步写算法(之线性堆栈)

    [ 声明:版权所有,欢迎转载,请勿用于商业用途.  联系信箱:feixiaoxing @163.com] 前面我们讲到了队列,今天我们接着讨论另外一种数据结构:堆栈.堆栈几乎是程序设计的命脉,没有堆栈 ...

  3. 一步一步写算法(之循环和递归)

    [ 声明:版权所有,欢迎转载,请勿用于商业用途.  联系信箱:feixiaoxing @163.com] 其实编程的朋友知道,不管学什么语言,循环和递归是两个必须学习的内容.当然,如果循环还好理解一点 ...

  4. 一步一步写算法(之循环和递归)(转)

    其实编程的朋友知道,不管学什么语言,循环和递归是两个必须学习的内容.当然,如果循环还好理解一点,那么递归却没有那么简单.我们曾经对递归讳莫如深,但是我想告诉大家的是,递归其实没有那么可怕.所谓的递归就 ...

  5. 一步一步写算法(开篇)

    [ 声明:版权所有,欢迎转载,请勿用于商业用途.  联系信箱:feixiaoxing @163.com] 算法是计算机的生命.没有算法,就没有软件,计算机也就成了一个冰冷的机器,没有什么实用价值.很多 ...

  6. 一步一步写算法(之图结构)

    原文:一步一步写算法(之图结构) [ 声明:版权所有,欢迎转载,请勿用于商业用途.  联系信箱:feixiaoxing @163.com] 图是数据结构里面的重要一章.通过图,我们可以判断两个点之间是 ...

  7. 一步一步写算法(之prim算法 中)

    原文:一步一步写算法(之prim算法 中) [ 声明:版权所有,欢迎转载,请勿用于商业用途.  联系信箱:feixiaoxing @163.com] C)编写最小生成树,涉及创建.挑选和添加过程 MI ...

  8. 一步一步写算法(之寻找丢失的数)

    一步一步写算法(之寻找丢失的数) 原文:一步一步写算法(之寻找丢失的数) [ 声明:版权所有,欢迎转载,请勿用于商业用途.  联系信箱:feixiaoxing @163.com] 假设我们有一个1亿个 ...

  9. 一步一步写算法(之克鲁斯卡尔算法 中)

    一步一步写算法(之克鲁斯卡尔算法 中) 原文:一步一步写算法(之克鲁斯卡尔算法 中) [ 声明:版权所有,欢迎转载,请勿用于商业用途.  联系信箱:feixiaoxing @163.com] 前面说到 ...

  10. 一步一步写算法(之prim算法 下)

    [ 声明:版权所有,欢迎转载,请勿用于商业用途.  联系信箱:feixiaoxing @163.com] 前两篇博客我们讨论了prim最小生成树的算法,熟悉了基本的流程.基本上来说,我们是按照自上而下 ...

最新文章

  1. vue下轻松解决模拟微信视频缩略图拖拽→吸附窗口边界的功能
  2. 移动端自动化测试(一)appium环境搭建
  3. 计算机基础算法棋盘覆盖,分治算法求解棋盘覆盖问题互动教学过程.doc
  4. Could not find codec parameters for stream 0 (Video: h264, none)
  5. Java实现算法导论中Miller-Rabin随机性素数测试
  6. 将ListT集合用DataGridView展示
  7. java swing总结,Java 实用经验总结 Swing 篇
  8. MKMapView的Span和Region深入分析
  9. 汇编烧程序进单片机要什么软件_单片机编程语言及应用技巧解析
  10. 地铁 java_怎么用Java编写一个地铁售票机的程序?
  11. leetcode 1202 python
  12. [UVa11995] I Can Guess the Data Structure!
  13. 大规模均衡分割与层次聚类
  14. 第107章 SQL函数 $PIECE
  15. MacOS解压rar文件
  16. deny后加to do还是doing_常见的后面只能接to do的词组(不能接doing)有哪些
  17. react 页面跳转(下一页,返回上一页)
  18. 深圳软件测试培训:Pytest+Appium+Allure 做 UI 自动化的那些事
  19. Matlab 断供哈工大,国产替代软件挺身而出,霸气!
  20. MFC-Toolbar(24位真彩色)

热门文章

  1. linux下面实现执行rm命令,显示do not use rm command
  2. angularjs 模块化
  3. 树莓派-linux的多种启动自运行方式
  4. Bootstrap-基于jquery的bootstrap在线文本编辑器插件Summernote
  5. 1、图解Oracle Logminer配置使用
  6. Lync 2010 企业版安装
  7. 一步一步学Silverlight 2系列(27):使用Brush进行填充
  8. JavaScript——Prototype详探
  9. Java数据结构——顺序表
  10. 求最近点对算法分析 closest pair algorithm