递归是什么
递归就是方法自己调用自己,每次调用时传入不同的变量。解决复杂问题,减少耦合代码
递归内存分析
现有以下代码
public class DiGui{
public static void main(String[] args) {
T t = new T();
t.rePrint(4);
}
}
class T{
public void rePrint(int n){
if (n>2) {
rePrint(n-1);
}
System.out.println("n="+n);
}
}
编译输出是
n=2
n=3
n=4
那么为什么不是4 3 2 呢 因为在递归中当调用方法时会重新先开辟一个栈空间,优先运行调用方法的结构体,以此循环,当不调用新的方法时,再依次进行方法下方的语句。从而导致输出语句是从后往前输出
内存示意图:
只有当上一个语句块中的语句执行完才会执行下方的语句 (调用方法 包括找个方法内的所有语句都要执行完,才会回到调用方法的下面继续执行)
递归实现阶乘
4的阶乘 = 1234 5的阶乘 = 1234*5
public class DiGui{
public static void main(String[] args) {
T t = new T();
int num = t.rePrint(5);
System.out.println(num);
}
}
class T{
public int rePrint(int n){
if (n == 1) {
return 1;
}else{
return rePrint(n-1)*n;
}
}
}
运行操作:
1.main方法栈实例化T
2.调用rePrint方法 并传入实参5
3.rePrint方法栈(1)带入实参5
if (n == 1) { //5不等于1 进入else
return 1;
}else{
return rePrint(n-1)n; // 再开辟栈空间rePrint(2)5-1=4 传入下一个栈空间的是4 这里n先不进行运算先将调用的方法执行完回头再计算
}
(3.2)rePrint(2):
if (n == 1) { //4不等于1 进入else
return 1;
}else{
return rePrint(n-1)n; //再开辟空间rePrint(3)4-1=3 传入下一个栈空间的是3 这里n先不进行运算先将调用的方法执行完回头再计算
(3.3)rePrint(3):
if (n == 1) { //3不等于1 进入else
return 1;
}else{
return rePrint(n-1)n; //再开辟空间rePrint(4)3-1=2 传入下一个栈空间的是2 这里n先不进行运算先将调用的方法执行完回头再计算
(3.4)rePrint(4):
if (n == 1) { //2不等于1 进入else
return 1;
}else{
return rePrint(n-1)n; //再开辟空间rePrint(5)2-1=1 传入下一个栈空间的是1 这里n先不进行运算先将调用的方法执行完回头再计算
(3.5)rePrint(5):
if (n == 1) { //1等于1 进入if语句
return 1; //返回值为1
}else{
return rePrint(n-1)*n;
(3.6) rePrint(5)的返回值为1 带入rePrint(4) *n rePrint(4)的n是2所以是1X2 = 2 所以 rePrint(4)的返回值是1X2
rePrint(4)的返回值为1x2 带入rePrint(3) *n rePrint(3)的n是3所以是1X2X3 所以 rePrint(3)的返回值为1X2X3
rePrint(3)的返回值为1x2x3带入rePrint(2) *n rePrint(2)的n是4所以是1X2X3X4 所以 rePrint(2)的返回值为1X2X3X4
rePrint(2)的返回值为1x2x3带入rePrint(1) *n rePrint(1)的n是5所以是1X2X3X4X5 所以 rePrint(1)的返回值为1X2X3X4X5
4.rePrint方法最终返回1X2X3X4X5 结果为120 再到main栈 传给num变量 最后输出 num = 120
内存图:
递归注意事项
1-执行一个方法时,就创建一个新的受保护的独立空间(栈空间)
2-方法的局部变量是独立的,不会相互影响,比如n变量
3-如果方法中使用的是引用类型变量(数组,对象),就会共享该引用类型的数据
4-递归必须向退出递归的条件逼近,否则就是无限递归,出现StackOverflowErro,栈溢出
5-当一个方法执行完毕,或者遇到return,就会返回,遵守谁调用,就将结果返回给谁,同时当方法执行完毕或者返回时,该方法也就执行完毕