关于递归的一些分析
来源:互联网 发布:网络同步的网络云盘 编辑:程序博客网 时间:2024/05/02 03:11
在CSDN论坛中,有一个贴子:
http://topic.csdn.net/u/20071221/07/1fc10b9d-e2a1-435a-95b8-75d77484cda3.html?seed=1208660145
内容如下:
一个递归的面试题有答案,可看不懂,请高手解析下原理
问题:把一个数组里的数组合全部列出,比如12列出来为1,2,12,21
答案:
*/
import java.util.*;
import java.io.*;
public class Dg1 ...{
public static void listAll(List candidate,String prefix) ...{
System.out.println(prefix);
for(int i = 0;i < candidate.size();i++)
...{
List temp = new LinkedList(candidate);
listAll(temp,prefix + temp.remove(i));
}
}
public static void main(String[] args) ...{
String[] array = new String[] ...{
"1","2"
};
listAll(Arrays.asList(array),"");
}
}
看一这个贴子,也让我想起多年前,关于递归调用的一些学习心得,我怕自己会忘记,所以把它记录一下:
大家都搞清楚了,不过我还是想把我的分析列一下,看看与你们的分析是否一样?
关于递归函数调用的问题,我想我们要先搞清楚“调用栈”问题,什么是“调用栈”呢?
我的理解是,递归之前,系统会保存当前CPU栈上的所有内容,如何保存呢?当然是入栈了,在这理我想我们对于数据结构中的“栈”应该都不陌生的。调用完成之后呢,就是出栈了,其实总结一下就是一句话:调用之前入栈,调用完成后出栈。
好的,有了理论后,我们来分析一下具体执行程序时,系统是如何做的?
在这理,为了理解方便,我们将当前栈上的数据都列一下:
1.main中的listAll()被调用,
此时,栈上的内容是:array(1,2),prefix=""
listAll方法中,println(prefix)执行,输出=>""
此时,栈顶的内容是:
prefix="";
candidate="1,2"
for()开始执行=>i=0;candidate.size() = 2
执行new LinkedList后,temp的值如下:
temp = 1->2;
调用listAll()=>
temp=> 2;
temp_prefix => prefix + "1";--为什么会多出个temp_prefix呢,因为,我们使用了prefix+temp.remove(i)时,
编译器会自动为我们生成一个临时的String对象来存储prefix+temp.remove(i)的值
好的,递归前,系统会将这些变量入栈:
①:
i=>0;
temp=>2
prefix=>""
candidate=>"1,2"
递归调用listAll(temp,prefix),此时:
candidate=>"2"
prefix=>"1",println(prefix)输出1
进入for()
i=0;
candidate.size() = 1;
i < candidate.size() == true,条件成立,执行:
temp = new LinkedList(candidate) =>temp="2"
listAll()调用,调用的参数内容如下:
temp=>""
temp_prefix= prefix + temp.remove(0) ==> "1" + "2"
系统同样将当前栈上的内容入栈,以下是当前栈上的内容
②:
i=0
candidate=>2
prefix="1"
temp=>""
递归进来后,此时栈的内容如下:
candidate=""
prefix="12";
print(prefix)后,输出"12"
好的,开始执行for()
i=0;candidate.size() = 0;条件不成立,没有进入for内,此函数已经没有要执行的下一条语句,结束调用,
开始出栈,到此,我们的栈内只有两项栈记录,出栈时,首先弹出②,此时我们看一下
栈②内容:
i=0
candidate=>2
prefix="1"
temp=>""
现在系统执行for()->
i++ => i=1; candidate.size()=1
条件:i < candidate.size() == false,不执行
结束调用,出栈,此时弹出①栈,好的,我们看一下,栈①的内容:
①:
i=>0;
temp=>2
prefix=>""
candidate=>"1,2"
执行for()
i++ => i=1;
candidate.size() = 2;
条件:i < candidate.size() == true,执行
temp = new LinkedList(candidate) => temp = 1->2;
调用:listAll(temp,prefix + temp.remove(i)) =>此时,参数值如下:
i = 1;
temp=> 1;
temp_prefix = "" + "2";
保存栈内容:
③:
candidate="1,2";
i = 1;
temp => 1;
prefix="";
递归listAll("1","2"),
执行print(prefix),输出 2
我们看一下当前栈上的内容:
i=0;
candidate="1";
prefix="2"
执行for()
i=0; candidate.size() = 1;
条件i < candidate.size() == true,执行
temp = new LinkedList(candidate);
temp=>"1";
调用listAll(temp,prefix);
temp=> "";
temp_prefix = "2" + temp.remove(0) ==> temp_prefix="21"
此时,保存当前栈内容:
④:
candidate="1";
temp="";
i=0;
prefix="2";
调用listAll("","21");
println(prefix)输出"21"
i=0;
candidate="";
i < candidate.size() == false,条件不成立,返回,出栈,首先弹出的是栈④,我们看一下栈④的内容:
④:
candidate="1";
temp="";
i=0;
prefix="2";
此时,开始执行for()
i++ => i=1; candidate.size() == 1;
i < candidate.szie() == false,条件不成立,返回,出栈,此时弹出的是栈③,我们看一下栈③的内容:
③:
candidate="1,2";
i = 1;
temp => 1;
prefix="";
执行for();
i++ => i= 2;
candidate.size() = 2;
i < cnadidate.size() == false,条件不成立,返回,出栈,此时弹出的是main函数在调用listAll()之前 的栈,
如此,整个递归执行完毕,输出的内容:
""
1
12
2
21
- 关于递归的一些分析
- 关于递归的一些感悟
- 关于递归的一些思考
- 关于递归的一些题型
- 关于递归的简单分析
- 关于递归的简单分析
- java中关于递归的一些总结
- 关于递归问题的一些小例子
- 关于递归的一些简单想法
- 浅谈关于递归的一些感悟
- 关于递归的一些简单应用
- 关于Fragment的一些分析
- 关于递归超时问题的实例分析
- 关于PHP中数组递归遍历的一些见解
- 关于DB2递归查询的一些学习分享
- 白书 - 拓扑排序 及 关于递归、coding的一些思考
- 关于递归调用,函数指针,数组,字符串的一些理解
- 数据结构关于树的一些递归函数代码
- IP Helper API 简介 (zz)
- J2ME——XmlReader学习总结
- 新添堡回族乡人民政府网站正式开通
- 指针、数组、二级指针、指针数组与字符串
- showModalDialog/showModelessDialog实例,父窗口向子窗口传递值,子窗口设置父窗口的值,子窗口关闭的时候返回值到父窗口.关闭刷新父窗口
- 关于递归的一些分析
- 地址传送指令LEA,LDS,LES;
- J2me xmlReader的轻量级实现
- 2007最牛的50个站
- 四六级是这样的
- Struts中Tilts标记的使用
- D2D网络数据存储器开发全过程(2)
- SQL Server 2008和T-SQL新功能
- 汇编乐曲编程