Java方法的递归调用
方法的递归调用就是方法自身调用自身。
先看下面的例子:
public class Test {
/**
* 使用 for 循环实现1~n的和
*
* @param n 参数
* @return int
*/
private static int loopSum(int n) {
int sum = 0;
for (int i = 1; i <= n; i++) {
sum += i;
}
return sum;
}
/**
* 使用递归实现1~n的和
*
* @param n 参数
* @return int
*/
private static int recursionSum(int n) {
if (n == 1) {
return 1;
} else {
return n + recursionSum(n - 1);
}
}
/**
* 使用 for 循环实现1~n的乘积
*
* @param n 参数
* @return int
*/
private static int loopMultiplyValue(int n) {
int sum = 1;
for (int i = 1; i <= n; i++) {
sum *= i;
}
return sum;
}
/**
* 使用递归实现1~n的乘积
*
* @param n 参数
* @return int
*/
private static int recursionMultiplyValue(int n) {
if (n == 1) {
return 1;
} else {
return n * recursionMultiplyValue(n - 1);
}
}
public static void main(String[] args) {
int result1 = loopSum(100);
int result2 = recursionSum(100);
System.out.println("result1= " + result1);
System.out.println("result2= " + result2);
int result3 = loopMultiplyValue(6);
int result4 = recursionMultiplyValue(6);
System.out.println("result3= " + result3);
System.out.println("result4= " + result4);
}
}
运行结果:
递归应用中有个经典的例子就是实现斐波那契数列:
public class FibonacciDemo {
/**
* 计算斐波那契数列 一对兔子,第一个月不生,第二个月不生,从第三个月开始生下一对兔子
* 生下的那一对兔子,第一个月不生第二个月不生,从第三个月开始生下一对兔子
* 问:12个月后 一共有多少对兔子?
* 示例:1 1 2 3 5 8 13 21 34 55 89 144
* 分析可知:从第三个月开始 month = (month - 1) + (month - 2)
*
* @param month 参数
* @return int
*/
private static int getFibonacci(int month) {
if (month == 1) {
return 1;
}
if (month == 2) {
return 1;
}
return getFibonacci(month - 1) + getFibonacci(month - 2);
}
public static void main(String[] args) {
System.out.println(getFibonacci(12));
}
}
运行结果:
方法的递归调用适用于方法中运算的主体不变,但运行的方法参数会发生变化的场景。
注意:
- 递归一定要有出口,必须可以让程序可以停下;
- 递归次数不能过多;
- 构造方法,禁止递归。
以下程序因为递归没有结束的条件,所以一直压栈,没有弹栈,导致栈内存溢出错误!所以递归必须要有结束条件。
public class RecursionTest{
public static void main(String[] args) {
method();
}
private static void method() {
//java.lang.StackOverflowError
method();
}
}
运行结果: