欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

【栈的应用】迷宫算法(栈和回溯思想)

程序员文章站 2024-01-28 18:15:34
...

人生,就像一个很大的栈演变。出生时赤条条地来到这个世界,慢慢地长大,渐渐地变老,最终还得赤条条地离开世间。

思路分析:


【栈的应用】迷宫算法(栈和回溯思想)

上面是一个迷宫地图,在地图上,0 代表墙,1 代表通路。

迷宫是回溯法和栈的综合应用。

下面给出完整的思路和寻路算法:

【栈的应用】迷宫算法(栈和回溯思想)
这里我们只研究一种情况:地图只有一条路径可以出去。

【栈的应用】迷宫算法(栈和回溯思想)
寻路算法按照上下左右的顺序进行遍历和判断。

【栈的应用】迷宫算法(栈和回溯思想)

从入口出发,按照上下左右的顺序寻路,每次的路径坐标Pos放到栈中,存放坐标是为了方便回溯。如上图,直到向上没有通路了,再查看当前位置,左,右是否有通路,实际如图所示,没有。那么就取栈顶坐标,回退一步,再查看左右是否有通路。如此循环。

【栈的应用】迷宫算法(栈和回溯思想)

如果不停地回退,导致栈中没有元素,这就说明回退到了迷宫入口。那么就可以说明此迷宫没有通路。

在迷宫中还有一点值得注意就是对是否为地图边界 的判断。

下面给出核心代码:

迷宫定义:

#define N 10
typedef struct Pos{
    int _row;
    int _col;
}Pos;

typedef struct Maze
{
    int _mz[N][N];
    Pos _entry;
}Maze;

寻路算法:

int CheckIsAccess(Maze *m, Pos pos)
{
    if(pos._row >= 0 && pos._row < N
       && pos._col >= 0 && pos._col < N
       && m->_mz[pos._row][pos._col] == 1)
       {
           return 1;
       }
       return 0;
}


void MazeGetPath(Maze* m)
{
    Stack s;
    StackInit(&s, 10);
    StackPush(&s, m->_entry);

    while(StackEmpty(&s) != 0)
    {
        //1,入口   2,下一个可以走的位置  3,回溯的上一个位置
        cur = StackTop(&s);
        m->_mz[cur._row][cur._col] = 2;

        if(cur._col == N-1)
        {
            printf("找到通路了\n");
            return;
        }

        Pos next = cur;

        //next._row -= 1;
        if(CheckIsAccess(m, next) == -1)
        {
            StackPush(&s, next);
            continue;
        }

        //下
        next = cur;
        next._row += 1;
        if(CheckIsAccess(m, next) == 1)
        {
            StackPush(&s, next);
            continue;
        }

        //左
        next = cur;
        next._col -= 1;
        if(CheckIsAccess(m, next) == 1)
        {
            StackPush(&s, next);
            continue;
        }

        //右
        next = cur;
        next._col += 1;
        if(CheckIsAccess(m, next) == 1)
        {
            StackPush(&s, next);
            continue;
        }

        //回溯
        StackPop(&s);
    }
    printf("没有通路\n");
}