递归调用机制
例:看下面代码输出什么
public class Recursion{
public static void main(String[] args){
T t = new T();
t.test(4);
int res = t.factorial(5);
System.out.println("res="+res);
}
}
class T{
public void test(int n){
if(n > 2){
test(n-1);//自己调用自己
}
System.out.println("n="+n);
}//输出 n=2;
//n = 3;
//n = 4;
public int factorial(int n){
if(n == 1){
return 1;
}else{
return factorial(n-1)*n;
}
}
}
递归重要规则
(1)执行一个方法时,就创建一个新的受保护的独立空间(栈空间)
(2)方法的局部变量是独立的,不会相互影响,比如n变量
(3)如果方法中使用的是引用数据类型变量(比如数组),就会共享该引用类型的数据
(4)递归必须向退出递归的条件逼近,否则就是无限递归,出现StackOverFlowError,”死龟了“:)(内存溢出)
(5)当一个方法执行完毕,或者遇到return,就会返回,遵守谁调用,就将结果返回给谁,同时当方法执行完毕或者返回时,该方法也就执行完毕
-
例
(1)请使用递归的方式求出斐波那契数列1,1,2,3,5,8,13...给你一个整数n,求出它的值是多少
public class RecursionExercise01{
public static void main(String[] args){
Mytools tool = new tool;
int res = tool.shulie(7);
System.out.println("res = "+ res);
}
}
class Mytools{
public int shulie(int n){
if( n <= 2){
return n == 1;
}else{
return shulie(n-1)+shulie(n-2);
}
}
}
(2)猴子吃桃问题:
有一堆桃子,猴子第一天吃了其中的一半,并再多吃了一个。以后每天猴子都吃其中的一半,然后再多吃一个。当到第十天时,还想再吃,发现只有一个桃子了。问:最初有多少桃子
public class Monkey{
public static void main(String[] args){
Peach day = new Peach();
int sum = day.peach(1);
if(sum != -1){
System.out.println("最初的桃子个数是"+ sum);
}
}
}
class Peach{
public int peach(int day){
if(day==10){
return 1;
}else if(day >= 1 && day <= 9){
return ((peach(n+1))+1)*2;
}else{
System.out.println("你的输入有误,请重新输入");
return -1;
}
}
}
方法递归案例:
(1)迷宫问题
注意事项:
①小球得到的路径,和设置的找路策略有关即:找路的上下左右的顺序相关
②在得到小球路径时,可以先使用(下右上左),再改成(上右下左),看看路径是不是有变化
③测试回溯现象
④思考:如何求出最短路径
public class MiGong{
public static void main(String[] args){
//思路:
//1、先创建迷宫,用二维数组表示int【】【】map = new int 【8】【7】;
//2、先规定map数组的元素值 0:表示可以走 1:表示障碍物
int[][] map = new int[8][7];
//最上面的一行和最下面的一行设置为1
for(int i = 0 ;i < 7;i++){
map[0][i] = 1;
map[7][i] = 1;
}
//最左边和最右边的一行设置为1
for(int j = 0 ;j < 6; j++){
map[j][0] = 1;
map[j][6] = 1;
}
map [2][1] = 1;
map [2][2] = 1;
System.out.println("====== 迷宫地形图如下:=====");
for(int i = 0; i < map.length; i++){
for(int j = 0; j < map[i].length ;j++){
System.out.print(map[i][j] + " ");
}
System.out.println();
}
MiGong mi = new MiGong();
mi.findway2(map , 1, 1);
System.out.println("=====找到的路如下=====");
for(int i = 0; i < map.length; i++){
for(int j = 0; j < map[i].length ;j++){
System.out.print(map[i][j] + " ");
}
System.out.println();
}
}
}
class MiGong{
// public boolean findway(int [][] map,int i,int j){
// /*思路:
// (1)findway方法就是专门找出来迷宫的路
// (2)当 map 【6】【5】==2时,找到了路,出迷宫
// (3)初始位置 map 【1】【1】 = 2
// (4)找到路,返回true。没找到,返回false
// (5)递归找路:先确定找路规则
// 0 表示可以走还没走,2表示可以走,3表示走不通
// (6)确定方向:下→右→上→左
// */
// if(map[6][5] == 2){
// return true;
// }
// else{
// if(map[i][j] == 0){
// map[i][j] = 2;
// if(findway(map, i+1,j)){
// return true;
// }else if(findway(map, i, j+1)){
// return true;
// }else if(findway(map, i - 1, j)){
// return true;
// }else if(findway(map, i , j-1)){
// return true;
// }else{
// map [i][j] = 3;
// return false;
// }
// }else{
// return false;
// }
// }
// }
public boolean findway2(int[][] map , int i, int j){
//改变行动策略 右->上-左->下
/*(1)findway方法就是专门找出来迷宫的路
(2)当 map 【6】【5】==2时,找到了路,出迷宫
(3)初始位置 map 【1】【1】 = 2
(4)找到路,返回true。没找到,返回false
(5)递归找路:先确定找路规则
0 表示可以走还没走,2表示可以走,3表示走不通
(6)确定方向:右->上-左->下*/
if(map[6][5] == 2){
return true;
}else{
if (map[i][j] == 0){
map[i][j] = 2;
if(findway2(map, i, j + 1)){
return true;
}else if(findway2(map, i + 1,j)){
return true;
}else if(findway2(map, i,j-1)){
return true;
}else if(findway2(map, i-1,j)){
return true;
}else{
map[i][j] = 3;
return false;
}
}else{
return false;
}
}
}
}
(2)汉诺塔
public class HanNuo{
public static void main(String[] args){
T m = new T();
m.move(3, 'A','B', 'C');
}
}
}
class T{
public void move(int num, char a,char b,char c){
if(num == 1){
System.out.println(a+"->"+c);
}else{
//把上面的num-1个圆盘移动到b塔上
move(num - 1,a , c, b);
//把最后一个圆盘移到c塔上
System.out.println(a + "->"+c);
//把b塔上的移到c上
move(num - 1,b,a,c);
}
}
}