试列代码:
public class Recursive {
public static void main(String[] args) {
Rec t1 = new Rec();
t1.test(4);
}
}
class Rec{
public void test(int n) {
if(n>2) {
test(n-1);
}
System.out.println("n="+n);
}
}
结果:
n=2
n=3
n=4
分析流程:
递归:先传递,然后在返回过来。
这里会有小伙伴疑惑为什么会输出三个结果,而不是输出一个结果。因为在返回的时候都会执行一句out语句
详细如下:
- 首先执行main里面的代码:Rec t1 = new Rec()如图在堆内存创建对象空间。
- 执行到test方法,t1.test(4),并且如图创建一个test栈空间(所有方法执行时都会单独创建一个栈空间),满足If条件继续执行test(4-1),并且又创建栈空间。当执行到n=2时,不满足if条件,开始执行System.out.println("n="+n);,并返回到n = 3的栈空间,因为n=2栈空间是n=3所调用的。
- 当返回到n=3的栈空间时,会继续执行System.out.println("n="+n),那么为什么会执行这段输出呢?
- 因为每一个栈在返回的时候都会完整的执行完所有代码。
- n=4返回main方法,并且main方法中无代码,所以执行完毕。
- 每个栈在返回的时候相当于已经销毁,上图是为了更详细,所以未删除。
- 栈是先进后出。
在来一个例子吧:
public static void main(String[] args) {
Rec t1 = new Rec();
int res = t1.factorial(5);
System.out.println(res);
}
}
class Rec{
public int factorial(int n) {
if(n==1) {
return 1;
}else{
return factorial(n-1)*n;
}
}
结果:120
如下图解释:
首先执行main区,然后生成
- n=5 的时候的栈空间
- 然后依次执行生成,因为递归调用一次方法就会生成空间。
- 然后执行到n=1时执行return 语句,并且返回给f(2-1),因为是它所引用的该方法。
- 然后同理,最后返回到main函数的fac(5)中,得到值120。
- 方法执行以后会返回。
递归重要规则:
- 执行一个方法时,就创建一个新的独立的栈空间。
- 方法的局部变量是独立的,不会相互影响。
- 如果方法中使用的是引用数据类型(如数组,对象,字符串)就会共享该数据。
- 递归必须向退出递归条件无限逼近,否则就是无限递归出现。
- 当一个方法执行完毕,或者遇到return就会返回,遵守谁调用返回谁,同时当方法执行完毕或者返回时,该方法也就执行完毕,就会销毁该栈空间。