DFS求解迷宫问题

DFS求解迷宫问题

给定一个迷宫地图,实际就是一个二维的数组,其中0代表可通过,1代表有障碍不能通过,求出所有路径。这种搜索问题一般使用深度搜索DFS,从出口处开始,根据选择的不同方向(上下左右)来到达另一个位置,这时可以把新到达的位置看做是新的起点,这样就可以递归的求解同样的子问题,递归结束的条件是最后到达了终点。在搜索的过程中,我们可以进行剪枝操作,我们先沿着某个方向走,并沿途把走过的节点进行标记,沿着某个节点一直搜索下去,不中南墙不回头,直到碰到障碍,或者数组越界,走到了已经访问过的节点,这时就直接返回,不必再继续搜索下去,可以称之为回溯,实际是递归的返回。
下面为具体代码:

#include <iostream>
#include <stdlib.h>
#include <vector>
#include <string>
using namespace std;
//迷宫问题
#define M 5//行数
#define N 5//列数
int map[M][N] = {
    { 0, 1, 0, 0, 0 },
    { 0, 0, 0, 0, 0 },
    { 1, 0, 0, 1, 1 },
    { 0, 1, 0, 1, 0 },
    { 1, 1 ,0 ,0, 0 },
};
//用一个数组来标记是否走过某个位置
int mark[5][5] = { 0 };//初始全部未标记
//终点
int di = 4, dj = 4;
int dir[4][2] = { { -1, 0 }, { 1, 0 }, { 0, 1 }, { 0, -1 } };//四个方向
static int num = 0;
//x,y代表起点座标
bool DFS(int x, int y, vector<vector<int>> &vec, vector<int> &path)
{
    if (x < 0 || x >= M || y < 0 || y >= N||mark[x][y]==1)//数组越界或者被标记了
    {
        return false;
    }
    if (map[x][y] == 1)//碰到障碍
        return false;
    if (x == di&&y == dj)//当起点座标与终点相等时,返回真
    {
        path.push_back(5 * x + y);//终点存入路径中
        vec.push_back(path);
        //开始这里没有添加,终点自己要单独弹出,否则其余路径会对一个节点值
        path.pop_back();//与push对应
        num++;
        cout << "找到了" << num << "条路径" << endl;
        return true;
    }
    path.push_back(5 * x + y);//将该点存入路径中
    mark[x][y] = 1;
    for (int i = 0; i < 4;i++)
    {
        int tx = x + dir[i][0];
        int ty = y + dir[i][1];
        DFS(tx, ty, vec, path);//依次搜索该点周围的四个点,但在dfs中会处理
            //比如 该点为障碍就返回,该点为访问过了的节点也返回,
    }
    mark[x][y] = 0;
    path.pop_back();
}
//测试
int main(void)
{
    vector<vector<int>> vec;
    vector<int> path;
    bool flag=DFS(0, 0, vec, path);
    if (flag)
        cout << "\n---------------yes-------------" << endl;
    vector<int>::iterator it;
    for (int i = 0; i < vec.size();i++)
    {
        for (it = vec[i].begin(); it != vec[i].end(); it++)
        {
            cout<< *it << " ";
        }
        cout << endl;
    }
    system("pause");
}

运行结果为《DFS求解迷宫问题》
实际还可以求解所有路径中最小的路径,只要在终点判断的逻辑中加入一个变量存储路径的长度即可。

点赞