C语言使用深度优先搜索算法解决迷宫问题(堆栈)

yizhihongxing

C语言使用深度优先搜索算法解决迷宫问题 (堆栈)

什么是深度优先搜索算法

深度优先搜索算法 (DFS) 是一种常见的搜索算法。深度优先搜索算法像探险家一样从起点往前走,如果碰到了障碍物就返回,再尝试另一条路径。这个过程就是递归。

在深度优先搜索算法中,我们需要利用堆栈结构来保存需要回溯的节点。在搜索过程中,我们访问每个相邻的顶点,并将已经访问过的标记为已访问。然后我们继续访问相邻的节点,并标记已访问,如此下去,直到找到我们需要的节点,或是到达终点。

迷宫问题

假设我们有一个 n 行 m 列的迷宫,为了通行方便,我们将道路和墙都画成了矩阵,矩阵里的数字表示他的属性。其中,0 表示道路,1 表示墙,2 表示起点,3 表示终点。

我们需要使用深度优先搜索算法,在这个迷宫中找出一条从起点到终点的路径。

以下是一个 6x6 的迷宫示例:

1 1 1 1 1 1
1 0 0 0 0 1
1 0 1 1 0 1
1 0 0 1 0 1
1 0 0 0 0 1
1 1 1 1 1 1

起点为 (1, 1),终点为 (4, 4)。

解决迷宫问题

我们可以使用一个二维数组来表示迷宫,并初始化起点和终点的坐标:

#define MAX_ROW 6
#define MAX_COL 6
int maze[MAX_ROW][MAX_COL] = {
    {1, 1, 1, 1, 1, 1},
    {1, 0, 0, 0, 0, 1},
    {1, 0, 1, 1, 0, 1},
    {1, 0, 0, 1, 0, 1},
    {1, 0, 0, 0, 0, 1},
    {1, 1, 1, 1, 1, 1}
};

// 起点和终点
int start_row = 1, start_col = 1;
int end_row = 4, end_col = 4;

我们还需要一个 stack 数据结构,用于保存需要回溯的节点:

#define MAX_SIZE 100
typedef struct {
    int row;
    int col;
} element;

// 定义堆栈
element stack[MAX_SIZE];
int top = -1;

// 入栈操作
void push(int row, int col) {
    element e = {row, col};
    stack[++top] = e;
}

// 出栈操作
element pop() {
    return stack[top--];
}

// 判断堆栈是否为空
int is_empty() {
    return top == -1;
}

在我们开启搜索之前,我们需要将起点压入堆栈,并将起点标记为已访问:

// 标记已访问
int visited[MAX_ROW][MAX_COL] = {0};
visited[start_row][start_col] = 1;

// 将起点入栈
push(start_row, start_col);

接下来,我们需要编写一个函数来搜索迷宫。这个函数的任务是,从堆栈中取出一个节点,检查它是否是终点,如果不是,则检查它的四个相邻节点是否可以访问。如果可以访问,则将这个节点压入堆栈,并标记为已访问。

如果堆栈为空,说明我们已经走到了迷宫的边缘,但是没有找到终点。这个时候,我们需要返回 0,表示没有找到出路。

int search() {
    while (!is_empty()) {
        element e = pop();

        // 判断是否到达终点
        if (e.row == end_row && e.col == end_col) {
            printf("(%d, %d)\n", e.row, e.col);
            return 1;
        }

        // 取出当前节点的四个相邻节点,如果可以访问,则入栈
        if (e.row - 1 >= 0 && maze[e.row - 1][e.col] == 0 && !visited[e.row - 1][e.col]) {
            element adj = {e.row - 1, e.col};
            push(adj.row, adj.col);
            visited[adj.row][adj.col] = 1;
        }
        if (e.col - 1 >= 0 && maze[e.row][e.col - 1] == 0 && !visited[e.row][e.col - 1]) {
            element adj = {e.row, e.col - 1};
            push(adj.row, adj.col);
            visited[adj.row][adj.col] = 1;
        }
        if (e.row + 1 < MAX_ROW && maze[e.row + 1][e.col] == 0 && !visited[e.row + 1][e.col]) {
            element adj = {e.row + 1, e.col};
            push(adj.row, adj.col);
            visited[adj.row][adj.col] = 1;
        }
        if (e.col + 1 < MAX_COL && maze[e.row][e.col + 1] == 0 && !visited[e.row][e.col + 1]) {
            element adj = {e.row, e.col + 1};
            push(adj.row, adj.col);
            visited[adj.row][adj.col] = 1;
        }

        printf("(%d, %d)\n", e.row, e.col);
    }
    return 0;
}

最后,我们只需要在主函数中调用 search 函数即可:

int main() {
    if (search()) {
        printf("找到了出路\n");
    } else {
        printf("没有出路\n");
    }
    return 0;
}

示例说明

假设我们要在以下这个迷宫中寻找一条从起点 (1, 1) 到终点 (4, 4) 的路径:

1 1 1 1 1
1 0 0 0 1
1 1 0 0 1
1 0 0 0 1
1 1 1 1 1

我们可以使用上面的代码进行搜索,得到的输出为:

(1, 1)
(2, 1)
(3, 1)
(4, 1)
(4, 2)
(4, 3)
(3, 3)
(2, 3)
(1, 3)
(1, 2)
(2, 2)
(3, 2)
(4, 4)
找到了出路

