栈——迷宫问题

前言:

这是基于栈的迷宫问题讲解,并不是最优解,毕竟只是穷举法,所以这个算法也不可能太聪明。

迷宫问题算是很简单的算法了,所以本文无论是否了解迷宫问题都可以阅读,但是如果完全不了解STL库可能会对代码有阅读障碍。

思路讲解:

(本算法确实很简单,没啥好讲的,故而讲述会较为简略)

1.首先确定下起点和终点

2.由起点选择一个方向朝着终点出发

3.若当前方向可前行则继续选择任意一个方向前行

4.若此次前行的位置不可继续前行则记录下该坐标无法通行

5.回退到上一个位置,选择一个其它方向前行

6.继续步骤4,若三个方向都不可以继续前进,则回退到上一个位置

7.由此位置开始选择一个其它方向前进,重复上述步骤

8.直到到达终点为止

9.若起点的四个方向都不可前进了,则说明没有到达终点的路径

代码如下:

(代码注释很详细,故而不再作文字讲解,看不懂也没关系,最下方有b站的该代码的视频讲解链接)

/****************************************************

    > File Name:     迷宫问题
    > Author:        唯恒
    > Mail:          2279811789@qq.com
    > Created Time:  2022年10月23日

*******************************************************/

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

//初始化迷宫
char** const InitMaze()
{
    char** const maze = new char*[12];
    static char mazes[12][13]=//手动生成一个迷宫,重点在于求解迷宫问题,没必要随机生成
    {
        {"************"},//*代表不可走,0代表可以走
        {"*0**********"},
        {"*00000******"},
        {"*0*0********"},
        {"*0*0*0000***"},
        {"***0*0**0***"},
        {"***0000*0***"},
        {"**00*0**0***"},
        {"*****0*000**"},
        {"*****0*0*00*"},
        {"*****0*0**0*"},
        {"************"},
    };
    
    for (int i = 0;i < 12;i++)
    {
        maze[i] = mazes[i];
    }
    
    return maze;
}

//行走路线图
class Path
{
public:
    vector<pair<int, int>> path;//记录足迹
    pair<int, int> terminus;//终点
    bool Can_t_walk[12][12] ;//不能走的地方
    char *maze[12];//迷宫副本 

    //初始化时将起点与终点入栈
    Path(pair<int, int>const origin, pair<int, int>const terminus, char** maze);

    //判断当前位置能否行走
    bool Pass(pair<int, int>const p);

    //下一步要走的位置
    pair<int, int> NextDirection();

    //开始寻路
    void find();

};

Path::Path(pair<int, int>const origin, pair<int, int>const terminus, char** maze)
{
    Can_t_walk[12][12] = { false };//不能走的地方,false可以走,true不可以走

    for (int i = 0;i < 12;i++)
    {
        this->maze[i] = maze[i];
    }
    if (origin.first < 1 || origin.second < 1 || origin.first>11 || origin.second>11 ||//判断起点坐标是否非法
        terminus.first < 1 || terminus.second < 1 || terminus.first>11 || terminus.second>11 ||//判断终点点坐标是否非法
        origin == terminus)//如果起点==终点 毫无意义
    {
        perror("参数错误\n");
        exit(1);
    }
    maze[origin.first][origin.second] = '1';//起点肯定在栈上
    path.push_back(origin);//起点压栈

    this->terminus = terminus;
}

bool Path::Pass(pair<int, int>const p)
{
    if (maze[p.first][p.second] == '1')//不能走回头路
        return false;
    if (Can_t_walk[p.first][p.second] == true)//已经确定走不通的路
        return false;
    if (maze[p.first][p.second] == '*')//不可前进的位置
        return false;
    return true;
}

pair<int, int> Path::NextDirection()
{
    pair<int, int>p = *--path.end();

    //依次判断四个方向是否可以前进
    if (Pass(make_pair(p.first + 1, p.second)))
    {
        return make_pair(p.first + 1, p.second);
    }
    else if (Pass(make_pair(p.first - 1, p.second)))
    {
        return make_pair(p.first - 1, p.second);
    }
    else if (Pass(make_pair(p.first, p.second + 1)))
    {
        return make_pair(p.first, p.second + 1);
    }
    else if (Pass(make_pair(p.first, p.second - 1)))
    {
        return make_pair(p.first, p.second - 1);
    }
    if (*path.begin() == p)//当起点找不到前行路径时说明已经找不到路了 梅梅
    {                                                                // (别问梅梅是啥意思,我后来检测代码的时候发现的,不知道按错哪两个键,就打上去了,连输入法都记到了我前女友的名字了,哭,我真的好难过,也别问我为啥不删掉这两个字,就是不想,没有为啥)
        cout << "抱歉找不到正确路径" << endl;
        exit(1);
    }
    return make_pair(-1, -1);//返回失败标志
}

