首先要了解递归是什么,举个大家都熟知的例子:从前有座山,山上有座庙,庙里有个老和尚和小和尚,老和尚正在给小和尚讲故事。从前有座山......这里就存在方法定义中调用方法本身的现象。一般用于解决存在相似规律的计算或操作,比如
兔子问题
(
斐波那契数列
) 有一对兔子,从出生第3个月起每月都生一对兔子,小兔子长到第3个月后又生一对兔子。假设所有的兔子都存活下来,问第二十个月的兔子对数为多少?
递归注意事项 (1):
要有出口,否则就是死递归;
(2):
次数不能太多,否则就内存溢出;
(3):
构造方法不能递归使用。
使用递归方法的基本条件就是找到算法实现的规律,找出递归的出口很关键。现在先从最简单的阶乘计算分析:
求6的阶乘
6! = 1*2*3*4*5*6
6! = 6*5!
5! = 5*4!
4! = 4*3!
3! = 3*2!
2! = 2*1! (1!=1)
4! = 4*3!
3! = 3*2!
2! = 2*1! (1!=1)
在这里第一种方法可以用for循环来实现阶乘的计算。当然也可以用递归的方法实现,知道了5!当然就知道了6!,知道了4!就知道了5!.......直到1!=1 就跳出了调用,开始返回2!3!.....6!。下面这个图就是递归求阶乘的内存图解。左边是java的代码,中间是栈空间(刚好实现了先进后出的调用和输出),右边是对空间和内存空间(放置方法体)。
下面给出兔子问题的具体实现代码:
</pre><pre name="code" class="javascript">package cn.itcast_01;
/*
* 有一对兔子,从出生第3个月起每月都生一对兔子,小兔子长到第3个月后又生一对兔子。。。。
* 问第二十个月的兔子对数为多少?
* 兔子对数
* 第一个月: 1
* 第二个月: 1
* 第三个月: 2
* 第四个月: 3
* 第五个月: 5
* 第六个月: 8
* 。。。
* 规则:
* A:从第三项开始,第一项是两项之和
* B:而且说明前两项是已知的
*/
public class DiGuiDemo2 {
public static void main(String[] args) {
//定义数组
int[] arr = new int [20];
arr[0]=1;
arr[1]=1;
//数组实现
for(int x= 2;x<arr.length;x++){
arr[x]= arr[x-2]+arr[x-1];
}
System.out.println(arr[19]);//6765
System.out.println("----------");
System.out.println(fib(20));
}
/*
* 方法:
* 返回值类型:int
* 参数列表: int n
* 出口条件:
* 第一个月是1 ,第二个月是1
* 规律:
* 从第三项开始,第一项是两项之和
*/
public static int fib(int n){
if(n==1||n==2){
return 1;
}else{
return fib(n-2)+fib(n-1);
}
}
}
这个代码分别给出了循环方法和递归方法的解决方案。希望对刚接触递归的朋友有所帮助哈~