java入门——浅谈递归
一、 递归的定义
通俗的讲,递归就是一个方法在执行的过程中,再次调用自身的过程。
递过程:不断调用函数自身,直到走到尽头。
归过程:函数不断返回的过程。
二、 递归的使用场景
有三个条件:
- 大问题可以拆成若干个子问题的解
- 拆封后的子问题与原问题除了数据规模的不同,解决思路一样
- 存在递归的终止条件
三、递归的核心
我们可以根据语义,即该方法的作用。如何运用这个作用达到我们想要的结果才是最终目的。我们可以假设这个方法已写好,然后调用该方法来辅助解决问题。
四、递归的示例
1. 传入一个任意的正整数,按顺序打印每一位数字。例:1234 --> 1 2 3 4
public class Note {
public static void printNum(int num) {
if (num < 10) {
System.out.print(num);
} else {
printNum(num / 10);
System.out.print((num % 10) + " ");
}
}
public static void main(String[] args) {
printNum(1234);
}
}
结果:1 2 3 4
解析:本题的终止条件,即不借助任何函数就能知道结果。当数字为一位数的时候,能直接出结果。
本题方法的作用:打印数字的每一位。
我们把终止条件当作自己的使用工具,即我们能知道数字的个位数是多少。当数字大于两位数的时候,由于我们只知道个位数是多少,那剩下的位数就交由该方法来实现。打印数字的高位就交给函数。我们只负责输出数字的各位,即有了num % 10。
2.求数字n的阶乘
public class Note {
private static int fac(int n) {
if(n == 1) {
return 1;
}
return n * fac(n-1);
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int num = sc.nextInt();
int ret = fac(num);
System.out.println(ret);
}
}
结果:
输入:5
输出:120
解析:公式 n!= n*(n-1)!
首先,我们要找到终止条件。当数字是1的时候,其阶乘就是1,所以我们直接返回1就行。
我们现在知道了1的阶乘,写下来我们要利用这个函数来计算其他数字的阶乘。
根据数学公式,我们知道n的阶乘就是n乘(n-1)的阶乘。而这个方法的作用就是就是求数字阶乘。
所以我们调用这个函数求出(n-1)的阶乘再去乘n就可以得到想要的结果。
3. 斐波那契数列
public class Note {
public static int fib(int n) {
if(n == 1 || n == 2) {
return 1;
}
return fib(n-1) + fib(n-2);
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int num = sc.nextInt();
int ret = fib(num);
System.out.println(ret);
}
}
结果:
输入:6
输出:8
解析:公式:
f ( n ) = { 1 n = 1 或 n = 2 f ( n − 1 ) + f ( n − 2 ) n ≥ 2 f(n)=\begin{cases} 1 & n=1或n=2 \\ f(n-1) + f(n-2) & n \ge 2 \end{cases} f(n)={1f(n−1)+f(n−2)n=1或n=2n≥2
这道题的做法和上面阶乘的核心思路是一样的不过多解释。但是利用递归求斐波那契数列调用自身过多,会造成运行缓慢。例如,我们要求f(5),下面是示例图。
上述图片f(2),f(1),f(3)多次使用,造成运行缓慢,资源浪费,我们可以优化代码,如下。
public static int fib1(int n) {
int first = 1; //第一位
int second = 1; //第二位
int tmp = 0; //前两项相加的结果
for (int i = 3; i <= n; i++) {
tmp = first + second;
first = second;
second = tmp;
}
return tmp;
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int num = sc.nextInt();
int ret = fib1(num);
System.out.println(ret);
}
结果:
输入:6
输出:8
解析:主要解释循环里面的内容,我用图来做说明。
五、总结
递归是一个复杂的过程,我也是个新手,有任何错误欢迎指正,继续练习。