如何理解"回溯"这个词呢?说白了就是利用递归相关的知识,来解决一些实际生活中的问题。这里我用一个简单的迷宫游戏带大家理解一下这个算法!

话不多说,先上代码:

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循环遍历给数组赋值,然后可以设计出我们想要的迷宫,下面来看运行结果。

快速构建Java挡板 java挡板接小球_System

这里我们需要给出小球的初始位置,已经我们想让小球到达的终点位置,看代码:

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挡板接小球_i++_02

其中红线标注的是小球的具体行走路线,可以看到小球是按照我们的想法"下->右->左->上",来行走的,这说明我们的方法是可行的。

下面给出完整的代码,大家有兴趣的可以在自己的电脑上面运行一下玩一玩,没有装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;
			   
		   }
	   }
   }

}

这个是一起的运行结果:

快速构建Java挡板 java挡板接小球_i++_03