C++ 迷宫求解:使用栈和队列寻找最短路径

本文将介绍如何使用 C++ 实现迷宫求解算法,并使用栈和队列两种数据结构来寻找从起点到终点的最短路径。

算法实现

该算法基于深度优先搜索 (DFS) 和广度优先搜索 (BFS) 两种策略,分别使用栈和队列来存储待探索的节点。

数据结构

  • Node: 表示迷宫中的一个节点,包含坐标 (x, y) 和到达该节点的方向 (dir)。
  • maze: 表示迷宫地图,用 1 表示可通行区域,用 0 表示障碍物。
  • visited: 表示已经访问过的节点,用 true 表示已访问,用 false 表示未访问。
  • dxdy: 用于表示移动方向的数组。

算法步骤

  1. 初始化迷宫和访问矩阵。
  2. 使用栈或队列存储起点节点。
  3. 循环遍历队列或栈中的节点,直到找到终点节点或所有节点都被访问过。
  4. 从当前节点向四个方向探索新的节点,如果新的节点有效且未被访问,则将其加入队列或栈中。
  5. 当找到终点节点时,输出从起点到终点的路径。

代码实现

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

struct Node {
    int x, y, dir;
    Node(int _x, int _y, int _dir) : x(_x), y(_y), dir(_dir) {}
};

// 定义方向常量
const int RIGHT = 1;
const int DOWN = 2;
const int LEFT = 3;
const int UP = 4;

// 定义迷宫和访问矩阵
int maze[101][101];
bool visited[101][101];

// 定义移动方向数组
int dx[5] = {0, 1, 0, -1, 0};
int dy[5] = {0, 0, 1, 0, -1};

// 定义迷宫的行数和列数
int M, N;

// 判断坐标是否有效
bool isValid(int x, int y) {
    return x >= 1 && x <= M && y >= 1 && y <= N && maze[x][y] == 1 && !visited[x][y];
}

// 输出路径
void printPath(int start_x, int start_y, int end_x, int end_y) {
    stack<Node> s;
    s.push(Node(end_x, end_y, 0));

    while (!s.empty()) {
        Node currentNode = s.top();
        s.pop();

        int x = currentNode.x;
        int y = currentNode.y;
        int dir = currentNode.dir;

        cout << '(' << x << ',' << y << ',' << dir << ')';
        if (s.size() % 5 == 0) {
            cout << endl;
        } else if (!s.empty()) {
            cout << ',';
        }

        for (int i = 1; i <= 4; i++) {
            int new_x = x + dx[i];
            int new_y = y + dy[i];

            if (isValid(new_x, new_y)) {
                visited[new_x][new_y] = true;
                s.push(Node(new_x, new_y, i));
                break;
            }
        }
    }
}

// 使用栈寻找最短路径
bool findShortestPath(int start_x, int start_y, int end_x, int end_y) {
    stack<Node> s;
    s.push(Node(start_x, start_y, 0));
    visited[start_x][start_y] = true;

    while (!s.empty()) {
        Node currentNode = s.top();
        s.pop();

        int x = currentNode.x;
        int y = currentNode.y;
        int dir = currentNode.dir;

        if (x == end_x && y == end_y) {
            printPath(start_x, start_y, end_x, end_y);
            return true;
        }

        for (int i = dir + 1; i <= 4; i++) {
            int new_x = x + dx[i];
            int new_y = y + dy[i];

            if (isValid(new_x, new_y)) {
                visited[new_x][new_y] = true;
                s.push(Node(new_x, new_y, 0));
                break;
            }
        }
    }

    return false;
}

// 使用队列确定最短路径
bool findShortestPathBFS(int start_x, int start_y, int end_x, int end_y) {
    queue<Node> q;
    q.push(Node(start_x, start_y, 0));
    visited[start_x][start_y] = true;

    while (!q.empty()) {
        Node currentNode = q.front();
        q.pop();

        int x = currentNode.x;
        int y = currentNode.y;
        int dir = currentNode.dir;

        if (x == end_x && y == end_y) {
            printPath(start_x, start_y, end_x, end_y);
            return true;
        }

        for (int i = 1; i <= 4; i++) {
            int new_x = x + dx[i];
            int new_y = y + dy[i];

            if (isValid(new_x, new_y)) {
                visited[new_x][new_y] = true;
                q.push(Node(new_x, new_y, 0));
            }
        }
    }

    return false;
}

int main() {
    while (cin >> M >> N && M != 0 && N != 0) {
        // 初始化迷宫和访问矩阵
        for (int i = 1; i <= M; i++) {
            for (int j = 1; j <= N; j++) {
                cin >> maze[i][j];
                visited[i][j] = false;
            }
        }

        int start_x = 1, start_y = 1;
        int end_x = M, end_y = N;

        // 使用栈找最短路径
        if (findShortestPath(start_x, start_y, end_x, end_y)) {
            cout << endl;
        } else {
            // 使用队列找最短路径
            if (findShortestPathBFS(start_x, start_y, end_x, end_y)) {
                cout << endl;
            } else {
                cout << "没有通路" << endl;
            }
        }
    }

    return 0;
}

代码说明

  • findShortestPath() 函数使用栈来实现深度优先搜索,它会优先探索当前节点的下一个方向,直到找到终点节点或所有节点都被访问过。
  • findShortestPathBFS() 函数使用队列来实现广度优先搜索,它会按照层级顺序探索所有节点,保证找到的最短路径。
  • printPath() 函数用于输出从终点到起点的路径,该路径是根据访问顺序反推得到的。

示例运行

例如,对于以下迷宫地图:

5 5
1 1 1 1 1
1 0 0 0 1
1 1 1 0 1
1 0 0 1 1
1 1 1 1 1

使用栈和队列找到的最短路径分别为:

  • 使用栈找到的路径: (5,5,0),(5,4,4),(4,4,3),(4,3,3),(3,3,1),(2,3,1),(1,3,1),(1,2,2),(1,1,0)
  • 使用队列找到的路径: (1,1,0),(2,1,2),(2,2,2),(3,2,2),(3,3,3),(4,3,3),(4,4,4),(5,4,4),(5,5,0)

总结

本文介绍了使用 C++ 实现迷宫求解算法,并使用栈和队列两种数据结构来寻找最短路径。该算法代码清晰易懂,可扩展性强,可以用于解决各种迷宫求解问题。

C++ 迷宫求解:使用栈和队列寻找最短路径

原文地址: https://www.cveoy.top/t/topic/XUX 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录