第11周 【项目5 - 迷宫问题之图深度优先遍历解法】
发布日期:2021-05-24 13:03:22 浏览次数:12 分类:精选文章

本文共 3646 字,大约阅读时间需要 12 分钟。

迷宫问题之深度优先遍历解法

将每一格作为顶点,相邻格子可达则存在边相连。迷宫对应的图结构通过邻接表表示。


邻接表结构

迷宫被转换为一个邻接表:每个顶点存储其相邻顶点。例如,迷宫的对应邻接表如下:

int mg[M+2][N+2] = {    {1,1,1,1,1,1},    {1,0,0,0,1,1},    {1,0,1,0,0,1},    {1,0,0,0,1,1},    {1,1,0,0,0,1},    {1,1,1,1,1,1}  };  邻接表G的结构为:  - 每个顶点存储相邻的边。边的结点结构(ArcNode)包含相邻顶点的位置和指向下一条边的指针。

深度优先遍历算法

  • 思路:深度优先遍历通过递归来实现,从起点出发,尽可能沿着一条边走到底部或死胡同前,然后回溯,尝试另一条边。

递归函数:FindPath

  • 参数:邻接表G,起点(xi, yi),终点(xe, ye),路径记录器path。
  • 阶段:
  • 标记当前位置已访问。
  • 如果到达终点,记录路径并输出。
  • 遍历当前位置所有邻接边,若邻居未访问,递归访问。

初始设置

  • 起点为(1, 1),终点为(M, N)。
  • 路径记录器path初始化为空。

代码实现

#include 
#include
#define MaxSize 100#define M 5#define N 6typedef struct { int i, j; struct ANode *nextarc;} ANode;typedef struct { ANode *firstarc;} VNode;typedef struct { VNode adjlist[M+2][N+2];} ALGraph;typedef struct { int i, j;} Box;typedef struct { Box data[MaxSize]; int length;} PathType;int visited[M+2][N+2] = {0};int count = 0;void CreateList(ALGraph *G, int mg[M+2][N+2]) { G = (ALGraph *)malloc(sizeof(ALGraph)); for (int i = 0; i <= M+1; i++) for (int j = 0; j <= N+1; j++) G->adjlist[i][j].firstarc = NULL; for (int i = 1; i <= M; i++) { for (int j = 1; j <= N; j++) { if (mg[i][j] == 0) { int di = 0; while (di < 4) { switch(di) { case 0: i1 = i - 1; j1 = j; break; case 1: i1 = i; j1 = j + 1; break; case 2: i1 = i + 1; j1 = j; break; case 3: i1 = i; j1 = j - 1; break; } if (mg[i1][j1] == 0) { ANode *p = (ANode *)malloc(sizeof(ANode)); p->i = i1; p->j = j1; p->nextarc = G->adjlist[i][j].firstarc; G->adjlist[i][j].firstarc = p; } di++; } } } }}void DispAdj(ALGraph *G) { for (int i = 0; i <= M+1; i++) { for (int j = 0; j <= N+1; j++) { ANode *p = G->adjlist[i][j].firstarc; printf(" [%d,%d]: ", i, j); while (p) { printf("(%d,%d) ", p->i, p->j); p = p->nextarc; } printf("\n"); } }}void FindPath(ALGraph *G, int xi, int yi, int xe, int ye, PathType path) { if (xi == xe && yi == ye) { path.length++; path.data[path.length].i = xi; path.data[path.length].j = yi; return; } visited[xi][yi] = 1; path.data[path.length].i = xi; path.data[path.length].j = yi; path.length++; ANode *p = G->adjlist[xi][yi].firstarc; while (p) { if (visited[p->i][p->j] == 0) { FindPath(G, p->i, p->j, xe, ye, path); } p = p->nextarc; } visited[xi][yi] = 0;}int main() { ALGraph *G; int mg[M+2][N+2] = { {1,1,1,1,1,1}, {1,0,0,0,1,1}, {1,0,1,0,0,1}, {1,0,0,0,1,1}, {1,1,0,0,0,1}, {1,1,1,1,1,1} }; CreateList(G, mg); printf("迷宫对应的邻接表:\n"); DispAdj(G); PathType path; path.length = 0; printf("所有的迷宫路径:\n"); FindPath(G, 1, 1, 5, 6, path); return 0;}

测试与输出

程序运行后,输出迷宫的邻接表以及所有从(1,1)到(5,6)的路径。


扩展应用

可以修改迷宫尺寸M和N,或调整迷宫数组,测试不同迷宫的解。


通过该方法,可以系统地找出迷宫中的所有通路,适用于各种复杂路径的问题。

上一篇:第12周 【项目1 - 验证算法】
下一篇:第11周 【项目4 - 利用遍历思想求解图问题】

发表评论

最新留言

很好
[***.229.124.182]2025年04月25日 04时16分56秒