`
Candy_Code
  • 浏览: 14480 次
  • 性别: Icon_minigender_1
社区版块
存档分类
最新评论

关于递归,不得不说的

阅读更多
二话不说,先上代码
public class TestRecursion{
	//递归方法
	public static  void fun(int i){
		if(i > 0){
			i--;
			fun(i);
			System.out.print(i);
		}
		System.out.print(" ok ");
	}
	public static void main(String args[]){
		fun(10);
	}
}


这段代码看似简单,其中的奥秘你却未必尽知。
首先.什么是递归?相信大家都知道,就是方法直接或间接地调用自身。
要想深入理解递归,得从栈的角度去看待方法间的调用。
先来看一个简单的例子:

public void a(){}
public void b(){
	System.out.println("Hello");
	a();
	System.out.println("boy");
}


方法b()调用了方法a(),此时程序不再顺序执行,而是发生跳转。CPU首先将下一条机器指令的地址以及相关的参数信息压入栈中,然后程序跳转到a()的方法体中。当a()方法返回时,CPU会执行出栈操作,取出上一次存储的机器指令的地址以及参数信息,即System.out.println("boy")(当然了,System.out.println()不是一条机器指令,而是被翻译成多条机器指令)
递归方法也是一个道理,只不过,调用者与被调用者是同一个方法。
递归与循环的有些相似,但又截然不同。循环没有方法间的调用关系,也就没有指令地址的压栈、出栈,它仅仅指令地址的改变。
现贴出TestRecursion小程序的输出结果:

 ok 0 ok 1 ok 2 ok 3 ok 4 ok 5 ok 6 ok 7 ok 8 ok 9 ok 


分析调用过程:fun(10)->fun(9)->fun(8)->fun(7)->fun(6)->fun(5)->fun(4)->fun(3)->fun(2)->fun(1)->fun(0)
我们倒过来分析:当i=0时,首次不满足i>0的条件,所以首先打印“ok"。然后fun(0)结束了,返回到fun(1)中,执行调用fun(0)的下一条语句,即System.out.print(i),此时i=0.肯定有的朋友不明白为什么这里i=0.看下面的代码

public static  void fun(int i){//此时i==1
	if(i > 0){//yes
		i--; //此时i==0了
		fun(i);//即fun(0)
		System.out.print(i);//i==?
	}
	System.out.print(" ok ");
}


继续分析:打印"0",又打印" ok ",之后fun(1)方法结束了,返回到fun(2)调用fun(1)的下一条语句,System.out.print(i),此时i=1,依次类推。

分享到:
评论
4 楼 weiwei14811 2012-08-29  
很不错,
3 楼 Leasen 2012-08-09  
建议楼主看看Inside JVM,看一下执行栈那一段  可能会理解得更深入一点
2 楼 ifox 2012-03-09  
不错啊,我又debug一下。感觉理解效果更好 了
1 楼 java小生 2012-03-07  
Recursion

相关推荐

    不得不说的全排列算法递归实现

    对于初学者来说,通过编写递归算法来实现全排列,能够加深对递归逻辑的理解,提高编程能力,并且掌握算法中涉及的重要概念,如回溯、基准情况、状态保存和恢复等。通过不断练习和思考,相信每个人都能熟练掌握全排列...

    C语言递归求汉诺塔问题.docx

    庙里的僧人们必须把所有金盘从这根柱子移到另一根柱子上,并且在移动过程中,不得将较大的盘子放在较小的盘子上面。 #### 汉诺塔问题规则 汉诺塔问题通常包括三个柱子(通常标记为A、B、C)和n个不同大小的圆盘。...

    12 关于 React Fiber不得不说的事慕课专栏1

    React v15 时代的渲染机制,即Stack Reconciler,采用自顶向下的递归方式处理组件树,一次性计算整个Virtual DOM树的变更,这可能导致JavaScript引擎长时间占用主线程,从而阻碍浏览器的其他工作,如页面渲染,进而...

    pytorch_RVAE:递归变异自动编码器,可生成使用pytorch实现的顺序数据

    男人相信他们不得不走在,因为他们的是昂贵重要 两家公司坚持认为,可以在程序中包含颜色设置 用法 在模型训练之前,有必要训练单词嵌入: $ python train_word_embeddings.py 该脚本训练了定义的单词嵌入 参数: ...

    很好的面试逻辑题,不得不看的东西

    5. **迭代与递归**:称球问题的解决方法是一种递归思路,每次称量后根据结果缩小问题规模,直到找到答案。在编程中,递归算法是解决复杂问题的常见手段。 6. **决策制定**:在每个问题中,都需要做出一系列决策,...

    rdp-generator:递归下降解析器生成器

    在看到许多编程语言类的人编写他们的Wren递归下降分析器,并且不得不为我的编译器类编写此程序之后,我认为我会发布源代码,以便也许有人可以从其生成的代码中受益。 我可能会在生成的代码中添加水印,以便Fenwick...

    编程中不得不看的牛逼代码

    对于资深开发者来说,理解和解析这样的代码是提升技能的重要环节;对于初学者,尽管可能会感到头疼,但也是学习和成长的过程。 "混淆代码"这个概念通常指的是那些难以理解或阅读的代码,可能是因为过度压缩、加密、...

    不得不看211重点大学的数据结构课件

    对于211重点大学的学生来说,掌握数据结构的知识至关重要,因为它是计算机科学与技术、软件工程等专业基础的重要组成部分。本课件集合了多个章节的内容,旨在全面而深入地讲解数据结构的基础理论和实际应用。 一、...

    经典海盗分金C++源码

    经济学上有个“海盗分金”模型,是说5个海盗抢得100枚金币,他们按抽签的顺序依次提方案:首先由1号提出分配方案,然后5人表决,超过半数同意方案才被...每人多得1金,其余不得, 这样依次类推写成程序里的递归算法。

    不得不看的10道Python经典的编程面试题

    阶乘可以用递归或循环来实现。`factorial_sum(a, b)`函数中定义了`fact(n)`函数来计算阶乘,然后将结果相加。 5. 找到字符串中最长的单词 `find_longest_word(s)`函数通过`split()`方法将字符串分割成单词列表,...

    TFSUndo-for-TFSAdmins:TFS UNDO 其他结帐 - 对所有用户递归

    因此,在大型组织中,如果您有 100-200 名开发人员在一个分支中工作,这意味着如果 100 名开发人员分别从分支签出 1 个文件,那么我将不得不按 100 次撤消按钮以使分支签出免费。 我进行了广泛的搜索,但找不到...

    C语言学习重难点分析编程经验分享等17个资料合集.zip

    C语言与C++不得不说的那点事.pdf C语言与Java的区别.pdf C语言函数的递归和调用实例分析.pdf C语言单链表功能完全详解.pdf C语言大作业(仅供参考).docx C语言嵌入式系统编程修炼之内存操作.pdf C语言经典算法大全....

    学习Linux---不得不知的Linux命令

    ### 学习Linux---不得不知的Linux命令 在Linux操作系统中,掌握一系列基本且重要的命令是每个用户必备的技能之一。这些命令可以帮助我们更高效地管理服务器、进行日常操作及故障排查等工作。以下是对给定内容中列出...

    An Introduction to the Analysis of Algorithms, 2nd Edition

    《算法分析导论》第二版是罗伯特·塞杰维克(Robert Sedgewick)与菲利普·弗拉乔莱特(Philippe Flajolet)联合著作的一本关于算法分析领域的权威书籍。这本书详细介绍了算法分析的基本理论和方法,帮助读者掌握...

Global site tag (gtag.js) - Google Analytics