如何理解"回溯"这个词呢?说白了就是利用递归相关的知识,来解决一些实际生活中的问题。这里我用一个简单的迷宫游戏带大家理解一下这个算法!
话不多说,先上代码:
public class migong {
public static void main(String[] args) {
// TODO 自动生成的方法存根
//地图
int [][] map = new int[10][10];
//使用1表示墙
//上下全部置为1
for(int i =0;i<10;i++) {
map[0][i] = 1;
map[9][i] = 1;
}
//左右全部置为1
for(int i = 0;i < 10;i++) {
map[i][0] = 1;
map[i][9] = 1;
}
//设置挡板
map[3][1] = 1;
map[3][2] = 1;
map[4][3] = 1;
map[5][4] = 1;
map[6][5] = 1;
map[7][6] = 1;
map[8][7] = 1;
// 输出地图
for(int i = 0;i < 10;i++) {
for(int j = 0;j < 10;j++) {
System.out.print(map[i][j]+" ");
}
System.out.println();
}
这个代码段就是我们先要设计一个迷宫地图出来,这里我们利用二维数组来处理这个问题,我们定义一个10*10的二维数组,我们将1视为墙,利用for循环遍历给数组赋值,然后可以设计出我们想要的迷宫,下面来看运行结果。
这里我们需要给出小球的初始位置,已经我们想让小球到达的终点位置,看代码:
setWay(map,1,1);//小球起始位置
System.out.println("小球走过,并标识过的地图情况");
for(int i = 0;i < 10;i++) {
for(int j = 0;j < 10;j++) {
System.out.print(map[i][j]+" ");
}
System.out.println();
}
}
public static boolean setWay(int[][]map,int i ,int j){
if(map[8][8]==2) {//通路已经找到ok
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,j-1)) {//向左走
return true;
}
else if(setWay(map,i-1,j)) {//向上走
return true;
}else {
map[i][j]= 3;//说明该点走不通,是死路
return false;
}
}else {//如果map[i][j]!=0,可能是1,2,3
return false;
}
}
}
}
大家可以详细看一下代码段的内容,每一个部分都注释的非常清楚,该问题最关键的是要确定小球的行走路线,这里我们需要确定一个策略(方法),根据下->右->左->上来让小球行走,如果该点走不通,再回溯,最后大家看一下最终的运行结果:
其中红线标注的是小球的具体行走路线,可以看到小球是按照我们的想法"下->右->左->上",来行走的,这说明我们的方法是可行的。
下面给出完整的代码,大家有兴趣的可以在自己的电脑上面运行一下玩一玩,没有装java编译器的小伙伴没有关系,大家可以在百度搜索java在线工具-->菜鸟工具-->选择java语言就可以在线运行了:
public class migong {
public static void main(String[] args) {
// TODO 自动生成的方法存根
//地图
int [][] map = new int[10][10];
//使用1表示墙
//上下全部置为1
for(int i =0;i<10;i++) {
map[0][i] = 1;
map[9][i] = 1;
}
//左右全部置为1
for(int i = 0;i < 10;i++) {
map[i][0] = 1;
map[i][9] = 1;
}
//设置挡板
map[3][1] = 1;
map[3][2] = 1;
map[4][3] = 1;
map[5][4] = 1;
map[6][5] = 1;
map[7][6] = 1;
map[8][7] = 1;
// 输出地图
for(int i = 0;i < 10;i++) {
for(int j = 0;j < 10;j++) {
System.out.print(map[i][j]+" ");
}
System.out.println();
}
setWay(map,1,1);//小球起始位置
System.out.println("小球走过,并标识过的地图情况");
for(int i = 0;i < 10;i++) {
for(int j = 0;j < 10;j++) {
System.out.print(map[i][j]+" ");
}
System.out.println();
}
}
//1.使用递归回溯来给小球找路
/*2.map 表示地图
*3. i 从哪个位置开始找(1,1)
*4.如果小球找到map[6][5],表示通路已经找到
*约定:当map[i][j]为0表示该点没有走过,当为1表示墙,2表示通路可以走,3表示该点已经走过,但是走不通
*在走迷宫时,需要确定一个策略(方法),下->右->左->上,如果该点走不通,在回溯
*5. 如果找到通路,就返回true,否则返回false
*
*/
public static boolean setWay(int[][]map,int i ,int j){
if(map[8][8]==2) {//通路已经找到ok
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,j-1)) {//向左走
return true;
}
else if(setWay(map,i-1,j)) {//向上走
return true;
}else {
map[i][j]= 3;//说明该点走不通,是死路
return false;
}
}else {//如果map[i][j]!=0,可能是1,2,3
return false;
}
}
}
}
这个是一起的运行结果: