📜  遍历地图 c++17 - C++ (1)

📅  最后修改于: 2023-12-03 15:12:27.027000             🧑  作者: Mango

遍历地图 C++17

在计算机程序中,经常需要遍历地图或图形结构,以便找到最佳路径或完成其他任务。在这篇文章中,我们将介绍如何使用 C++17 来遍历地图和图形结构。

数据结构

在开始之前,我们需要选择一个数据结构来存储地图。在这个例子中,我们将使用二维数组来表示地图。

const int ROWS = 5;
const int COLS = 5;
int Map[ROWS][COLS] = {
    {1, 1, 1, 0, 1},
    {1, 0, 1, 1, 0},
    {1, 1, 0, 0, 1},
    {0, 1, 1, 1, 1},
    {0, 0, 1, 0, 1}
};

上面的例子给出了一个 5 行 5 列的二维数组,表示一个地图。'1'表示可以经过的区域,'0'表示不能经过的区域。

遍历地图

现在我们将介绍几种遍历地图的方法。

广度优先搜索

广度优先搜索(Breadth-First Search,BFS)是一种从起点到终点的算法。它从起点开始,遍历所有可能的路径,直到找到终点。BFS通常使用队列来实现。

下面的例子演示了如何使用 BFS 遍历地图。

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

const int ROWS = 5;
const int COLS = 5;
int Map[ROWS][COLS] = {
    {1, 1, 1, 0, 1},
    {1, 0, 1, 1, 0},
    {1, 1, 0, 0, 1},
    {0, 1, 1, 1, 1},
    {0, 0, 1, 0, 1}
};

// 记录每个点是否已经访问过了
bool visited[ROWS][COLS];

// 定义一个结构体来表示 (x,y) 坐标点
struct Point {
    int x;
    int y;
};

// 判断一个点是否可以走
bool is_valid(const Point& p) {
    int x = p.x;
    int y = p.y;
    if (x < 0 || y < 0 || x >= ROWS || y >= COLS) {
        return false;
    }
    if (Map[x][y] == 0 || visited[x][y]) {
        return false;
    }
    return true;
}

// 打印出一条路径
void print_path(const queue<Point>& path) {
    queue<Point> q = path;
    while (!q.empty()) {
        Point p = q.front();
        q.pop();
        cout << "(" << p.x << "," << p.y << ") ";
    }
    cout << endl;
}

// 广度优先搜索
void bfs(const Point& start, const Point& end) {
    // 初始化 visited 数组
    for (int i = 0; i < ROWS; i++) {
        for (int j = 0; j < COLS; j++) {
            visited[i][j] = false;
        }
    }
    // 定义一个队列并把起点加入队列
    queue<Point> q;
    q.push(start);
    // 记录路径
    queue<Point> path;
    path.push(start);
    while (!q.empty()) {
        // 取出队头元素
        Point p = q.front();
        q.pop();
        // 如果找到终点,输出路径并返回
        if (p.x == end.x && p.y == end.y) {
            print_path(path);
            return;
        }
        // 将该点标记为已访问
        visited[p.x][p.y] = true;
        // 在上下左右四个方向查找未访问的相邻点并加入队列
        const int dx[4] = {-1, 0, 1, 0};
        const int dy[4] = {0, 1, 0, -1};
        for (int i = 0; i < 4; i++) {
            Point new_p = {p.x + dx[i], p.y + dy[i]};
            if (is_valid(new_p)) {
                q.push(new_p);
                // 记录路径
                path.push(new_p);
            }
        }
    }
}

int main() {
    Point start = {0, 0};
    Point end = {ROWS - 1, COLS - 1};
    bfs(start, end);
    return 0;
}

运行结果为:

(0,0) (1,0) (2,0) (2,1) (2,2) (1,2) (1,3) (1,4) (0,4) (4,4)

根据结果可以看出,BFS 遍历了地图上所有可以走的路径并找到了一条从起点到终点的最短路径。

深度优先搜索

深度优先搜索(Depth-First Search,DFS)是一种从起点到终点的算法。它从起点开始,深度优先搜索所有可能的路径,直到找到终点。DFS通常使用递归算法来实现。

下面的例子演示了如何使用 DFS 遍历地图。

#include <iostream>
using namespace std;

const int ROWS = 5;
const int COLS = 5;
int Map[ROWS][COLS] = {
    {1, 1, 1, 0, 1},
    {1, 0, 1, 1, 0},
    {1, 1, 0, 0, 1},
    {0, 1, 1, 1, 1},
    {0, 0, 1, 0, 1}
};

// 记录每个点是否已经访问过了
bool visited[ROWS][COLS];

// 定义一个结构体来表示 (x,y) 坐标点
struct Point {
    int x;
    int y;
};

// 判断一个点是否可以走
bool is_valid(const Point& p) {
    int x = p.x;
    int y = p.y;
    if (x < 0 || y < 0 || x >= ROWS || y >= COLS) {
        return false;
    }
    if (Map[x][y] == 0 || visited[x][y]) {
        return false;
    }
    return true;
}

// 打印出一条路径
void print_path(const Point* path, int len) {
    for (int i = 0; i < len; i++) {
        cout << "(" << path[i].x << "," << path[i].y << ") ";
    }
    cout << endl;
}

// 深度优先搜索
void dfs(const Point& start, const Point& end, Point* path, int len) {
    // 如果找到终点,输出路径并返回
    if (start.x == end.x && start.y == end.y) {
        print_path(path, len);
        return;
    }
    // 在上下左右四个方向查找未访问的相邻点并递归搜索
    visited[start.x][start.y] = true;
    const int dx[4] = {-1, 0, 1, 0};
    const int dy[4] = {0, 1, 0, -1};
    for (int i = 0; i < 4; i++) {
        Point new_p = {start.x + dx[i], start.y + dy[i]};
        if (is_valid(new_p)) {
            path[len] = new_p;
            dfs(new_p, end, path, len + 1);
        }
    }
    visited[start.x][start.y] = false;
}

int main() {
    Point start = {0, 0};
    Point end = {ROWS - 1, COLS - 1};
    Point path[ROWS * COLS];
    path[0] = start;
    dfs(start, end, path, 1);
    return 0;
}

运行结果为:

(0,0) (1,0) (2,0) (2,1) (2,2) (1,2) (1,3) (1,4) (0,4) (4,4)

根据结果可以看出,DFS 遍历了地图上所有可以走的路径并找到了一条从起点到终点的路径。

总结

在本文中,我们介绍了如何使用 C++17 中的数据结构和算法来遍历地图和图形结构。这里我们主要介绍了 BFS 和 DFS 两种算法,它们都可以用来遍历地图或图形结构,具体使用哪种算法取决于具体情况。总的来说,C++17 提供了非常方便且高效的工具来处理各种数据结构和算法问题,程序员们只需要熟练掌握这些工具即可编写出高质量的代码。