定义:程序函数直接或间接调用自身
二、递归的注意事项
-----递归不是无限循环,递归的次数必须是有限的!-----
---如果没有终止条件,会发生栈溢出(*Error)---
-
每次执行一个方法会在JVM-栈中开辟一个内存空间,用于存放方法所需的数据,
-
比如方法的局部变量、对象引用
注意事项
-
(1)递归必须有出口(终止条件)
-
(2)每次递归,范围逐渐缩小
例子:计算累加和
public class RecursionDemo1 {
/**
* 计算累加和
* @param start,开始累加的值
* @param end,结束累加的值
* @return int 返回累加的结果
*/
public static int addRecursion(int start,int end){
//递归出口
if (start == end){
return end;
}
?
//递归调用,每次递归,范围缩小
return start + addRecursion(start+1,end);
}
?
-
-
方法执行完,出栈!
-
-
用递归还是循环
-
优势:简洁明了(用循环实现的用递归一定可以实现)
-
劣势:循环速度快(但有些场景循环实现不了,必须使用递归)
-
总结:优先使用循环,循环搞不定使用递归
-
三、递归的练习
1、实现斐波那契数列(求当前值和和)
(1)循环实现
//输出指定的值,以及所有值的总和
public static int feboUsewhile(int num) {
//分析,当前的数的和,等于前2个数的和(NUM =1\2直接给定)
int key = 0;
int a = 1;
int b = 1;
int sum = 0;
?
for (int i = 1; i <= num; i++) {
if (i == 1 || i == 2) {
key = 1;
}else{
key = a + b; //计算当前的数的和
a = b; // 设置新的需要被加数
b = key;
}
sum += key;
System.out.print(" " + key);//输入当前数的值
}
return sum;//返回总和
// }
}
(2)递归调用
//返回指定的值(递归)
private int feboUseRecursion(int num){
//1、终止条件,num = 1或2时,返回值为1;
if (num == 1){
return 1;
}else if(num == 2){
return 1;
} else{
//return value(num - 1) + value(num-2);前num-1个数的和+当前的值=前num-1个数的和 +(sum())
int i = feboUseRecursion(num -1) + feboUseRecursion(num -2);
return i;
}
?
}
?
//求和,循环
public int sum(int num){
int sum = 0;
int value;
for (int i = 1; i <= num; i++) {
value = feboUseRecursion(i);
sum += value;
System.out.println(value);
}
return sum;
}
?
//另外附:
//直接打印数量无返回值,num最小从1开始,one:0,two:1,index:1
private void feboUseRecursion2(int num,int one,int two,int index){
if (num == 1){
System.out.println(1);
return;
}
//1、终止条件,num == index;
if (index <= num){
int sum = one + two ;
System.out.println(sum);
feboUseRecursion2(num,two,sum,index+1);
//return value(num - 1) + value(num-2);前num-1个数的和+当前的值=前num-1个数的和 +(sum())
}
?
}
public void hannuotaRecursion(int num, char start, char mid, char end){
if (num == 1){
move(1,start,end);
}else{
hannuotaRecursion(num-1,start,end,mid);//将N-1个盘子从开始移到中间
move(num,start,end);
hannuotaRecursion(num-1,mid,start,end);//将N-1个盘子从中间移到最后
}
}