目录
4.1按顺序打印一个数字的每一位(例如1234打印出1 2 3 4)
4.3写一个递归方法,输入一个非负整数,返回组成它的数字之和. 例如,输入 1729, 则应该返回1+7+2+9,它的和是19
4.4求斐波那契数列的第N项(注意:这个递归方法如果求较大的项目时,会有大量的重复计算,如果使用循环,效率会高很多)
1.递归的概念
当一个方法在执行过程中调用它本身,就称之为“递归”。
递归需要一个结束条件,然后也要有一个递归公式。
例如,我们求N!
结束条件:N=1的时候,N!为1,这个条件是递归的结束条件
递归公式:求N!,直接不好求,可以把问题转化成N!=>N*(N-1)!
代码示例:递归求N的阶乘
public class Test {
public static void main(String[] args) {
int n = factor(5); //调用递归函数并将n=5的值传进去 再把返回值存储到变量a中
System.out.println("n=" + n);
}
public static int factor(int a){ //递归方法
if(a==1){
return 1;
}else
return a*factor(a-1);
}
}
2.递归执行过程分析
递归的执行过程不太好理解,想要理解清楚递归,必须先理解“方法的执行过程”,尤其是“方法执行结束之后,回到调用位置继续往下执行。
我们把刚刚讲的N的阶乘这个递归方法来加上日志
public static void main(String[] args) {
int n = 5;
int ret = factor(n);
System.out.println("ret = " + ret);
}
public static int factor(int n) {
System.out.println("函数开始, n = " + n);
if (n == 1) {
System.out.println("函数结束, n = 1 ret = 1");
return 1;
}
int ret = n * factor(n - 1);
System.out.println("函数结束, n = " + n + " ret = " + ret);
return ret;
}
// 执行结果
函数开始, n = 5
函数开始, n = 4
函数开始, n = 3
函数开始, n = 2
函数开始, n = 1
函数结束, n = 1 ret = 1
函数结束, n = 2 ret = 2
函数结束, n = 3 ret = 6
函数结束, n = 4 ret = 24
函数结束, n = 5 ret = 120
ret = 120
可见,递归方法顾名思义,既要有递的过程,也要有归的过程。当往下递的时候,会逐步到方法的结束条件,然后在往回递。
3.关于"调用栈"
方法调用的时候,会有一个“栈”,这样的内存空间描述当前的调用关系,称为调用栈,每一次方法的调用就称为一个“栈帧”,每个栈帧包含了这次调用的参数是哪些,返回到哪些继续执行等信息。
4.代码示例
4.1按顺序打印一个数字的每一位(例如1234打印出1 2 3 4)
public static void printf(int num){
if(num>9) {
printf(num / 10);
}
System.out.println(num%10);
}
4.2递归求1+2+3+...+10
public static int sum(int num) {
if (num == 1) {
return 1;
}
return num + sum(num - 1);
}
4.3写一个递归方法,输入一个非负整数,返回组成它的数字之和. 例如,输入 1729, 则应该返回1+7+2+9,它的和是19
public static int sum(int num) {
if (num < 10) {
return num;
}
return num % 10 + sum(num / 10);
}
4.4求斐波那契数列的第N项(注意:这个递归方法如果求较大的项目时,会有大量的重复计算,如果使用循环,效率会高很多)
public static int fib(int n) {
if (n == 1 || n == 2) {
return 1;
}
return fib(n - 1) + fib(n - 2);
}
5.小结
递归是一种重要的编程解决问题方式,有一些问题天然就是用递归方式来定义的(例如,斐波那契数列,二叉树等),此时使用递归来解就很容易。
如果有一些问题用递归和非递归(循环)都可以解决,那么更推荐使用循环,相比于递归,非递归程序运行会更加高效。因为递归会不断的调用方法,在栈上开启新的空间,可能还会有大量重复计算。