四方显神

导航

数据结构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

 

posted on 2020-09-28 22:02  szdbjooo  阅读(289)  评论(0编辑  收藏  举报