迷宫的制作
迷宫如下,可以看成一个二维数组,黑色的代表是墙,不能通过,黄色的代表迷宫的起点,红的代表终点。
初始化二维数组中的数值
令:1代表墙,表示不能通过
int [][] map=new int[7][8];
int plan1=0;
int plan2=0;
for(int i=0;i<7;i++){
map[i][0]=1;
map[i][7]=1;
}
for(int j=0;j<8;j++){
map[0][j]=1;
map[6][j]=1;
}
map[1][6]=1;
map[2][1]=1;
map[2][2]=1;
map[2][4]=1;
map[3][2]=1;
map[4][5]=1;
map[4][3]=1;
System.out.println("=======map====");
for(int i=0;i<7;i++){
for(int j=0;j<8;j++){
System.out.print(map[i][j]+" ");
}
System.out.println(" ");
}
结果为:
=======map====
1 1 1 1 1 1 1 1
1 0 0 0 0 0 1 1
1 1 1 0 1 0 0 1
1 0 1 0 0 0 0 1
1 0 0 1 0 1 0 1
1 0 0 0 0 0 0 1
1 1 1 1 1 1 1 1
利用递归实现路径搜索
定义判断节点是否可以通过的方法
1. map表示迷宫地图
2. int i和j表示地图的哪一个节点开始搜索
3.对此地图而言,如果到达了map[4][4]的位置,说明通路已经找到了
4.规定:当map[i][j]为0表示该节点没有走过,当为1,表示墙,当为2 表示可以走,当为3表示节点已经走过,但是走不通
5.在走迷宫时,需要确定一个走的策略右--》下==》上==》左,如果走不通则回溯。
方法代码:
public static boolean judgePoint(int[][] map,int i,int j){
//设置终点,表示如果经过了终点,则说明搜索路径结束
if(map[4][4]==2){
return true;
}else {
//最先输入的这个点假设没有走过
if(map[i][j]==0){
//先把这个点假设可以走得通
map[i][j]=2;
//先向右走
if(judgePoint(map,i,j+1)){
return true;
//向右走不通则向下走
}else if(judgePoint(map, i+1, j)){
return true;
//如果先下走不通,则向向上走
}else if(judgePoint(map, i-1, j)){
return true;
//如果向上走不通,则向左走
}else if(judgePoint(map, i, j-1)){
return true;
}else {
//都走不通,则把这个点设成走不通3
map[i][j]=3;
return false;
}
}
//如果不为0,则可能为1,2,3.此时都不可以通过。
else {
return false;
}
}
}
比较最短路径
可以看出优化方式可以从搜索的路径上开始解决,此方法的搜索路径是右–》下==》上==》左。
可以多写几种遍历的方式来进行比较,如下例中比较了两种搜索的路径不同,来通过走过的节点数,判断最短的路径。
注意,要用不同的引用来传值,也就是要重新创建一个map二维数组,来进行调用judgePoint方法。
测试代码
package com.njupt.recurrence;
/**
* Creat with IntelliJ IDEA
*
* @Auther:倔强的加瓦
* @Date:2021/07/17/15:15
* @Description:
*/
public class MazePra {
public static void main(String[] args) {
//先创建一个二维数组来管理迷宫
int[][] map = new int[7][8];
int plan1 = 0;
int plan2 = 0;
for (int i = 0; i < 7; i++) {
map[i][0] = 1;
map[i][7] = 1;
}
for (int j = 0; j < 8; j++) {
map[0][j] = 1;
map[6][j] = 1;
}
map[1][6] = 1;
map[2][1] = 1;
map[2][2] = 1;
map[2][4] = 1;
map[3][2] = 1;
map[4][5] = 1;
map[4][3] = 1;
//这里为什么要重新创建一个地图呢?为什么用int[][] map1=map,然后用map1调用第二个方法不行呢?可以帮我回答一下吗???
int[][] map1 = new int[7][8];
for (int i = 0; i < 7; i++) {
map1[i][0] = 1;
map1[i][7] = 1;
}
for (int j = 0; j < 8; j++) {
map1[0][j] = 1;
map1[6][j] = 1;
}
map1[1][6] = 1;
map1[2][1] = 1;
map1[2][2] = 1;
map1[2][4] = 1;
map1[3][2] = 1;
map1[4][5] = 1;
map1[4][3] = 1;
System.out.println("=======map====");
for (int i = 0; i < 7; i++) {
for (int j = 0; j < 8; j++) {
System.out.print(map[i][j] + " ");
}
System.out.println(" ");
}
System.out.println("=======map1====");
for (int i = 0; i < 7; i++) {
for (int j = 0; j < 8; j++) {
System.out.print(map1[i][j] + " ");
}
System.out.println(" ");
}
System.out.println("=====策略1,先向右,在向下=====");
judgePoint(map, 1, 1);
for (int i = 0; i < 7; i++) {
for (int j = 0; j < 8; j++) {
System.out.print(map[i][j] + " ");
if (map[i][j] == 2) {
plan1++;
}
}
System.out.println(" ");
}
System.out.println("=====策略2,先向下,在向右=====");
judgePoint2(map1, 1, 1);
for (int i = 0; i < 7; i++) {
for (int j = 0; j < 8; j++) {
System.out.print(map1[i][j] + " ");
if (map1[i][j] == 2) {
plan2++;
}
}
System.out.println(" ");
}
System.out.println("策略1:先右后下的策略,共走了" + plan1 + "步");
System.out.println("策略2:先下后右的策略,共走了" + plan2 + "步");
if (plan1 < plan2) {
System.out.println("故策略1:先右后下的策略好,共走了" + plan1 + "步");
} else {
System.out.println("故策略2:先下后右的策略好,共走了" + plan2 + "步");
}
}
//开始写判断节点位置的状态的方法
// 策略1,向往右,在往下,在向上,在向左
//规定:1表示墙,2表示节点已经走过,3表示此节点不通
public static boolean judgePoint(int[][] map, int i, int j) {
if (map[4][4] == 2) {
return true;
} else {
//最先输入的这个点假设没有走过
if (map[i][j] == 0) {
//先把这个点假设可以走得通
map[i][j] = 2;
//先向右走
if (judgePoint(map, i, j + 1)) {
return true;
//向下走
} else if (judgePoint(map, i + 1, j)) {
return true;
//如果先下走不通,则向向上走
} else if (judgePoint(map, i - 1, j)) {
return true;
//如果向上走不通,则向左走
} else if (judgePoint(map, i, j - 1)) {
return true;
} else {
//都走不通,则把这个点设成走不通3
map[i][j] = 3;
return false;
}
} else {
return false;
}
}
}
//策略2,先往下,后往右,在向上,在向左
public static boolean judgePoint2(int[][] map, int i, int j) {
if (map[4][4] == 2) {
return true;
} else {
//最先输入的这个点假设没有走过
if (map[i][j] == 0) {
//先把这个点假设可以走得通
map[i][j] = 2;
//先向下走
if (judgePoint2(map, i + 1, j)) {
return true;
//如果先下走不通,则向右走
} else if (judgePoint2(map, i, j + 1)) {
return true;
//如果先右走不通,则向向上走
} else if (judgePoint2(map, i - 1, j)) {
return true;
//如果向上走不通,则向左走
} else if (judgePoint2(map, i, j - 1)) {
return true;
} else {
//都走不通,则把这个点设成走不通3
map[i][j] = 3;
return false;
}
} else {
return false;
}
}
}
}
测试结果
"D:\iedal\IntelliJ IDEA 2019.3.3\jbr\bin\java.exe" "-javaagent:D:\iedal\IntelliJ IDEA 2019.3.3\lib\idea_rt.jar=32130:D:\iedal\IntelliJ IDEA 2019.3.3\bin" -Dfile.encoding=UTF-8 -classpath E:\Java学习\数据结构与算法\DataStructure\out\production\SpareArray com.njupt.recurrence.MazePra
=======map====
1 1 1 1 1 1 1 1
1 0 0 0 0 0 1 1
1 1 1 0 1 0 0 1
1 0 1 0 0 0 0 1
1 0 0 1 0 1 0 1
1 0 0 0 0 0 0 1
1 1 1 1 1 1 1 1
=======map1====
1 1 1 1 1 1 1 1
1 0 0 0 0 0 1 1
1 1 1 0 1 0 0 1
1 0 1 0 0 0 0 1
1 0 0 1 0 1 0 1
1 0 0 0 0 0 0 1
1 1 1 1 1 1 1 1
=====策略1,先向右,在向下=====
1 1 1 1 1 1 1 1
1 2 2 2 2 2 1 1
1 1 1 0 1 2 2 1
1 0 1 0 0 0 2 1
1 0 0 1 2 1 2 1
1 0 0 0 2 2 2 1
1 1 1 1 1 1 1 1
=====策略2,先向下,在向右=====
1 1 1 1 1 1 1 1
1 2 2 2 0 0 1 1
1 1 1 2 1 0 0 1
1 0 1 2 2 0 0 1
1 0 0 1 2 1 0 1
1 0 0 0 0 0 0 1
1 1 1 1 1 1 1 1
策略1:先右后下的策略,共走了13步
策略2:先下后右的策略,共走了7步
策略2:故先下后右的策略好,共走了7步
Process finished with exit code 0