递归的定义
一个过程或函数在其定义或说明中有直接或间接调用自身的一种方法,它通常把一个大型复杂的问题层层转化为一个与原问题相似的规模较小的问题来求解,递归策略只需少量的程序就可描述出解题过程所需要的多次重复计算,大大地减少了程序的代码量。
递归的应用场景
- 应用于各种数学问题如:八皇后问题、汉诺塔、阶乘问题、迷宫问题、球和篮子的问题等等。
- 各种算法中也会使用到递归如:快排、归并排序、二分查找、分治算法等。
- 将用栈解决的问题使用递归得到的代码会更加简洁。
递归需要遵守的规则
- 执行一个方法,就创建一个新的受保护的独立空间(栈空间)。
- 方法的局部变量是独立的不会相互影响。
- 如果方法中使用的是引用类型变量,就会共享该引用类型的数据。
- 递归必须向退出递归的条件逼近,否则就会无限递归。
- 当一个方法执行完毕,或者遇到return时,就会返回,遵守谁调用就将结果返回给谁吗,同时当方法执行完毕或者返回时,该方法也就执行完毕。
递归的优缺点
- 优点:代码简洁、便于理解。
- 缺点:时间和空间的消耗较大,容易造成栈溢出、效率较低。
迷宫问题的解决
- 使用二维数组来代表迷宫地图,这里的地图为8*8大小。
- 对地图进行初始化 0代表未走过的路 1代表墙 2代表通路 3代表已经走过但不通的路。
- 定义起点为 map[1][2], 出口为 map[6][6]。
- 制定寻找通路的策略如:下 -> 右 -> 上 -> 左。不同的策略可能得到不同的结果。
代码实现(java)
public class MazeBacktracking {
public static void main(String[] args) {
int [][] map = new int[8][8];
for (int i = 0; i <8; i++) {
map[i][0] = 1;
map[i][7] = 1;
map[0][i] = 1;
map[7][i] = 1;
}
map[3][1] = 1;
map[3][2] = 1;
map[5][4] = 1;
map[6][3] = 1;
System.out.println("初始的迷宫:");
print(map);
setRoad(map, 1, 1);
System.out.println("最终的迷宫:");
print(map);
}
public static Boolean setRoad (int map[][], int i, int j) {
if (map[6][6] == 2) {
return true;
} else {
if (map[i][j] == 0) {
map[i][j] = 2;
if (setRoad(map, i + 1, j)) {
return true;
}
if (setRoad(map, i, j + 1)) {
return true;
}
if (setRoad(map, i - 1, j)) {
return true;
}
if (setRoad(map, i, j - 1)) {
return true;
}
map[i][j] = 3;
return false;
} else {
return false;
}
}
}
public static void print (int [][] map) {
for (int i = 0; i < 8; i++){
for (int j = 0; j < 8; j++){
System.out.printf("%d", map[i][j]);
if (j != 7) {
System.out.printf(" ");
}
}
System.out.println();
}
System.out.println();
}
}