迷宫问题

img
说明:

  • 小球得到的路径,和程序员 设置的找路策略有关即:找 路的上下左右的顺序相关
  • 再得到小球路径时,可以先 使用(下右上左),再改成(上 右下左),看看路径是不是有变化
  • 测试回溯现象
  • 思考: 如何求出最短路径? ``` //下面代码的找路策略是:下右上左 public static boolean setWay(int[][] map, int i, int j) { if (map[6][5] == 2) { // 表示路已经找到了
    1. return true;
    } else {
    1. if (map[i][j] == 0) { // 0: 可以走还没有走
    2. // 这里开始递归回溯
    3. map[i][j] = 2; // 认为该点是可以走通,但是不一定
    4. if (setWay(map, i + 1, j)) { // 下找
    5. return true;
    6. } else if (setWay(map, i, j + 1)) { // 右
    7. return true;
    8. } else if (setWay(map, i - 1, j)) { // 上
    9. return true;
    10. } else if (setWay(map, i, j - 1)) { // 左
    11. return true;
    12. } else {// 走不通
    13. map[i][j] = 3;
    14. return false;
    15. }
    16. } else {
    17. //如果map(i)(j)!=0
    18. //则值 1,2,3
    19. return false;}
    }}
  1. ```
  2. int[][] map = new int[8][7];
  3. //上下全部置1
  4. for(int i = 0 ; i<7;i++){
  5. map[0][i] = 1;
  6. map[7][i] = 1;
  7. }
  8. //左右全部置1
  9. for (int i = 0; i< 8; i++) {
  10. map[i][0] = 1;
  11. map[i][6] = 1;
  12. }

完整代码

  1. package com.atguigu.recursion;
  2. /**
  3. * ClassName: <br/>
  4. * Description: <br/>
  5. * Date: 2021-02-22 9:50 <br/>
  6. * @project data_algorithm
  7. * @package com.atguigu.recursion
  8. */
  9. public class MiGong {
  10. public static void main(String[] args) {
  11. // 先创建一个二维数组,模拟迷宫
  12. // 地图
  13. int[][] map = new int[8][7];
  14. // 使用1 表示墙
  15. // 上下全部置为1
  16. for (int i = 0; i < 7; i++) {
  17. map[0][i] = 1;
  18. map[7][i] = 1;
  19. }
  20. // 左右全部置为1
  21. for (int i = 0; i < 8; i++) {
  22. map[i][0] = 1;
  23. map[i][6] = 1;
  24. }
  25. //设置挡板, 1 表示
  26. map[3][1] = 1;
  27. map[3][2] = 1;
  28. // map[1][2] = 1;
  29. // map[2][2] = 1;
  30. // 输出地图
  31. System.out.println("地图的情况");
  32. for (int i = 0; i < 8; i++) {
  33. for (int j = 0; j < 7; j++) {
  34. System.out.print(map[i][j] + " ");
  35. }
  36. System.out.println();
  37. }
  38. //使用递归回溯给小球找路
  39. //setWay(map, 1, 1);
  40. setWay2(map, 1, 1);
  41. //输出新的地图, 小球走过,并标识过的递归
  42. System.out.println("小球走过,并标识过的 地图的情况");
  43. for (int i = 0; i < 8; i++) {
  44. for (int j = 0; j < 7; j++) {
  45. System.out.print(map[i][j] + " ");
  46. }
  47. System.out.println();
  48. }
  49. }
  50. //使用递归回溯来给小球找路
  51. //说明
  52. //1. map 表示地图
  53. //2. i,j 表示从地图的哪个位置开始出发 (1,1)
  54. //3. 如果小球能到 map[6][5] 位置,则说明通路找到.
  55. //4. 约定: 当map[i][j] 为 0 表示该点没有走过 当为 1 表示墙 ; 2 表示通路可以走 ; 3 表示该点已经走过,但是走不通
  56. //5. 在走迷宫时,需要确定一个策略(方法) 下->右->上->左 , 如果该点走不通,再回溯
  57. /**
  58. *
  59. * @param map 表示地图
  60. * @param i 从哪个位置开始找
  61. * @param j
  62. * @return 如果找到通路,就返回true, 否则返回false
  63. */
  64. public static boolean setWay(int[][] map, int i, int j) {
  65. if(map[6][5] == 2) { // 通路已经找到ok
  66. return true;
  67. } else {
  68. if(map[i][j] == 0) { //如果当前这个点还没有走过
  69. //按照策略 下->右->上->左 走
  70. map[i][j] = 2; // 假定该点是可以走通.
  71. if(setWay(map, i+1, j)) {//向下走
  72. return true;
  73. } else if (setWay(map, i, j+1)) { //向右走
  74. return true;
  75. } else if (setWay(map, i-1, j)) { //向上
  76. return true;
  77. } else if (setWay(map, i, j-1)){ // 向左走
  78. return true;
  79. } else {
  80. //说明该点是走不通,是死路
  81. map[i][j] = 3;
  82. return false;
  83. }
  84. } else { // 如果map[i][j] != 0 , 可能是 1, 2, 3
  85. return false;
  86. }
  87. }
  88. }
  89. //修改找路的策略,改成 上->右->下->左
  90. public static boolean setWay2(int[][] map, int i, int j) {
  91. if(map[6][5] == 2) { // 通路已经找到ok
  92. return true;
  93. } else {
  94. if(map[i][j] == 0) { //如果当前这个点还没有走过
  95. //按照策略 上->右->下->左
  96. map[i][j] = 2; // 假定该点是可以走通.
  97. if(setWay2(map, i-1, j)) {//向上走
  98. return true;
  99. } else if (setWay2(map, i, j+1)) { //向右走
  100. return true;
  101. } else if (setWay2(map, i+1, j)) { //向下
  102. return true;
  103. } else if (setWay2(map, i, j-1)){ // 向左走
  104. return true;
  105. } else {
  106. //说明该点是走不通,是死路
  107. map[i][j] = 3;
  108. return false;
  109. }
  110. } else { // 如果map[i][j] != 0 , 可能是 1, 2, 3
  111. return false;
  112. }
  113. }
  114. }
  115. }

运行结果

  1. 地图的情况
  2. 1 1 1 1 1 1 1
  3. 1 0 0 0 0 0 1
  4. 1 0 0 0 0 0 1
  5. 1 1 1 0 0 0 1
  6. 1 0 0 0 0 0 1
  7. 1 0 0 0 0 0 1
  8. 1 0 0 0 0 0 1
  9. 1 1 1 1 1 1 1
  10. 小球走过,并标识过的 地图的情况
  11. 1 1 1 1 1 1 1
  12. 1 2 2 2 2 2 1
  13. 1 0 0 0 0 2 1
  14. 1 1 1 0 0 2 1
  15. 1 0 0 0 0 2 1
  16. 1 0 0 0 0 2 1
  17. 1 0 0 0 0 2 1
  18. 1 1 1 1 1 1 1
  19. Process finished with exit code 0

通过递归,遍历所有方式的路径,共享棋盘中的数组位置数据

实现查找最优解

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

最后噼里啪啦的回去了

回溯