递归的定义
递归,就是在运行的过程中调用自己
递归结构包括两个部分:
- 递归头:什么时候不调用自身方法,如果没有头,将进入死循环
- 递归体:什么时候需要调用本身方法。
简单来说,A方法调用B方法,这样我们很容易就能理解。
但是递归它是A方法调用A方法!就是自己调用自己
利用递归可以用简单的程序来解决一些复杂的问题。
它通常把一个大型复杂的问题层层转化为一个与原问题相似的规模较小的问题来求解,递归策略只需要少量的程序就可以描述出解题过程所需要的多次重复计算,大大地减 少了代码量。
递归的能力在于用有限的语句来定义对象的无限集合。
递归的使用
说了这么多官方的话,我还是得用代码来证明才能理解。
public class Demo05 {
public static void main(String[] args) {
method();
}
public static int method(){
int num1 = 0;
method();
return num1;
}
}
这样就是最简单的递归,就像上面我说的,自己调用自己,但是这样肯定会报错,运行之后,结果会出现栈溢出异常
这样当然不行,下面我写一个和数学有关的程序。
练习:求一个数的阶乘
阶乘:其实我也不是很懂,但是有个速成的理解
例:
- 1的阶乘 1*1 = 1
- 2的阶乘 2*1 = 2
- 3的阶乘 3 * 2 * 1 = 6
- 4的阶乘 4 * 3 * 2 * 1 = 24
- 5的阶乘 5 * 4 * 3 * 2 * 1 = 120
大概就是这样推算的
那么用程序怎么表达呢?先思考一下,我先把代码放在下面
package com.simple.method;
/**
* @author huYuHao
* @version 1.0
* @create 2021/3/13
* @since 1.8
*/
public class Demo06 {
public static void main(String[] args) {
System.out.println(f(5));
}
//5! 5*4*3*2*1
public static int f(int n){
if(n ==1){
return 1;
}else{
return n * f(n-1); //5*(4*(3*(2*1)))
}
}
}
解析1
首先定义方法,一个静态的方法或者你不写new这个类的对象也行
n 是用来传参的,就不必多说了
解析2
main方法调用f方法就需要传入实参n,进入方法后判断,如果你是1,那么直接返回1,因为1的阶乘就是自己乘以自己。
解析3
如果不是1,就会进入else
这里我假设main方法调用的时候传入了一个5
那么第一次进入,if不满足要求,进入else
else返回5 * f( n -1)
可能有点懵,不急,慢慢来看,首先5f,这证明什么?方法进行了递归,自己调用自己,然后就是5 * f( 5 - 1 )那是不是等于54?
然后f(n-1)是不是等于我又调用了f并且传入了参数4,是不是就有递归那味了~
然后4不等于1,进入else 4 * f(4-1),又调用了f传入了3
然后3不等于1,进入else 3 * f(3-1),又调用了f传入了2
然后2不等于1,进入else 2 * f(2-1),又调用了f传入了1
这时候,n==1返回1
在学习之初我也很奇怪,明明这个方法最后返回的是1,怎么得出的5的阶乘是120呢?然后老师告诉我有一个返回阶段
简单来说就是:第一次传入5,else里面的代码是:
5 *( 4 * ( 3 * (2 * 1)))
就是说,第一次5*f也就是在等4这个结果出来,4又在等3出来,3等2出来,2等1出来之后,就开始了一个叫返回阶段的东西
它运行的过程是这样的:
本文章结束