复杂迷宫问题的递归实现以及最短路径

复杂迷宫就是有多条通路的迷宫,而且要求解最短路的话就要用递归集合栈,用递归探测,寻找所有通路,用栈保存所走过的路径,具体方法为:
(1)从当前点为起点探测由它开始能前进的点(这里的探测方向为上,有,左,下);
(2)找到能前进的点之后,首先将这个点的坐标压入栈(path)中保存起来,并将这个点的值赋为前一个点的值加1;递归调用这个函数,继续探测;
(3)当前结点不能前进之后,将path中的点弹出栈,探测它的另一个可以前进的方向;
(4)当前结点为出口时,比较栈path和栈shortestpath的size,将值较小的栈赋值给shortestpath;

具体代码如下:

#include <iostream>
#include <stack>
using namespace std;

const int N = 10;

int MazeMap[N][N] =
{
{ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
{ 0, 0, 0, 1, 1, 1, 1, 1, 1, 1 },
{ 1, 1, 0, 1, 1, 1, 1, 1, 1, 1 },
{ 1, 1, 0, 1, 1, 0, 0, 0, 1, 1 },
{ 1, 1, 0, 1, 1, 0, 1, 0, 1, 1 },
{ 1, 1, 0, 0, 0, 0, 0, 0, 1, 1 },
{ 1, 1, 1, 0, 1, 1, 1, 0, 1, 1 },
{ 1, 1, 1, 0, 1, 1, 1, 0, 1, 1 },
{ 1, 1, 1, 0, 1, 1, 1, 0, 1, 1 },
};

void PrintMap(int maze[][N], size_t N) 
{
    for (size_t i = 0;i < N;++i)
    {
        for (size_t j = 0;j < N;++j)
        {
            cout << maze[i][j]<<" ";
        }
        cout << endl;
    }
}

struct Pos
{
    size_t i;
    size_t j;
};
bool IsGoingR(int maze[][N], size_t n, Pos cur, Pos next)
{
    if (next.i < n && next.i >= 0 && next.j < n && next.j >= 0)
    {
        if (maze[next.i][next.j] == 0 || maze[cur.i][cur.j] < maze[next.i][next.j])
        {
            return true;
        }
    }
    return false;
}

bool GetTheWayR(int maze[][N], size_t n, Pos pos, stack<Pos>& path,stack<Pos>& shortestpath)
{
    path.push(pos);
    if (pos.i == n - 1)
    {
        if (path.size() < shortestpath.size()||shortestpath.empty())
        {
            shortestpath = path;
        }
    }
    Pos next;

    //上
    next = pos;
    next.i = pos.i - 1;
    if (IsGoingR(maze, N, pos, next))
    {
        maze[next.i][next.j] = maze[pos.i][pos.j] + 1;
        if (GetTheWayR(maze, N, next, path, shortestpath))
        {
            return true;
        }
    }

    //右
    next = pos;
    next.j = pos.j + 1;
    if (IsGoingR(maze, N, pos, next))
    {
        maze[next.i][next.j] = maze[pos.i][pos.j] + 1;
        if (GetTheWayR(maze, N, next, path, shortestpath))
        {
            return true;
        }
    }

    //左
    next = pos;
    next.j = pos.j - 1;
    if (IsGoingR(maze, N, pos, next))
    {
        maze[next.i][next.j] = maze[pos.i][pos.j] + 1;
        if (GetTheWayR(maze, N, next, path, shortestpath))
        {
            return true;
        }
    }
    //下
    next = pos;
    next.i = pos.i + 1;
    if (IsGoingR(maze, N, pos, next))
    {
        maze[next.i][next.j] = maze[pos.i][pos.j] + 1;
        if (GetTheWayR(maze, N, next, path, shortestpath))
        {
            return true;
        }
    }

    path.pop();
    return 0;
}

void Test()
{
    PrintMap(MazeMap, N);

    stack<Pos> path;
    stack<Pos> shortestpath;
    Pos entry = { 2,0 };
    GetTheWayR(MazeMap, N,entry,path,shortestpath);
    cout << endl;
    PrintMap(MazeMap, N);
}

运行结果:
这里我们可以清楚地看到所走过的路径。
这里写图片描述

而且我们可以看到,栈shortestpath中保存着最短路径的坐标。
这里写图片描述

  • 3
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值