递归应用场景
迷宫问题(回溯),递归(Recursion)
递归概念
简单的说:递归就是方法自己调用自己,每次调用时传入不同的变量,递归有助于编程者解决复杂的问题,同时可以让代码变得简洁。
递归调用机制
打印问题阶乘问题
递归能解决什么样的问题
各种数学问题如:8皇后问题,汉诺塔,阶乘问题,迷宫问题,球和篮子的问题(google编程大赛) 2)各 种算法中也会使用到递归,比如快排,归并排序,二分查找,分治算法等.3)将用栈解决的问题–>递归代码比较简洁
递归需要遵守的重要规则
递归需要遵守的重要规则 1)执行一个方法时,就创建一个新的受保护的独立空间(栈空间) 2)方法的局部变量是独立的,不会相互影响,比如n变量 3)如果方法中使用的是引用类型变量(比如数组),就会共享该引用类型的数据. 4)递归必须向退出递归的条件逼近,否则就是无限递归,出现StackOverflowError。 5) 当一个方法执行完毕,或者遇到return, 就会返回,遵守谁调用,就将结果返回给谁,同时当方法执行完毕或者返回时,该方法也就执行完毕
递归-迷宫问题
package com
.xhl
.recursion
;
public class MigGong {
public static void main(String
[] args
) {
int[][] map
= new int[8][7];
for (int i
= 0; i
< 7; i
++) {
map
[0][i
] = 1;
map
[7][i
] = 1;
}
for (int i
= 0; i
< 8; i
++) {
map
[i
][0] = 1;
map
[i
][6] = 1;
}
map
[3][1] = 1;
map
[3][2] = 1;
map
[2][2] = 1;
System
.out
.println("地图情况");
for (int i
= 0; i
< 8; i
++) {
for (int j
= 0; j
< 7; j
++) {
System
.out
.printf("%d\t", map
[i
][j
]);
}
System
.out
.println();
}
setWay(map
, 1, 1);
System
.out
.println("小球走过地图情况");
for (int i
= 0; i
< 8; i
++) {
for (int j
= 0; j
< 7; j
++) {
System
.out
.printf("%d\t", map
[i
][j
]);
}
System
.out
.println();
}
}
private static boolean setWay(int[][] map
, int i
, int j
) {
if(map
[6][5]==2) {
return true;
}else {
if(map
[i
][j
]==0) {
map
[i
][j
]=2;
if(setWay(map
, i
+1, j
)) {
return true;
}else if(setWay(map
, i
, j
+1)){
return true;
}else if(setWay(map
, i
-1, j
)){
return true;
}else if(setWay(map
, i
, j
-1)){
return true;
}else {
map
[i
][j
]=3;
return false;
}
}else {
return false;
}
}
}
}
小球得到的路径,和程序员设置的找路策略有关即:找路的上下左右的顺序相关再得到小球路径时,可以先使用(下右上左),再改成(上右下左),看看路径是有变化的测试回溯现象
递归-八皇后问题
问题描述
八皇后问题,是一个古老而著名的问题,是回溯算法的典型案例。该问题是国际西洋棋棋手马克斯.贝瑟尔于1848年提出:在8X8格的国际象棋上摆放八个皇后,使其不能互相攻击,即:任意两个皇后都不能处于同一行、同一列或同一斜线上,问有多少种摆法(92)。
思路分析
第一个皇后先放第一行第一列第二个皇后放在第二行第一列、然后判断是否OK,如果不0K, 继续放在第二列、第三列、依次把所有列都放完,找到一个合适继续第三个皇后,还是第一列、第二列…直到第8个皇后也能放在一个不冲突的位置,算是找到了一个正确解当得到一个正确解时,在栈回退到上一个栈时,就会开始回溯,即将第一个皇后,放到第一-列的所有正确解,全部得到.然后回头继续第一个皇后放第二列,后面继续循环执行123,4 的步骤示意图:
理论.上应该创建一个二维数组来表示棋盘,但是实际上可以通过算法,用一个一维数组即可解决问题.ar[8]={0,4, 7,5,2,6, 1,3} //对应arr 下标表示第几行,即第几个皇后,arr[i]=val, val 表示第i+1个皇后,放在第i+1行的第va1+1列
package com
.xhl
.recursion
;
public class Queue8 {
int max
= 8;
int[] array
= new int[max
];
static int count
=0;
static int judgecount
=0;
public static void main(String
[] args
) {
Queue8 queue8
= new Queue8();
queue8
.check(0);
System
.out
.printf("一共有%d种解法\t",count
);
System
.out
.printf("一共判断冲突%d次",judgecount
);
}
private void check(int n
) {
if(n
==max
) {
print();
return ;
}
for(int i
=0;i
<max
;i
++) {
array
[n
]=i
;
if(judge(n
)) {
check(n
+1);
}
}
}
private boolean judge(int n
) {
judgecount
++;
for(int i
=0;i
<n
;i
++) {
if(array
[i
]==array
[n
]||Math
.abs(n
-i
)==Math
.abs(array
[n
]-array
[i
])) {
return false;
}
}
return true;
}
private void print() {
count
++;
for(int i
=0;i
<max
;i
++) {
System
.out
.printf("%d\t",array
[i
]);
}
System
.out
.println();
}
}