数据结构009_递归(迷宫回溯算法)
在公司工作空隙里敲敲,基本上也觉得不难回来就不会再敲一遍了。还是上周敲完的代码了。今天趁着写博客重新敲一遍。
递归简单来说就是自己调用自己,每次调用传入不同的变量。
递归调用能解决的数学问题如:8皇后、汉诺塔、阶乘、迷宫、球和篮子等。
有些算法也会使用递归,比如快排、归并排序、二分查找、分治算法等。
注意点:
- 当程序执行到一个方法时,就会开辟一个独立的空间(栈).所以递归调用很占内存。
- 方法的局部变量是独立的,不会相互影响。
- 如果方法中使用的是引用类型变量(比如数组),就会共享该引用变量的数据。
- 递归必须向退出递归的条件逼近,否则就是无限递归,StackOverFlowError。
- 谁调用,就将结果返回给谁。
问题实例:迷宫问题。我就模拟一个8*8的棋盘当做迷宫的地图,搞点障碍物。就下面这个。
代码:
package com.njcx.test4; import javax.swing.text.StyledEditorKit.ForegroundAction; import javax.tools.ForwardingJavaFileObject; public class Mazi { public static void main(String[] args) { // 定义一个二维数组模拟地图 int[][] map = new int[8][8]; // 设置一些墙和障碍物 1代表墙或障碍物,不可通路 for (int i = 0; i < map.length; i++) { // 首先四面都是墙 map[0][i] = map[7][i] = map[i][0] = map[i][7] = 1; // 其他四个障碍物 map[1][4] = map[2][4] = map[3][4] = map[5][2] = 1; } // 输出地图,看看什么损样 for (int[] row : map) { for (int item : row) { System.out.print(item); } System.out.println(); } getWay(map, 1, 1); // 看看走完的地图啥样 //注意哈,你想要找其他的路径就要改变策略,一个策略就走一条路,找最短路径就要把策略都定义一遍再比较 for (int[] row : map) { for (int item : row) { System.out.print(item); } System.out.println(); } } // 使用递归回溯来给小球找路 // 说明 // 1. map 表示地图 // 2. i,j 表示从地图的哪个位置开始出发 (1,1) // 3. 如果小球能到 map[6][6] 位置,则说明通路找到. // 4. 约定: 当map[i][j] 为 0 表示该点没有走过 当为 1 表示墙 ; 2 表示通路可以走 ; 3 表示该点已经走过,但是走不通 // 5. 在走迷宫时,需要确定一个策略(方法) 下->右->上->左 , 如果该点走不通,再回溯 public static boolean getWay(int[][] map, int i, int j) { if (map[6][6] == 2) { System.out.println("通"); return true; } else { // 按 下->右->上->左 策略找路 while (map[i][j] == 0) { // 这个点没有走过 map[i][j] = 2;// 先假定这个点可以通 if (getWay(map, i + 1, j)) return true; else if (getWay(map, i, j + 1)) return true; else if (getWay(map, i - 1, j)) return true; else if (getWay(map, i, j - 1)) return true; else { // 走不通 map[i][j] = 3; return false; } } // while循环外面就是map[i][j]!=0,123都不通 return false; } } }
这里有个小思考:如何求出最短路径?这个要改变策略。将代码改动一点点就可以了。比较每种策略下的路径长度就可以了。
这里我看到别人用栈来模拟迷宫回溯问题,链接做参考。
https://blog.csdn.net/qq_41804778/article/details/80623053