背景
上一节已经制造出了地图并写下了第一个代码,实现了走迷宫并找到出口
迷宫问题的递归方法调用
测试回溯现象:如果地图现在变成这样,执行的步骤是怎样的呢
测试一下
public class MiGong01 {
public static void main(String[] args) {
//初始化地图
int[][] map = new int[8][7];
//8代表行7代表列
//初始化行
for (int i = 0; i < 7; i++) {
map[0][i] = 1;
map[7][i] = 1;
}
//初始化列
for (int i = 0; i < 8; i++) {
for (int j = 0; j < 7; j++) {
if (j == 0 || j == 6) {
map[i][j] = 1;
}
}
}
//初始化特殊的两个格子
map[3][1] = 1;
map[3][2] = 1;
map[2][2] = 1;
//走一遍试试
tools04 t = new tools04();
t.findWay(map, 1, 1);
for (int i = 0;i<map.length;i++){
for(int j = 0;j<map[i].length;j++){
System.out.print(map[i][j]+"\t");
}
System.out.println("");
}
}
}
class tools04{
//传入的map为经过初始化的符合要求的(墙代表1,可以走的路代表0)二维数组
//i和j为初始位置的坐标
public boolean findWay(int[][] map, int i,int j){
//5.因为我们是递归的找路,所以我先规定 map数组的各个值的含义:
// 0 表示可以走 1 表示障碍物 2 表示可以走 3 表示走过,但是走不通,是死路
//6.当map[6][5] =2 就说明找到通路,就可以结束,否则就继续找
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;
}
}
}
}
执行结果
1 1 1 1 1 1 1
1 2 2 2 0 0 1
1 3 1 2 0 0 1
1 1 1 2 0 0 1
1 0 0 2 0 0 1
1 0 0 2 0 0 1
1 0 0 2 2 2 1
1 1 1 1 1 1 1
为什么会这样呢
这是因为当老鼠走到2,1这个位置的时候会发现向下走为false,然后接着是右边,上边,左边,发现都是不通,也就是说当向下的那个if语句没有正确的结果,就会留下一个3,回溯到第一个地方(差不多就是上一级)然后开始右边的if,这个过程就是回溯现象
扩展思考:如何求出最短的路径
方法1,穷举法(麻烦,但是容易理解)
方法2,用图的数据结构求出最短路径,这个就涉及到以后说的数据结构和算法
对于穷举法,我的想法是给方法的执行次数里面加一个计数器,统计出每个运行策略(上下左右顺序打乱为24种,分别统计出执行次数,然后最小的即为最优结果,下面是其中一种结果的实现方法)
public class MiGong02 {
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++) {
for (int j = 0; j < 7; j++) {
if (j == 0 || j == 6) {
map[i][j] = 1;
}
}
}
map[3][1] = 1;
map[3][2] = 1;
map[2][2] = 1;
//执行的逻辑与上一节相同,只有这里加了一个计数器,统计执行的次数
int counter[] = new int[1];
tools05 t = new tools05();
t.findWay(map, 1, 1,counter);
for (int i = 0;i<map.length;i++){
for(int j = 0;j<map[i].length;j++){
System.out.print(map[i][j]+"\t");
}
System.out.println("");
}
System.out.println("执行计数:"+counter[0]);
}
}
class tools05{
public boolean findWay(int[][] map, int i,int j,int[] counter){
if(map[6][5] == 2){
counter[0]++;
return true;
}else{
if(map[i][j] == 0){
map[i][j] = 2;
if(findWay(map,i+1,j,counter)){
counter[0]++;
return true;
}else if(findWay(map,i,j+1,counter)){
counter[0]++;
return true;
}else if(findWay(map,i-1,j,counter)){
counter[0]++;
return true;
}else if(findWay(map,i,j-1,counter)){
counter[0]++;
return true;
}else {
map[i][j] = 3;
counter[0]++;
return false;
}
}else {
counter[0]++;
return false;
}
}
}
}