方法递归
什么是递归?
其实说白了就是自己调用自己。
递归没有结束条件的时候会发生栈内存溢出原理:
递归的执行原理:
案例1:
/* 方法递归? 1 什么是方法递归? 方法自己调用自己,这就是方法递归。 2 当递归时程序没有结束条件,一定会发生: 栈内存溢出错误:StackOverflowError 所以:递归必须要有结束条件(这是一个非常重要的知识点。) JVM发生错误之后只有一个结果,就是退出JVM。 3 递归假设是有结束条件的,就一定不会发生栈内存溢出错误吗? 假设这个结束条件是对的,是合法的,递归有的时候也会出现栈内存溢出错误。 因为有可能递归的太深,栈内存不够了。因为一直在压栈。 4 在实际的开发中,不建议轻易地选择递归,能用for循环while循环代替的,尽量使用循环来说。因为循环的效率高,耗费的内存少。 递归耗费的内存比较大,另外递归的使用不当,会导致JVM死掉。(但在极少数的情况下,不用递归,这个程序没办法实现。) 所以,递归我们还是要认真学习的 5 在实际的开发中,假设有一天你真的遇到了这个错误,你怎么解决这个问题,可以谈一下你的思路吗? 我来谈一下我的个人思路: 首先第一步:先检查递归的结束条件对不对。如果递归结束条件不对,必须对条件进一步修改,直到正确为止。 第二步:假设递归条件没问题,怎么办? 这个时候需要手动的调整JVM的栈内存初始化大小。 可以将栈内存的空间调大一些。(可以调整大一些。) 第三步:调整了大小,如果运行时还是出现这个错误,没办法,只能扩大栈的内存大小。 (java -X)这个可以查看调整堆栈大小的参数。 */ public class RecursionTest01{ public static void main(String[] args){ doSome(); } public static void doSome(){ System.out.println("doSome begin!"); // 调用方法:doSome既然是一个方法,那么doSome方法可以调用吗?当然可以。 doSome(); // 然后他一直自己调自己,所以他下面的这行代码永远都不会执行到。 System.out.println("doSome voer!"); } }
案例2:
// 先不使用递归,请编写程序,计算1~n的和 public class RecursionTest02{ public static void main(String[] args){ // 1~10的和 System.out.println(sum(10)); // 55 // 1~3的和 int result = sum(3); // 6 System.out.println(result); } // 单独编写一个计算1~n和的方法 public static int sum(int n){ int result = 0; for(int i = 1 ; i <= n ; i++){ result += i; } return result; } }
案例3:
// 使用递归,请编写程序,计算1~n的和 public class RecursionTest03{ public static void main(String[] args){ // 1~3的和 int result = sum(3); // 6 System.out.println(result); } // 大家努力的去看,去听,自己学不出来没关系 // 单独编写一个计算1~n和的方法 // 这个代码修改为递归的方式 // 3 + 2 + 1 public static int sum(int n){ if(n == 1){ return 1; } // 程序能执行到此处说明n不是1 // return 你+ sum(n - 1); int result = n + sum(n - 1); return result; } }
案例4:
// 实现1 * n 的递归方式 public class RecursionTest04{ public static void main(String[] args){ int n = 5; System.out.println(multiply(5)); } public static int multiply(int n){ if(n == 1){ return 1; } return n * multiply(n - 1); } }