学编程语言的人都知道递归,但不一定所有人都明白它是如何被执行的。接下来我想谈一下我对递归的认识和理解。
如果一个算法调用自己来完成它的部分工作,则这个算法是递归的。举一个小小的例子:
#include<iostream>
using namespace std;
void test(int a){
if(a>1){
test(a-1);
test(a-2);
}
cout<<a<<endl;
}
void main(){
test(3);
}
输出结果为:1 0 2 1 3
为什么会这样呢?这与递归的存储机制有关。
递归的子程序调用通过将有关子程序的一些必要信息(如返回地址、参数、局部变量等)存储到栈中来实现它的目的。栈结构的特点为FILO(先进后出)。 现在来看上面的例子,主函数中第一次调用test时,把test指令所在的地址保存到栈中,并把3传给test。 接下来test(a-1)对test进行递归调用,调用时参数变为2,这时test(a-1)指令所在的地址和参数2一起被保存到栈中。
test(a-1)继续递归调用test,参数变为1,这时test(a-1)指令所在的地址和参数1一起被保存到栈中。
第三次调用test时if(a>1)不满足,所以不执行if语句中的内容,执行cout语句,输出a(此时a为1)。注意此时test(a-1)对test的第三次调用结束,每一次从test返回都将弹出栈所保存的a的当前值,以及函数调用所返回的地址。所以返回到第二次调用时的地址,而第二次调用test函数没有执行完里面的内容,因此在第二次调用里继续接下来的语句(从程序的第六行到第九行),第六行又是一个递归调用,相当于递归里的递归。我们已经知道,此时a=1已经被弹出栈,现在的a=2,test(a-2)调用test后a变为0,由于0<=1,所以直接执行cout语句,输出0。这个过程中,test(a-2)和test(a-1)一样,也要保存它的指令地址和参数的值。a=0弹出栈后栈为空,test(a-2)的调用结束。最后一定不要忘记执行cout语句,输出2.至此,test(a-1)的第二次调用已全部完成。
最后返回test(a-1)第一次调用的地址,a=3,继续从程序的第六行到第九行执行下去(执行方式与第二次调用一样,在此我不再赘述)。不过要强调的一点就是,在执行递归的递归结束后,一定要知道程序具体返回到哪里, 不要混淆。此次输出1和3.至此,第一次调用结束,返回到程序的第十一行。
遇到不太清楚过程的程序一定要多上机调试,从每一步的结果中得到启发,才能对其有更深刻的理解。
分享到:
相关推荐
根据给定文件的信息,我们可以提炼出递归机制与非递归转换的相关知识点: ### 递归机制 #### 定义 递归是一种方法,通过在函数内部调用自身来解决问题的技术。递归的关键在于确定一个或多个基本情况(base cases)...
易语言虽然使用中文编程,但其递归机制与大多数其他编程语言类似,理解和掌握递归是提高编程技能的重要一步。通过这个99表的例子,我们可以学习到如何在易语言中运用递归,这将有助于我们在解决更复杂问题时的思考和...
在给定的标题“一个递归调用的存储过程”中,我们可以推测这个存储过程利用了递归机制来解决某个问题。 描述中提到的博文链接指向了iteye博客的一个条目,尽管具体内容没有提供,但我们可以假设它会详细解释如何...
这不仅锻炼了对文法的理解,也提升了对程序控制流和递归机制的掌握。在实现过程中,你可以使用栈数据结构来辅助管理当前解析的状态,以更高效地处理嵌套结构。 最后,为了测试你的解析器,你需要准备一系列输入符号...
在语言学中,这一概念主要由诺姆·乔姆斯基在1957年的《句法结构》中提出,他强调递归机制对于语言生成的重要性。递归性是生成语法的基石,使得有限的规则能够生成无限数量的句子。 语言递归性的核心特征包括四个...
乔姆斯基的生成语法理论将递归作为语言的“离散的无限性”的根源,认为语言单位可以通过递归机制进行无限重复、并列、内嵌等操作,形成丰富多样的语言表达式。这种对于递归性在语言学中的理解也启示我们,在体育教学...
Hanoi塔问题的非递归算法开发,就是在形式化方法的指导下,为问题寻找一个不依赖递归机制的解决方案。递归是算法设计中常用的一种技术,但在某些情况下,递归可能会导致效率低下或资源消耗过大,因此,研究非递归...
Java作为一门广泛使用的高级编程语言,其内置的多线程机制为开发者提供了丰富的工具,以便在多核架构上进行高效编程。在递归算法中,利用Java的多线程特性可以显著提升算法的执行效率,尤其是在处理大规模数据集时。...
### ABAP简单递归算法解析 #### 一、引言 ABAP(Advanced Business ...通过上述分析,我们不仅了解了递归算法的工作机制,也熟悉了ABAP中递归函数的实现方法,这对于进一步学习和应用ABAP编程具有重要意义。
通过递归机制,我们可以定义一个名为`fact`的函数,当n等于0时,阶乘值为1,否则阶乘值为n乘以`fact(n-1)`。递归的关键在于,每次调用`fact`函数,都是在解决规模更小但结构相同的问题,直到达到基本情况(n=0)。 ...
C++递归程序的概念及其执行过程 递归是计算机科学中的一个核心概念,它是一种解决复杂问题的方法...通过仔细分析递归调用的每一步,我们可以更加深入地理解递归的工作机制,并在未来的编程实践中更好地运用这一技术。
使用场景及目标帮助读者理解并应用二分搜索来定位数据集中的指定元素,运用递归方式得到斐波纳契数,通过递归机制执行高效的数据排列,同时还可以方便统计定量数据集的平均值。 学习指导本资料详细附有代码注释便于...
- **对于数据量较大且层级较多的情况**,使用变量和循环的方法可能更加高效,因为它可以更好地利用数据库的优化机制。 #### 五、总结 本文通过对比两种MySQL递归树查询方法——使用自连接和递归联合以及利用变量和...
4. **性能优化**:由于递归可能导致大量的数据库查询,因此需要考虑缓存策略和懒加载机制,只在需要时加载子节点。 结合上述两个概念,"分页+递归显示"意味着在分页控件中,不仅能够逐页加载数据,还能以树状结构...
此外,错误恢复机制通常不如递归下降解析器灵活。 在实际应用中,非递归预测分析常用于编译器的实现,或者在解释器、语法高亮器等工具中。通过学习和理解这一技术,我们可以更好地设计和优化编译器,提高程序的编译...
在IT行业中,尤其是在软件开发领域,递归和非递归算法是解决问题的两种常见方法,特别是在处理层次结构数据,如树形结构时。QT库,一个C++的跨平台应用程序开发框架,提供了丰富的UI组件,其中包括QTreeWidget,用于...
总的来说,程序设计语言的语法描述是理解和编写代码的基础,通过文法、规则和递归机制,我们能够构建和解析复杂的程序结构,从而实现计算机理解和执行我们的指令。理解这些概念对于任何从事编程和软件开发的人来说都...
### Hanoi程序实现:栈的应用与递归理解 在计算机科学中,汉诺塔(Hanoi)问题是一个经典的递归...通过对上述代码的深入分析,我们可以更好地理解栈的操作和递归机制,这对于学习高级编程技巧和算法设计具有重要意义。
在Java递归树型结构通用数据库中,提供了异常处理机制,可以捕捉和处理数据库访问中出现的异常,具有良好的可维护性和可靠性。 10. 可扩展性设计 在Java递归树型结构通用数据库中,提供了可扩展性设计,可以根据...
尽管如此,由于Python的递归机制,即使增加了递归深度,过度的递归仍然可能导致内存问题。 接下来,我们来看迭代。迭代是通过重复执行一段代码来处理一组数据的过程,每次迭代的输出作为下一次迭代的输入。在Python...