博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
递归解决斐波那契数列
阅读量:6831 次
发布时间:2019-06-26

本文共 2169 字,大约阅读时间需要 7 分钟。

1、什么是递归?

  递归:递归是方法定义调用方法本身的现象。递归举例如下:

public class DiGuiDemo {	//递归方法举例	 public void show()	 {	     show();	 }}
2、递归的注意事项?

(1)递归一定要有出口。否则就会死递归。

  上面举例用的递归就是一个死递归,方法永远都在进行自身调用,最终一定会陷入内存崩溃。所以递归要定义出口,就是结束递归的条件。举例如下:

            public void show(int n) 			{ 				if(n==0) 				{ 					System.exit(0);           				} 				else{ 					System.out.println("hell"); 					show(n-1); 				} 			}
  这个例子就是给show方法传递一个参数,每次递归参数减1,当参数为0时,退出。

(2)递归的次数不要过多,否则调用方法太多会导致内存空间溢出。

(3)构造方法不能使用递归的方式调用。

3、生活中存在的递归与递归思想?

  编程思想来源于生活,生活中有很多的递归小例子,例如小时候经常听的故事:

  从前有座山,山上有座庙,庙里有个老和尚,老和尚给小和尚讲故事:从前有座山,山上有座庙,庙里有个老和尚,老和尚给小和尚讲故事:从前有座山,山上有座庙,庙里有个老和尚,老和尚给小和尚讲故事。。。。。

  这就是递归了,可惜这个故事没有递归出口。。。

  递归的思想:编程取材于生活然后解决特定问题,在编程中递归是将大问题分解成若干的小问题,然后再将小问题分解成更小的问题,直到分解的问题是已知的结论。

4、练手:用递归求5!

  分析:(1)规律 :n!=n(n-1)!   (2)出口:当递归到1!时是已知的,1!=1。

  思路:将5!分解为5*4!;再将5*4!分解为5*4*3!。。。如图:

  代码体现:

 public class DiGuiDemo {	public static void main(String[] args) {		int num = 5;		System.out.println(jc(num));	}        //定义求阶乘方法	public static int jc(int n) {		if (n == 1) {			return 1; // 出口 ,如果是1,就返回1		} else {						return n * jc(n - 1);  // 规律,如果不等于1,就递归		}	}}
  对于阶乘方法来说,求n的阶乘,就返回n*(n-1)!,体现在递归上就是n*jc(n-1),当递归到1时,返回1。这个过程在内存中解析应该是:

  DiGuiDemo类被加载到方法区中,当执行此类时,首先将main方法调用到栈中执行,main方法中还有jc(num)方法,于是接下来调用jc(num)方法,因为jc方法递归直到1,所以调用顺序为:main--jc(5)--jc(4)--jc(3)--jc(2)--jc(1)。因为栈这种数据结构的特点是先进后出,所以方法的执行顺序是jc(1)--jc(2)--jc(3)--jc(4)--jc(5)然后返回给main方法。内存图如下:

  jc(1)是已知的值为1,所以将1 return 给jc(2),因为栈中调用特点为调用结束后被调用者就在栈中消失,所以这些方法会按jc(1)--jc(2)--jc(3)--jc(4)--jc(5)--main顺序依次return 回值并在栈中依次消失。

5、递归解决斐波那契数列。

  需求:有一对兔子,从出生后第3个月起每个月都生一对兔子,小兔子长到第三个月后每个月又生一对兔子,假如兔子都不死, 问第二十个月的兔子对数为多少? 

  分析:因为每对兔子从第三个月开始每个月生一对小兔子,那么第一个月有1对;第二个月1对;第三个月2对;第四个月3对;第五个月5对。。。

  得到这样的一个数列:1,1,2,3,5,8,13,21。。。

  规律:从第三项开始,每一项是前两项之和。

  出口:出口一般都定义为已知的值,因为规律是从第三个月开始的,所以这里第一项和第二项是已知的。

  代码实现:

public class DiGuiDemo {	public static void main(String[] args) {		System.out.println(fun(20));	}        //定义递归方法	public static int fun(int n) {		 if (n == 1) {		 return 1; //第一个月1对,返回1		 } else if (n == 2) {		 return 1; //第二个月1对,返回1		 } else {		 return fun(n - 1) + fun(n - 2); //从第三个月开始是前两个月对数之和		 }	}}

  小结:递归是方法调用方法本身的情况,利用递归可以解决一些能够将问题分解成小问题的情况。但是注意递归一定要有出口,并且递归次数不宜过多。

你可能感兴趣的文章
Windows Server 2012 R2 新功能体验——工作文件夹(Work Folders)
查看>>
ubuntu11.10的root密码
查看>>
django python 文件上传【Part 5】
查看>>
【模板】最小费用最大流
查看>>
五周第一次课(1月8日)
查看>>
解决vsftpd编译时的错误:could not read symbols: File in wrong format
查看>>
NHibernate学习总结
查看>>
html转译java语言
查看>>
oracle中时间转换的问题
查看>>
如何设计Android App测试用例
查看>>
sysbench
查看>>
详解MySQL读写分离
查看>>
dns服务器在做nslookup测试的时候,出现dns timeout 2 seconds的错误解释
查看>>
使用监控宝监控snmp性能经验实录
查看>>
開發Android, 從Eclipse官網下載Eclipse開始,從無到有安裝一遍
查看>>
逻辑判断
查看>>
mockcpp的so加载失败问题
查看>>
RHEL5下 JDK-7u4(rpm)+Tomcat-7.0+JavaCenterHome
查看>>
laravel 分页
查看>>
如何给在用的nginx添加新模块
查看>>