1 package com.recursion; 2 3 /* 4 * 递归(recursion)基本介绍 5 * 1、简单的说,递归就是方法自己调用自己,每次调用时传入不同的变量,递归有助于编程者解决复杂的问题,同事也可以让代码变得简洁 6 * 2、当程序执行到一个方法是,都会开辟一个独立的空间 7 * 3、每个空间的数据(局部变量)都是独立的 8 * 9 * 通过两个案例,对递归做简单回顾: 10 * 1)打印问题调用机制 11 * 1)首先执行main函数,在栈中开辟一个空间 12 * 2)在main函数中遇到test(4),则继续在栈中开辟另一个空间,执行test(4) 13 * 3)在test(4)这个栈中,执行if语句,则执行test(3),此时test(4)这个栈中暂时不会执行打印语句,而是继续开辟空间test(3) 14 * 4)在test(3)这个栈空间中,继续判断if语句,则继续执行test(2),即test(3)这个栈空间中不会执行打印语句,而是继续开辟test(2)空间 15 * 5)在test(2)中,执行if语句,则不满足条件,此时继续执行打印语句,即打印n=2,此时test(2)这个栈空间执行完毕,释放 16 * 6)返回test(3)这个栈空间,继续执行打印,即打印n=3,则test(3)这个栈空间执行完毕,释放 17 * 7)返回test(4)这个栈空间,继续执行打印,即打印n=4,则test(4)这个栈空间执行完毕,释放 18 * 8)返回main()这个栈空间,继续执行main函数中test(4)后面的代码,如果没有则退出main函数,执行结束 19 * 20 * 2)阶乘问题 21 * 22 * 递归能解决什么问题 23 * 1、各种数学问题如:8皇后问题,汉诺塔,阶乘问题,迷宫问题,球和篮子问题等 24 * 2、各种算法中也会使用到递归,如快排,归并排序,二分法查找,分之算法等 25 * 3、将用栈解决的问题=》递归代码比较简洁 26 * 27 * 递归需要遵守的重要原则: 28 * 1、执行一个方法时,就创建一个新的受保护的独立空间栈空间 29 * 2、方法中的局部变量是独立的,不会相互影响 30 * 3、如果方法中使用的是引用类型变量,就会共享该应用类型的数据 31 * 4、递归必须向推出的递归的条件逼近,否则就是无限递归,出现StackOverflowError, 32 * 5、当一个方法执行完毕,或者遇到return,就会返回,遵守谁调用,就将结果返回给谁, 33 * 同时当执行方法执行完毕或者返回时,该方法也就执行完毕 34 */ 35 public class RecursionDemo { 36 37 public static void test(int n) 38 { 39 /* 40 * 如果n=4,则显示结果为: 41 * n= 2 42 * n= 3 43 * n= 4 44 */ 45 46 if(n>2) 47 { 48 test(n-1); 49 } 50 System.out.println("n= "+n); 51 } 52 public static void test2(int n) 53 { 54 /* 55 * 如果n=4,则显示结果为: 56 * n= 2 57 */ 58 59 if(n>2) 60 { 61 test2(n-1); 62 } 63 else 64 { 65 System.out.println("n= "+n); 66 } 67 } 68 69 //阶乘问题 70 public static int factorial(int n) 71 { 72 if(n==1) 73 { 74 return 1; 75 } 76 else 77 { 78 return factorial(n-1)*n;// 79 } 80 } 81 public static void main(String[] args) { 82 // TODO Auto-generated method stub 83 //通过打印问题,回顾递归调用机制 84 test(4); 85 System.out.println("带else语句"); 86 test2(4); 87 88 System.out.println("阶乘结果:"); 89 System.out.println(factorial(10)); 90 } 91 }
执行结果如下:
n= 2 n= 3 n= 4 带else语句 n= 2 阶乘结果: 3628800