递归——应用

迷宫问题

小球找路径:

image-20230126160647622

代码实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
public class Migong {
public static void main ( String[] args ) {
//先创建一个二维数组,模拟迷宫
//地图
int[][] map = new int[ 8 ][ 7 ];
//使用1表示墙
for ( int i = 0 ; i < 7 ; i++ ) {
map[ 0 ][ i ] = 1;
map[ 7 ][ i ] = 1;
}
for ( int i = 1 ; i < 7 ; i++ ) {
map[ i ][ 0 ] = 1;
map[ i ][ 6 ] = 1;
}
map[ 3 ][ 1 ] = 1;
map[ 3 ][ 2 ] = 1;
//遍历出来
list ( map );
//使用递归函数找路
//setWay ( map, 1, 1 );
list ( map );
setWay2 ( map, 1, 1 );

//输出新的地图,小球走过,并标识过的地图
list ( map );

}

private static void list ( int[][] map ) {
System.out.println ("地图情况" );
for ( int i = 0 ; i < 8 ;i++) {
for ( int j = 0 ; j < 7 ; j++ ) {
System.out.print ( map[i][j]+" ");
}
System.out.println ( );
}
}

//使用递归回溯来给小球找路
//说明
//i,j表示从地图的哪个位置开始出发(1,1)
//如果小球能到map[6][5]位置,则说明通路找到
//约定:当map[i][j]为0表示该点没有走过,当为1表示墙,当为2表示通路可以走,3表示该点已经走过,但走不通
//在走迷宫时,我们需要确定一个策略,下-》右-》上-》左如果该点走不通,在回溯
/**
*
* @param map 表示地图
* @param i 从哪个位置开始出发
* @param j
* @return 如果找到返回true,否在false
*/
public static boolean setWay ( int[][] map, int i, int j ) {
if ( map[ 5 ][ 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;

}
}
}

//修改策略,上-》右下左
public static boolean setWay2 ( int[][] map, int i, int j ) {
if ( map[ 5 ][ 5 ] == 2 ) {//表示通路已经找到
return true;
}else {
if ( map[ i ][ j ] == 0 ) {//如果当前这个点还没有走过
//按策略下-》右-》上-》左
map[ i ][ j ] = 2; //假设该点可以走通
if ( setWay2 ( map, i-1, j ) ) { //向上走
return true;
}
else if ( setWay2 ( map, i, j + 1 ) ) { //向右走
return true;
}else if ( setWay2 ( map, i+1, j ) ){ //向下走
return true;
}
else if ( setWay2 ( map, i, j - 1 ) ) { //向左走
return true;
}
else {
map[ i ][ j ] = 3; //说明该节点走不通,是死路
return false;
}
}else { //如果map[i][j]!=0,可能是1,2,3
return false;

}
}
}

}

结果

策略:下-》右-》上-》左

这里有张图片:
image-20230127221950295

策略:上-》右-》下-》左

这里有张图片:
image-20230127222120850

讨论

  1. 小球得到的路径,和程序员设置的找路策略有关

  2. 所以目前求最短路径可以根据策略来找最短路径,改变策略顺序依次求出每个策略所得出的路径,进而比较求出最短路径。