void Path::find()
{
    while (true)
    {
        pair<int, int> p = NextDirection();//获取下一次前行的位置

        if (p == make_pair(-1, -1))//栈顶位置为死路弹出栈顶
        {
            Can_t_walk[(*(--path.end())).first][(*(--path.end())).second] = true;//标记该位置为死路
            maze[(*(--path.end())).first][(*(--path.end())).second] = '0';
            path.pop_back();
        }
        else//可以前行则压栈,并记录下当前位置已经走过
        {
            maze[p.first][p.second] = '1';
            path.push_back(p);
        }
     
        if (*(--path.end()) == terminus)//栈顶与终点重合
        {
            return;
        }
    }
}

int main()
{
    char** maze = InitMaze();
    cout << "迷宫如图:" << endl;
    for(int i=0;i<12;i++)
    {
        for (int j = 0;j < 12;j++)
        {
            cout << " " << maze[i][j]<<" ";
        }
        cout << endl << endl;
    }

    Path p(make_pair(1, 1), make_pair(10, 10), maze);
    p.find();

    cout << "路径如图:" << endl;
    for (int i = 0;i < 12;i++)
    {
        for (int j = 0;j < 12;j++)
        {
            cout << " " << p.maze[i][j] << " ";
        }
        cout << endl << endl;
    }
    return 0;
}

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
以下是使用 C 语言实现迷宫问题的完整代码: ```c #include<stdio.h> #include<stdlib.h> #include<conio.h> #define MAX_ROW 5 #define MAX_COL 5 int maze[MAX_ROW][MAX_COL] = { {0, 1, 0, 0, 0}, {0, 1, 0, 1, 0}, {0, 0, 0, 0, 0}, {0, 1, 1, 1, 0}, {0, 0, 0, 1, 0}, }; void print_maze() { int i, j; for (i = 0; i < MAX_ROW; i++) { for (j = 0; j < MAX_COL; j++) { printf("%d ", maze[i][j]); } printf("\n"); } printf("*********\n"); } typedef struct { int row, col; } element; element stack[512]; int top = -1; void push(element item) { stack[++top] = item; } element pop() { return stack[top--]; } int is_empty() { return top == -1; } void path() { int i, row, col, next_row, next_col; element position; maze[0][0] = 2; top = 0; stack[0].row = stack[0].col = 0; while (!is_empty()) { position = pop(); row = position.row; col = position.col; printf("(%d, %d)\n", row, col); if (row == MAX_ROW - 1 && col == MAX_COL - 1) { printf("Path found!\n"); return; } if (col+1 < MAX_COL && maze[row][col+1] == 0) { // right next_row = row; next_col = col+1; maze[next_row][next_col] = 2; position.row = next_row; position.col = next_col; push(position); } if (row+1 < MAX_ROW && maze[row+1][col] == 0) { // down next_row = row+1; next_col = col; maze[next_row][next_col] = 2; position.row = next_row; position.col = next_col; push(position); } if (col-1 >= 0 && maze[row][col-1] == 0) { // left next_row = row; next_col = col-1; maze[next_row][next_col] = 2; position.row = next_row; position.col = next_col; push(position); } if (row-1 >= 0 && maze[row-1][col] == 0) { // up next_row = row-1; next_col = col; maze[next_row][next_col] = 2; position.row = next_row; position.col = next_col; push(position); } print_maze(); } printf("Path not found\n"); } int main() { path(); return 0; } ``` 在上述代码中,我们定义了一个 `maze` 数组来表示迷宫,0 表示可以通过的路,1 表示障碍物,2 表示走过的路程。我们使用来记录已经走过的路径,并通过 `push()` 和 `pop()` 操作来实现的基本功能。在 `path()` 函数中,我们从起点开始遍历迷宫,如果找到了终点,则输出 "Path found!",否则输出 "Path not found"。 我们可以通过调用 `print_maze()` 函数来输出迷宫的状态,以及调用 `path()` 函数来寻找迷宫的路径。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值