设计一个算法找一条从迷宫入口到出口的最短路径。_[数据结构实践项目]移动迷宫小游戏(升级版)...

本文介绍了如何设计算法寻找迷宫中从入口到出口的最短路径。通过将二维数组转化为图,利用迪杰斯特拉算法或广度优先搜索来解决问题。同时,文章探讨了广度优先搜索结合回溯法找出所有最短路径的可能性。
摘要由CSDN通过智能技术生成

在上一章的《移动迷宫》小游戏中,使用回溯法帮助骑士在迷宫中找到了通往出口的一条通路,但是骑士并不太满意,他又提出了更高的需求。《移动迷宫》升级版游戏简介:迷宫只有两个门,一个入口,一个出口。一个骑士骑马从入口走进迷宫,迷宫中设置有很多墙壁,对前进方向造成障碍。先需要你从迷宫中找到一条最短的通路,将行走路线和行走的最短距离告知骑士。

设计思路

类似于寻找最短路径这样的问题,最直接的方法就是使用迪杰斯特拉算法和弗洛伊德算法。两种算法面对的数据结构是图,但是迷宫是在二维数组中进行存储的,所以如果使用前面两种算法的话,需要首先将二维数组转化为图的存储形式。

二维数组转化成图

如下图所示,此为 3*3 迷宫:

e55f74c7448d77fb8d49fc14b46683e8.png图 1 移动迷宫

提示:S 为入口,E 为出口,# 为墙壁,- 为通路。

在编写程序向计算机中输入该迷宫的数据时,宜使用二维数组进行存储。但是无论是迪杰斯特拉算法还是弗洛伊德算法,其处理对象都是有向网或者无向网。迷宫中并不涉及到具体的方向,所以需要将存储迷宫的二维数组转化为无向网。无向网的存储方式也是用二维数组来实现,将迷宫中所有的顶点看作是图中的顶点,对于上图的迷宫来说,共有 9 个顶点,所以转化为无向网时,需要用 9*9 的一个二维数组来表示。在转化时,从迷宫的左上角(上图的 S 开始),一行一行的进行转化,对于每个顶点来说,只需要判断其右侧和相邻的下方顶点是否为通路,如果是通路,转化为图中的直接体现就是两顶点之间有线连接。例如,上图中的 S 其右侧和下方的顶点都是 - ,骑士可以通过,那在图中的表现就是 S 同其右侧顶点和下方顶点之间存储通路,如下图所示:

facd04cdf98c88bc46ae487d9ab19ea8.png 

对于图 1 中的二维数组,其完全转化为图,如下图所示(每个顶点用其二维数组中的坐标来表示,00 表示第 0 行第 0 列):

07f3613388c61c51772dbff1f5332261.png 

图 1 中的二维数组转化为图的存储表示如下图所示:

86491b531f83ea710060ae288a82ac00.png

提示:1 表示有通路,0 表示没有通路,# 由于表示墙壁,同其它任何顶点之间都没有通路。

迪杰斯特拉算法

使用迪杰斯特拉算法求迷宫的最短路径,其完整代码如下:

#include #define MAX_VERtEX_NUM 200              //顶点的最大个数#define VRType int                          //表示弧的权值的类型#define VertexType char                     //图中顶点的数据类型#define INFINITY 65535typedef enum{
    false,true} bool;typedef struct {
        VertexType vexs[MAX_VERtEX_NUM];        //存储图中顶点数据    VRType arcs[MAX_VERtEX_NUM][MAX_VERtEX_NUM];                         //二维数组,记录顶点之间的关系    int vexnum,arcnum;                      //记录图的顶点数和弧(边)数}MGraph;typedef int PathMatrix[MAX_VERtEX_NUM];     //用于存储最短路径中经过的顶点的下标typedef int ShortPathTable[MAX_VERtEX_NUM]; //用于存储各个最短路径的权值和//迪杰斯特拉算法,v0表示有向网中起始点所在数组中的下标void ShortestPath_Dijkstra(MGraph G,int v0,PathMatrix *p,ShortPathTable *D){
        int final[MAX_VERtEX_NUM];//用于存储各顶点是否已经确定最短路径的数组    //对各数组进行初始化    for (int v=0; v        final[v]=0;        (*D)[v]=G.arcs[v0][v];        (*p)[v]=0;    } 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值