说明我们已经成功找到了一条从起点到终点的路径。

再举一个例子,假设我们要在以下这个迷宫中寻找一条从起点 (1, 1) 到终点 (5, 5) 的路径:

1 1 1 1 1 1
1 0 1 0 0 1
1 0 1 0 1 1
1 0 1 0 0 1
1 0 0 0 1 1
1 1 1 1 1 1

我们可以使用上面的代码进行搜索,得到的输出为:

(1, 1)
(2, 1)
(3, 1)
(4, 1)
(4, 2)
(4, 3)
(4, 4)
(5, 4)
(5, 5)
找到了出路

说明我们已经成功找到了一条从起点到终点的路径。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:C语言使用深度优先搜索算法解决迷宫问题(堆栈) - Python技术站

(0)
上一篇 2023年5月22日
下一篇 2023年5月22日

相关文章

  • 浅析C++内存布局

    浅析C++内存布局 C++是一门面向过程的编程语言,与其他编程语言一样,C++也有自己的内存布局。 内存布局基本概念 堆 使用new或malloc操作后存放动态分配的数据的区域。 栈 用于存放程序运行时的函数栈帧,栈帧将在函数执行完后自行清除。 全局变量区 在程序运行前就分配好的存放全局变量的区域,该区域分为静态区和可读写区。 常量区 存放程序中常量的区域,…

    C 2023年5月22日
    00
  • VSCode各语言运行环境配置方法示例详解

    下面我会为你详细讲解 “VSCode各语言运行环境配置方法示例详解”的完整攻略。 概述 在使用 Visual Studio Code 进行编程开发时,不同的语言需要不同的运行环境。本篇攻略将会详细讲解如何配置 VSCode 的运行环境。 步骤 步骤一:安装与配置相应的编程语言环境 首先确定你需要使用的编程语言,然后安装相应的运行环境。以 Node.js 为例…

    C 2023年5月23日
    00
  • 手机版CCleaner怎么卸载软件应用程序

    下面是详细讲解“手机版CCleaner怎么卸载软件应用程序”的完整攻略: CCleaner简介 CCleaner是一款著名的系统清理与优化软件,其拥有较高的用户口碑。除去PC版本之外,CCleaner还在移动端推出了相应清理软件,广受用户好评。CCleaner安装在手机上后,它可以帮助用户管理手机存储空间,清理垃圾数据,优化手机性能。但有时,当用户不再需要某…

    C 2023年5月23日
    00
  • C语言实现的猜数字小游戏

    C语言实现的猜数字小游戏攻略 游戏规则 系统会在1~100之间随机生成一个整数,玩家需要猜测这个数字是多少。 玩家每次输入一个数字,系统会告诉玩家猜的数字是否正确,如果不正确,还会告诉玩家猜测的数字是偏大还是偏小。 玩家可以根据系统的提示,逐步缩小猜测范围,直到猜中为止。 玩家最多可以猜测7次,如果7次内未能猜中,游戏结束。 游戏实现步骤 首先需要生成一个1…

    C 2023年5月23日
    00
  • C++浅析析构函数的特征

    C++浅析析构函数的特征 在C++中,析构函数是一个类的特殊成员函数。它是在对象被销毁时调用的,用于清理对象的资源。析构函数的特征由以下几个方面组成。 析构函数的命名 析构函数的命名与类名相同,但它在前面加上一个波浪号(~)。例如,如果类名为MyClass,那么析构函数的命名应为~MyClass()。 析构函数的返回类型 析构函数没有返回值,它的返回类型必须…

    C 2023年5月22日
    00
  • 微信小程序使用uni-app开发小程序及部分功能实现详解

    微信小程序使用uni-app开发小程序及部分功能实现详解 一、uni-app简介 uni-app是DCloud提供的一款跨平台开发框架,可以通过一套代码在不同平台上运行(H5、小程序、APP)。该框架采用Vue.js作为前端开发框架,并提供了一系列的API和插件,让程序开发更加简单。 二、微信小程序使用uni-app开发 1. 安装uni-app 在命令行工…

    C 2023年5月23日
    00
  • C++利用多态实现职工管理系统(项目开发)

    C++利用多态实现职工管理系统(项目开发)攻略 介绍 在本项目中,我们将使用C++多态机制来实现一个职工管理系统。对于不同类型的职工,我们将采用不同的数据结构进行存储。并且我们将使用纯虚函数和虚函数来实现基类和派生类之间的协作和交互,使得职工管理系统具有良好的扩展性和可维护性。 开发步骤 确定项目需求和功能 在开发项目之前,我们需要确定项目的需求和功能,这可…

    C 2023年5月23日
    00
  • C语言实现扫雷经典游戏

    C语言实现扫雷经典游戏攻略 概述 扫雷经典游戏是一种利用逻辑推理完成的益智游戏。本攻略将详细讲解如何使用C语言实现扫雷经典游戏。 准备工作 在开始编写代码前,需要安装C语言编译器。常用的C语言编译器有GCC、Clang等,可根据自己的喜好选择。此外,还需要使用到C语言中的标准库函数,如rand()、time()等,需要确保它们的头文件stdlib.h和tim…

    C 2023年5月23日
    00
合作推广
合作推广
分享本页
返回顶部