递归解决斐波那契数列

简介: 1、什么是递归?   递归:递归是方法定义调用方法本身的现象。递归举例如下: <span style="font-size:14px;">public class DiGuiDemo { //递归方法举例 public void show() { show(); }}</span>2、递归的注意事项? (1)递归一定要有出口

1、什么是递归?

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

<span style="font-size:14px;">public class DiGuiDemo {

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

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

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

<span style="font-size:14px;">            public void show(int n)
 			{
 				if(n==0)
 				{
 					System.exit(0);          
 				}
 				else{
 					System.out.println("hell");
 					show(n-1);
 				}
 			}</span>
  这个例子就是给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!。。。如图:



  代码体现:

<span style="font-size:14px;"> 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; <span style="font-family: Arial, Helvetica, sans-serif;">// 出口 ,如果是1,就返回1</span>

		} else {
			
			return n * jc(n - 1);  <span style="font-family: Arial, Helvetica, sans-serif;">// 规律,如果不等于1,就递归</span>

		}
	}
}</span>
  对于阶乘方法来说,求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。。。

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

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

  代码实现:

<span style="font-size:14px;">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); //从第三个月开始是前两个月对数之和
		 }
	}
}</span>

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


目录
相关文章
|
6月前
|
算法 C++
C++快速幂(递归)
C++快速幂(递归)
|
1月前
递归阶乘详解
递归阶乘详解
12 1
|
4月前
|
C语言
递归求阶乘
【1月更文挑战第18天】C语言实例——递归求阶乘。
23 1
|
10月前
递归和非递归分别实现求第n个斐波那契数
递归和非递归分别实现求第n个斐波那契数
43 0
|
10月前
|
机器学习/深度学习
青蛙跳台阶(递归)
青蛙跳台阶(递归)
65 0
|
11月前
|
机器学习/深度学习 存储 设计模式
从斐波那契数列到递归
大家好,我是王有志。今天我们要通过经典数学问【题斐波那契数列】来学习非常重要的编程技巧:递归。
89 1
从斐波那契数列到递归
|
机器学习/深度学习 算法 C语言
函数递归+青蛙跳台阶——“C”
函数递归+青蛙跳台阶——“C”
你是真的“C”——函数递归详解青蛙跳台阶
手把手教学——函数递归详解汉诺塔+青蛙跳台阶问题
81 0
你是真的“C”——函数递归详解青蛙跳台阶
|
算法
【递归与递推 3】AcWing 717. 简单斐波那契(求解斐波那契数列的若干方法)
【递归与递推 3】AcWing 717. 简单斐波那契(求解斐波那契数列的若干方法)
【递归与递推 3】AcWing 717. 简单斐波那契(求解斐波那契数列的若干方法)
【递归】青蛙跳台阶的变式题你还会吗?
【递归】青蛙跳台阶的变式题你还会吗?
88 0
【递归】青蛙跳台阶的变式题你还会吗?