一、简介
回溯法的基本思想是:对一个包括有很多结点,每个结点有若干个搜索分支的问题,把原问题分解为对若干个子问题求解的算法。当搜索到某个结点、发现无法再继续搜索下去时,就让搜索过程回溯(即退回)到该结点的前一结点,继续搜索这个结点的其他尚未搜索过的分支;如果发现这个结点也无法再继续搜索下去时,就让搜索过程回溯到这个结点的前一结点继续这样的搜索过程;这样的搜索过程一直进行到搜索到问题的解或搜索完了全部可搜索分支没有解存在为止。
该方法可以使用堆栈实现。也可以使用递归实现,递归实现的话代码比较简单,较难理解建议自己打断点一步步跟踪理解
//=============
1 /** 2 * 回溯法解决,迷宫算法 3 * 4 * @author MIX 5 * 6 */ 7 public class MyMaze { 8 9 private static int startPosI; // 入口的i下标 10 private static int startPosJ; // 入口的j下标 11 private static int endPosI; // 出口的j下标 12 private static int endPosJ; // 出口的j下标 13 14 // 设置迷宫入口的坐标 15 public void setStart(int startPosI, int startPosJ) { 16 17 MyMaze.startPosI = startPosI; 18 MyMaze.startPosJ = startPosJ; 19 } 20 21 // 设置迷宫出口的坐标 22 public void setEnd(int endPosI, int endPosJ) { 23 24 MyMaze.endPosI = endPosI; 25 MyMaze.endPosJ = endPosJ; 26 } 27 28 // 迷宫搜索通路的算法 29 /** 30 * 31 * @param cell 32 * 迷宫地图 33 * @param i 34 * 入口的i坐标 35 * @param j 36 * 入口的j坐标 37 */ 38 public static void visited(int[][] cell, int i, int j) { 39 // 表示此路为通 40 /* 41 * 该标记记为走过该路径,一旦该路径为通路且走到了该路径那么就将该位置置为1 42 */ 43 cell[i][j] = 1; 44 String oriention = null; 45 if (i == endPosI && j == endPosJ) { // 找到了出口 46 System.out.println("找到一条通路"); 47 for (int m = 0; m < cell.length; m++) { 48 for (int n = 0; n < cell[i].length; n++) { 49 if (cell[m][n] == 2) { 50 System.out.print("2"); 51 } else if (cell[m][n] == 1) { 52 System.out.print("*"); 53 } else { 54 System.out.print(" "); 55 } 56 } 57 System.out.println(); 58 } 59 } 60 61 // 向左边寻找通路 62 if (cell[i][j - 1] == 0) { 63 oriention = "left"; 64 visited(cell, i, j - 1); 65 } 66 // 向右寻找通路 67 if (cell[i][j + 1] == 0) { 68 oriention = "right"; 69 visited(cell, i, j + 1); 70 } 71 // 向上寻找通路 72 if (cell[i - 1][j] == 0) { 73 oriention = "up"; 74 visited(cell, i - 1, j); 75 } 76 // 向下寻找通路 77 if (cell[i + 1][j] == 0) { 78 oriention = "down"; 79 visited(cell, i + 1, j); 80 } 81 /* 82 * 一旦该路径走到了死胡同里,清理走过的路径将当前位置重新标志为1,推出当前递归的迭代堆栈,返回上一次,继续 83 * 在当前函数里面的应用主要是清理之前走过的但是被标记为1的位置,将该位置重新置为0,以便下一次的位置可以访问 84 */ 85 oriention = "无知的我"; 86 cell[i][j] = 0; 87 88 } 89 90 public static void main(String[] args) { 91 // 初始化一个迷宫地图 92 int[][] maze = { { 2, 2, 2, 2, 2, 2, 2, 2, 2 }, 93 { 2, 0, 0, 0, 0, 0, 0, 0, 2 }, { 2, 0, 2, 2, 0, 2, 2, 0, 2 }, 94 { 2, 0, 2, 0, 0, 2, 0, 0, 2 }, { 2, 0, 2, 0, 2, 0, 2, 0, 2 }, 95 { 2, 0, 0, 0, 0, 0, 2, 0, 2 }, { 2, 2, 0, 2, 2, 0, 2, 2, 2 }, 96 { 2, 0, 0, 0, 0, 0, 0, 0, 2 }, { 2, 2, 2, 2, 2, 2, 2, 2, 2 } }; 97 98 // MyMaze cell = new MyMaze(); 99 // cell.setStart(1, 1); 100 // cell.setEnd(7, 7); 101 // cell.visited(maze, startPosI, startPosI); 102 int[][] maze2 = { { 2, 2, 2, 2 }, { 2, 0, 0, 2 }, { 2, 0, 0, 2 }, 103 { 2, 2, 2, 2 } }; 104 MyMaze cell = new MyMaze(); 105 cell.setStart(1, 1); 106 cell.setEnd(2, 2); 107 cell.visited(maze2, startPosI, startPosJ); 108 } 109 110 }
//上面代码里面的测试代码我是用了一个比较简单的4*4矩阵进行测试,方便断点观察,理解该算法的思路。
//这里其实和递归方法的方法栈应用有点类似。
时间: 2024-10-14 22:34:50