1. 迷宫会回溯
递归在于解决的问题的特点:对于每一个分块具有一样的操作,这样的问题可以采用递归的方法去实现。
比如:针对迷宫的每一个点,遇到墙则返回。
package Package01;
public class MiGong {
public static void main(String[] args) {
//先创建一个二维数组,模拟迷宫
//地图
int[][] map = new int[8][7];
//上下全部置为1
for(int i=0; i<map[0].length; i++){
map[0][i] = 1;
map[7][i] = 1;
}
//左右置为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[1][2] = 1;
//map[2][2] = 1;
map[4][2] = 1;
map[5][2] = 1;
map[5][3] = 1;
map[5][4] = 1;
map[4][4] = 1;
//显示出矩阵
System.out.println("地图情况:");
for(int[] cow:map){
for(int data:cow){
System.out.print("\t" + data);
}
System.out.println();
}
//使用递归回溯来给小球找路
setWay(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();
}
}
/**
*
* @param map 表示地图
* @param i 表示从地图哪个位置开始出发,横坐标
* @param j 表示从地图哪个位置开始出发,纵坐标
* @return
*
* 1.如果小球能到map[6][5],则说明通路找到
* 2.约定:当地图的map[i][j]为0时,表示该点没有走过。
* 如果为1表示墙,
* 如果为2表示通路可以走,true
* 如果为3表示该点已经走过,但是走不通
* 3.在走迷宫时,我们需要确定一个策略。下 -> 右 -> 上 -> 左
*/
public 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{//如果map[i][j] != 0,可能是1,2,3
return false; //说明这一个点是不能走的,只能改变自己的方向
}
}
}
}
"C:\Program Files\Java\jdk1.8.0_152\bin\java.exe" "-javaagent:D:\软件下载\idea\idea\IntelliJ IDEA 2021.1\lib\idea_rt.jar=61535:D:\软件下载\idea\idea\IntelliJ IDEA 2021.1\bin" -Dfile.encoding=UTF-8 -classpath "C:\Program Files\Java\jdk1.8.0_152\jre\lib\charsets.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\deploy.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\access-bridge-64.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\cldrdata.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\dnsns.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\jaccess.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\jfxrt.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\localedata.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\nashorn.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\sunec.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\sunjce_provider.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\sunmscapi.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\sunpkcs11.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\zipfs.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\javaws.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\jce.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\jfr.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\jfxswt.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\jsse.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\management-agent.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\plugin.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\resources.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\rt.jar;E:\刘建成\java\project\HSP\out\production\Modulate03" Package01.MiGong
地图情况:
1 1 1 1 1 1 1
1 0 0 0 0 0 1
1 0 0 0 0 0 1
1 1 1 0 0 0 1
1 0 1 0 1 0 1
1 0 1 1 1 0 1
1 0 0 0 0 0 1
1 1 1 1 1 1 1
路线
1 1 1 1 1 1 1
1 2 0 0 0 0 1
1 2 2 2 0 0 1
1 1 1 2 2 2 1
1 0 1 3 1 2 1
1 0 1 1 1 2 1
1 0 0 0 0 2 1
1 1 1 1 1 1 1
Process finished with exit code 0
2.八皇后问题
八皇后问题:是一个古老而著名的问题,是回溯算法的经典案例。该问题是国际西洋象棋手马克思在1848年提出的:在8*8各格的国际象棋上摆放8个皇后,使其不能相互攻击,即:任意两个皇后都不能处于同一行,同一列或者同一斜线上面,问有多种摆法。
高斯认为有76种方案。1854年在柏林的象棋杂志上不同的作者发表了40种不同的解,后来有人用图论的方法解出了92种结果。计算机发明后,有多种计算机语言可以解决此问题。
八皇问题的算法分析:
- 第一个皇后先放第一行第一列
- 第二个皇后放在第二行第一列,然后判断是否ok,如果不ok,继续放在第二列,第三列,依次把所有列都放完,找到一个合适。
- 继续第三个皇后,还是第一列,第二列…直到第8个皇后也能放在一个不冲突的位置,算是找到一个正确解。
- 当得到一个正确解时,在栈回退到上一个栈时,就会开始回溯,即将第一个皇后,放到第一列的所有正确解,全部得到。
- 然后回头继续第一个皇后放到第二列,后面继续循环执行1,2,3的步骤。
说明:理论上,应该创建一个二维数组来表示棋盘,但实际上可以通过算法,用一个一维数组即可解决问题。