迷宫问题实验报告用栈解决迷宫问题
- 格式:docx
- 大小:77.66 KB
- 文档页数:12
一、实验目的1. 了解回溯法在求解迷宫问题中的应用。
2. 进一步掌握栈、队列等数据结构在解决实际问题中的应用。
3. 提高编程能力,锻炼逻辑思维能力。
二、实验环境1. 操作系统:Windows 102. 编程语言:C++3. 开发环境:Visual Studio 2019三、实验内容1. 迷宫问题概述迷宫问题是指寻找从迷宫入口到出口的路径,且路径上不能有障碍物。
迷宫问题在计算机科学中具有广泛的应用,如路径规划、图论等。
2. 迷宫表示方法迷宫可以用二维数组表示,其中0表示通路,1表示障碍。
例如,以下迷宫可以用以下二维数组表示:```0 1 0 0 10 1 0 1 00 0 0 0 01 1 1 1 00 0 0 0 0```3. 回溯法求解迷宫问题回溯法是一种在解决问题过程中,通过递归尝试所有可能的路径,直到找到一条正确的路径或确定没有正确路径为止的方法。
4. 实验步骤(1)定义迷宫:创建一个二维数组表示迷宫,初始化为通路(0)和障碍(1)。
(2)初始化栈:创建一个栈,用于存储当前路径。
(3)从入口开始,按照上、下、左、右的顺序探索迷宫,每次探索前,将当前位置压入栈中。
(4)判断当前位置是否为出口,如果是,则输出路径并结束程序;如果不是,继续探索。
(5)如果当前位置为障碍或已访问过,则回溯到上一个位置,继续探索其他路径。
(6)重复步骤(3)至(5),直到找到一条从入口到出口的路径或确定没有正确路径为止。
5. 实验结果通过实验,成功实现了使用回溯法求解迷宫问题,并输出了一条从入口到出口的路径。
四、实验分析1. 时间复杂度分析在迷宫中,每个位置最多被访问一次,因此,时间复杂度为O(mn),其中m和n分别为迷宫的长和宽。
2. 空间复杂度分析实验中使用了栈来存储路径,栈的最大深度为迷宫的宽度,因此,空间复杂度为O(n)。
五、实验总结通过本次实验,我对回溯法在求解迷宫问题中的应用有了更深入的了解,同时也提高了编程能力和逻辑思维能力。
第1篇一、实验背景迷宫探路系统是一个经典的计算机科学问题,它涉及到算法设计、数据结构以及问题求解等多个方面。
本实验旨在通过设计和实现一个迷宫探路系统,让学生熟悉并掌握迷宫问题的求解方法,提高算法实现能力。
二、实验目的1. 理解迷宫问题的基本概念和求解方法。
2. 掌握深度优先搜索(DFS)和广度优先搜索(BFS)算法的原理和实现。
3. 了解A搜索算法的基本原理,并能够实现该算法解决迷宫问题。
4. 学会使用数据结构如栈、队列等来辅助迷宫问题的求解。
三、实验原理迷宫问题可以通过多种算法来解决,以下为三种常用的算法:1. 深度优先搜索(DFS):DFS算法通过递归的方式,沿着一条路径深入搜索,直到遇到死胡同,然后回溯并尝试新的路径。
DFS算法适用于迷宫的深度较深,宽度较窄的情况。
2. 广度优先搜索(BFS):BFS算法通过队列实现,每次从队列中取出一个节点,然后将其所有未访问过的邻接节点加入队列。
BFS算法适用于迷宫的宽度较宽,深度较浅的情况。
3. A搜索算法:A算法结合了DFS和BFS的优点,通过估价函数f(n) = g(n) +h(n)来评估每个节点的优先级,其中g(n)是从起始点到当前节点的实际代价,h(n)是从当前节点到目标节点的预估代价。
A算法通常能够找到最短路径。
四、实验内容1. 迷宫表示:使用二维数组表示迷宫,其中0表示通路,1表示障碍。
2. DFS算法实现:- 使用栈来存储路径。
- 访问每个节点,将其标记为已访问。
- 如果访问到出口,输出路径。
- 如果未访问到出口,回溯到上一个节点,并尝试新的路径。
3. BFS算法实现:- 使用队列来存储待访问的节点。
- 按顺序访问队列中的节点,将其标记为已访问。
- 将其所有未访问过的邻接节点加入队列。
- 如果访问到出口,输出路径。
4. A算法实现:- 使用优先队列来存储待访问的节点,按照f(n)的值进行排序。
- 访问优先队列中的节点,将其标记为已访问。
数据结构-迷宫实验报告数据结构-迷宫实验报告1.引言1.1 背景迷宫是一个有趣又具有挑战性的问题,它可以用于测试和评估不同的搜索算法和数据结构。
在这个实验报告中,我们将使用不同的数据结构和算法来解决迷宫问题。
1.2 目的本实验的目的是比较使用不同数据结构和算法解决迷宫问题的效率和性能。
我们将尝试使用栈、队列和递归等方法进行迷宫的搜索。
2.方法2.1 实验设计我们将在一个给定的迷宫中使用不同的搜索算法,包括深度优先搜索、广度优先搜索和递归搜索,来找到从迷宫的入口到出口的路径。
我们还将使用栈和队列数据结构来实现这些搜索算法。
2.2 实验步骤1) 定义迷宫的结构,并初始化迷宫的入口和出口。
2) 使用深度优先搜索算法找到迷宫中的路径。
3) 使用广度优先搜索算法找到迷宫中的路径。
4) 使用递归算法找到迷宫中的路径。
5) 比较不同算法的性能和效率。
6) 记录实验结果并进行分析。
3.结果与分析3.1 实验结果在我们的实验中,我们使用了一个10x10的迷宫进行测试。
我们比较了深度优先搜索、广度优先搜索和递归算法的性能。
深度优先搜索算法找到的最短路径长度为14步,搜索时间为0.15秒。
广度优先搜索算法找到的最短路径长度为14步,搜索时间为0.18秒。
递归算法找到的最短路径长度为14步,搜索时间为0.12秒。
3.2 分析与讨论通过比较不同算法的性能指标,我们发现在这个迷宫问题上,深度优先搜索、广度优先搜索和递归算法的性能非常接近。
它们在找到最短路径的长度和搜索时间上都没有明显差异。
4.结论与建议根据本次实验的结果,我们可以得出以下结论:●深度优先搜索、广度优先搜索和递归算法都可以成功解决迷宫问题。
●在这个具体的迷宫问题上,这些算法的性能差异不大。
在进一步研究和实验中,我们建议考虑更复杂的迷宫结构和更多的搜索算法,以探索它们在不同情况下的性能差异。
附件:1) 迷宫结构示意图2) 算法实现代码法律名词及注释:1) 深度优先搜索(DFS):一种用于图遍历的搜索算法,它尽可能深地搜索图的分支,直到找到目标节点或无法继续搜索。
一、实训背景与目的随着计算机技术的不断发展,数据结构作为计算机科学的基础课程,对于培养学生的逻辑思维能力和解决问题的能力具有重要意义。
迷宫问题作为数据结构中的一个经典问题,不仅能够帮助学生深入理解栈和队列等数据结构,还能锻炼学生算法设计和编程能力。
本次实训旨在通过解决迷宫问题,使学生更好地掌握数据结构的相关知识,并提高实际问题的解决能力。
二、迷宫问题的描述迷宫问题可以描述为:给定一个由二维数组表示的迷宫,其中0表示通路,1表示墙壁。
迷宫的入口位于左上角(0,0),出口位于右下角(m-1,n-1)。
要求设计一个程序,找到一条从入口到出口的路径,如果不存在路径,则输出“无路可通”。
三、解决方案为了解决迷宫问题,我们采用了以下方案:1. 数据结构选择:选择栈作为主要的数据结构,用于存储路径上的节点,以便在回溯过程中找到正确的路径。
2. 算法设计:- 初始化栈,将入口节点压入栈中。
- 循环判断栈是否为空:- 如果栈为空,则表示没有找到路径,输出“无路可通”。
- 如果栈不为空,则从栈中弹出一个节点,判断其是否为出口节点:- 如果是出口节点,则输出路径并结束程序。
- 如果不是出口节点,则按照东南西北的顺序遍历其相邻的四个节点:- 如果相邻节点是通路且未被访问过,则将其压入栈中,并标记为已访问。
- 重复步骤2,直到找到出口或栈为空。
3. 迷宫的表示:使用二维数组表示迷宫,其中0表示通路,1表示墙壁。
四、程序实现以下是用C语言实现的迷宫问题解决方案:```c#include <stdio.h>#include <stdlib.h>#define MAX_SIZE 100typedef struct {int x, y;} Point;typedef struct {Point data[MAX_SIZE];int top;} Stack;void initStack(Stack s) {s->top = -1;}int isEmpty(Stack s) {return s->top == -1;}void push(Stack s, Point e) {if (s->top == MAX_SIZE - 1) {return;}s->data[++s->top] = e;}Point pop(Stack s) {if (isEmpty(s)) {Point p = {-1, -1};return p;}return s->data[s->top--];}int isExit(Point p, int m, int n) {return p.x == m - 1 && p.y == n - 1;}int isValid(int x, int y, int m, int n, int maze[][n], int visited[][n]) {return x >= 0 && x < m && y >= 0 && y < n && maze[x][y] == 0&& !visited[x][y];}void findPath(int maze[][n], int m, int n) {Stack s;initStack(&s);Point start = {0, 0};push(&s, start);int visited[m][n];for (int i = 0; i < m; i++) {for (int j = 0; j < n; j++) {visited[i][j] = 0;}}while (!isEmpty(&s)) {Point p = pop(&s);if (isExit(p, m, n)) {printf("找到路径:");while (!isEmpty(&s)) {p = pop(&s);printf("(%d, %d) ", p.x, p.y);}printf("\n");return;}int directions[4][2] = {{1, 0}, {0, 1}, {-1, 0}, {0, -1}}; for (int i = 0; i < 4; i++) {int nx = p.x + directions[i][0];int ny = p.y + directions[i][1];if (isValid(nx, ny, m, n, maze, visited)) {visited[nx][ny] = 1;push(&s, (Point){nx, ny});break;}}}printf("无路可通\n");}int main() {int m, n;printf("请输入迷宫的行数和列数:");scanf("%d %d", &m, &n);int maze[m][n];printf("请输入迷宫的布局(0表示通路,1表示墙壁):\n");for (int i = 0; i < m; i++) {for (int j = 0; j < n; j++) {scanf("%d", &maze[i][j]);}}findPath(maze, m, n);return 0;}```五、实训心得通过本次迷宫实训,我深刻体会到了数据结构在实际问题中的应用价值。
实验二:迷宫问题班级:姓名:学号:一、需求分析(1 )以二维数据Maze[m+2][n+2] 表示迷宫,其中:Maze[0][j] 和Maze[m+1][j](0<=j<=n+1)及Maze[i][0]和Maze[i][n+1](0<=i<=m+1)为添加一圈障碍。
数组中以元素值为0 表示通路,1 表示障碍,限定迷宫的大小m,n<=100。
(2)用户输入迷宫的规模m,n;并按照此规模输入迷宫的具体数据。
(3)迷宫的入口位置和出口位置可由用户随时设定。
(4)若设定的迷宫存在通路,则以长方阵形式将迷宫及其通路输出到标准输出文件(即终端)上,其中,字符“#”表示障碍,字符“*”表示路径上的位置,字符“@”表示“死胡同”,即曾途径然而不能到达出口的位置,余者用空格符印出。
若设定的迷宫不存在通路,则报告相应信息。
(5)本程序只求出一条成功的通路。
然而,只需要对迷宫求解的函数作小量修改,便可求得全部路径。
(6)测试数据见原题,当入口位置为(1,1),出口位置为(9,8)时,输出数据应为:* * # @ @ @ #* # @ @ @ #* * @ @ # # #* # # # # @* * * # * * * @# * * * # * ## # # # * ## # # * ## # * *(7)程序执行的命令为:1)创建迷宫;2)求解迷宫;3)输出迷宫的解。
二、概要设计1. 设定栈的抽象数据类型定义:ADT Stack{数据对象:D={a i|a i∈CharSet,i=1,2,…,n,n>=0}数据关系:R1={<a i-1,a i>|a i-1,a i∈D,i=2,…,n}基本操作:InitStack(&S)操作结果:构造一个空栈S。
DestroyStack(&S)初始条件:栈S 已存在。
操作结果:销毁栈S。
ClearStack(&S)初始条件:栈S 已存在。
数据结构实验报告实验名称:实验二——利用栈结构实现迷宫求解问题学生姓名:班级:班内序号:学号:日期:2012年11月19日一、实验目的1、进一步掌握指针、模板类、异常处理的使用2、掌握栈的操作的实现方法3、掌握队列的操作的实现方法4、学习使用栈解决实际问题的能力5、学习使用队列解决实际问题的能力二、实验要求:利用栈结构实现迷宫求解问题。
迷宫求解问题如下:心理学家把一只老鼠从一个无顶盖的大盒子的入口赶进迷宫,迷宫中设置很多隔壁,对前进方向形成了多处障碍,心理学家在迷宫的唯一出口放置了一块奶酪,吸引老鼠在迷宫中寻找通路以到达出口,测试算法的迷宫如下图所示。
提示:1、可以使用递归或非递归两种方法实现2、老鼠能够记住已经走过的路,不会反复走重复的路径3、可以自己任意设置迷宫的大小和障碍4、使用“穷举求解”的方法三、程序分析1、存储结构栈存储结构;示意图;2、关键算法分析A、绘制迷宫;伪代码:1、输出迷宫的大小及全部设置为障碍;2、根据键盘的输入绘制迷宫的路线,起始点和终点;void draw()//绘制迷宫障碍{k=getch();switch(int(k)){case 105://上if(by>5){by--;j--;}break;case 107://下if(by<M+4){by++;j++;}break;case 106://左if(bx>2){bx=bx-2;i--;}break;case 108://右if(bx<2*N){bx=bx+2;i++;}break;case 114://'R'路map[i][j]=0;cout<<".";break;case 119://'W'墙map[i][j]=-3;cout<<"■";break;case 115://'S'起点s[0].x=i;//起点入栈s[0].y=j;top=1;map[i][j]=-1;cout<<k;break;case 101://'E'终点map[i][j]=-2;cout<<k;break;}gotoxy(bx,by);}B、路径寻找伪代码;1、向某一方向查找是否有路;2、如有遍历一下栈,看是否已经进栈,一进栈就舍弃,寻求下一个;无就让其进栈。
一、实验内容3、迷宫问题。
假设迷宫由m行n列构成,有一个出口和一个入口,入口坐标为(1,1),出口坐标为(m,n),试设计并验证以下算法:找出一条从入口通往出口的路径,或报告一个“无法通过”的信息。
(1)用C语言实现顺序存储队列上的基本操作,然后利用该队列的基本操作找出迷宫的一条最短路径。
(2)设计一个二维数组MAZE[m+2][n+2]表示迷宫,数组元素为0表示该位置可以通过,数组元素为1表示该位置不可以通行。
MAZE[1][1]、MAZE[m][n]分别为迷宫的入口和出口。
(3)输入迷宫的大小m行和n列,动态生成二维数组;由随机数产生0或1,建立迷宫,注意m*n的迷宫需要进行扩展,扩展部分的元素设置为1,相当于在迷宫周围布上一圈不准通过的墙。
(4)要求输出模拟迷宫的二维数组;若存在最短路径,则有出口回溯到入口(出队列并利用栈实现),再打印从入口到出口的这条路径,例如(1,1),......,(i,j),......,(m,n);若没有路径,则打印“No path”。
(5)迷宫的任一位置(i,j)上均有八个可移动的方向,用二维数组Direction存放八个方向的位置偏移量。
Direction[8][2]={{0,1},{1,1},{0,-1},{-1,-1},{1,-1},{1,0},{-1,0},{-1,1}};(6)为避免出现原地踏步的情况需要标志已经通过的位置,采用一个标志数组MARK[m+2][n+2],初值均为0,在寻找路径的过程中,若通过了位置(i,j),则将MARK[i][j]置为1。
(7)为了记录查找过程中到达位置(i,j)及首次到达(i,j)的前一位置(i_pre,j_pre),需要记住前一位置(i_pre,j_pre)在队列中的序号pre,即队列中数据元素应该是一个三元组(i,j,pre)。
(8)搜索过程简单下:将入口MAZE[1][1]作为第一个出发点,依次在八个方向上搜索可通行的位置,将可通行位置(i,j,pre)入队,形成第一层新的出发点,然后依次出队,即对第一层中各个位置分别搜索它所在八个方向上的可通行位置,形成第二层新的出发点,...,如此进行下去,直至达到出口MAZE[m][n]或者迷宫所有位置都搜索完毕为止。
实验二栈在迷宫求解问题中的应用实验项目中文名称:栈在迷宫求解问题中的应用实验项目英文名称:Application of Stack for Solving MazeProblem实验学时:2 学时、实验目的1、掌握栈的综合应用。
2、掌握迷宫求解的基本算法。
、实验内容1、编写函数,构造一个栈;2、编写函数,实现压栈操作;3、编写函数,实现弹栈操作;4、编写函数,销毁一个栈;5、编写函数,求解迷宫;6、编写函数,展示迷宫的解路径;、设计概要1、核心数据结构1)数据类型:链栈2)定义方法:定义栈顶和栈底指针以及栈容量typedef struct sqstack{ ElemType *bottom;/* 栈不存在时值为NULL */ ElemType *top; /* 栈顶指针*/int stacksize ; /* 当前栈容量,以元素为单位*/ }SqStack ;3)链栈的结构示意图2、程序框架结构与流程图(1)程序模块:·迷宫生产模块:手动生成迷宫。
·判断结点存在:防止结点的重复访问。
·路径查找模块:实现通路的查找,返回一条通路。
·路径输出模块:实现路径以题意要求输出。
(2)程序框架图流程图:3、细节设计(1)坐标位置类型:typedef struct{ int row; // 迷宫中的行int col; // 的列}PosType;// 坐标 (2)迷宫类型:typedef struct{ int m,n;int arr[RANGE][RANGE];}MazeType; // 迷宫类型co void InitMaze(MazeType &maze, int a[][COL], int row, int l)\// 设置迷宫的初值,包括边缘一圈的值Bool MazePath(MazeType &maze,PosType start, PosType end) // 求解迷宫maze中,从入口start 到出口end 的一条路径// 若存在,则返回true ,否则返回false Void PrintMaze ( MazeTypemaze)我的手机2018/12/519:00:05// 将迷宫打印出来(3)栈类型:typedef struct{int step;// 当前位置在路径上的" 序号PosType seat; //当前的坐标位置DirectiveType di;// 往下一个坐标位置的方向}SElemType;// 栈的元素类型typedef struct{SElemType *base;SElemType *top; int stacksize;}SqStack;四、程序源代码#include<stdio.h> #include<stdlib.h>#define SIZE 20#define ERROR 0#define OK 1typedef struct{int row,col;}PosType;typedef struct{int ord;PosType seat;int di;} Elemtype;typedef int Statu;typedef struct stacknode{Elemtype data;struct stacknode* next;}SNode;typedef struct LinkStack{SNode *top, *bottom;}LinkStack;Statu LinkStackInit(LinkStack *S){ //这里编写代码,初始化链栈SNode *a;a=(SNode*)malloc(sizeof(SNode)); S->bottom=a;S->top=a;S->top->next=NULL; return OK;}Statu LinkStackEmpty(LinkStack S){return S.bottom == S.top ? OK:ERROR; }Statu LinkStackPop(LinkStack *S, Elemtype *e){ //这里编写代码,弹栈SNode *b; b=S->top->next; S->top->next=b->next; free(b);return 0;}Statu LinkStackPush(LinkStack *S,Elemtype e){ //这里编写代码,压栈SNode *a; a=(SNode*)malloc(sizeof(SNode)); a->next=S->top->next; a->data=e;S->top->next=a;return 0;Statu LinkStackDestroy(LinkStack *S){ //这里编写代码,销毁栈SNode *a;a=(SNode*)malloc(sizeof(SNode)); while(S->top!=NULL){ a=S->top; S->top=S->top->next; free(a);} return 0;}Statu readmaze(char map[SIZE][SIZE], int *row, int *col){ int i,j; FILE *fp;fp = fopen("maze.txt","r"); fscanf(fp,"%d%*c",row); fscanf(fp,"%d%*c",col);for(i = 0; i < *row; i++){ for(j = 0; j < *col; j++){ map[i][j] = fgetc(fp);} fgetc(fp);} fclose(fp); return OK;}void showmap(char map[SIZE][SIZE], int row, int col){ int i,j;for(i = 0; i < row; i++){ for(j = 0; j<col; j++){ printf("%c ",map[i][j]);} printf("\n");}}void showpath(LinkStack path){ //这里编写代码,输出走出迷宫的路径int i,j,tag;char m[SIZE][SIZE];int row1,col1;FILE *fp1;fp1 = fopen("maze.txt","r");fscanf(fp1,"%d%*c",&row1); fscanf(fp1,"%d%*c",&col1);for(i = 0; i < row1; i++){for(j = 0; j < col1; j++){m[i][j] = fgetc(fp1);}fgetc(fp1);}fclose(fp1);SNode *c;for(i = 0; i < row1; i++){for(j = 0; j<col1; j++){c=path.top->next->next;tag=0;while(c!=NULL){ if(c->data.seat.row==i&&c->data.seat.col==j) {if(c->data.di==1)printf(" ↓ ");if(c->data.di==2) printf(" → ");if(c->data.di==3) printf(" ↑ ");if(c->data.di==4)printf(" ← ");tag=1;break;}elsec=c->next;}if(tag==0)printf("%c ",m[i][j]);}printf("\n");}Statu MazePath(char map[SIZE][SIZE], PosType start, PosType end, LinkStack *path){ //这里编写代码,求解迷宫。
数据结构实验报告题目:用栈解决迷宫问题.需求分析1.以结构体 Maze 表示迷宫,其中 pos 表示该位置是否有障碍; freq 记录该位置被经过的次数;数组 move 表示下一步的方向。
2. 本程序自动随机生成一个12 × 12大小的迷宫,字符“ H”表示有障碍,空符表示通路。
3. 迷宫的入口为左上角,出口为右下角。
4. 本程序只求出一条成功的通路。
.概要设计为了实现上述操作,以栈为存储结构。
本程序包含三个模块:1)主程序模块 :实现人机交互。
2)迷宫生产模块:随机产生一个12× 12的迷宫。
3)路径查找模块:实现通路的查找。
4)求解迷宫中一条通路的伪代码:do{若当前位置可同,则{将当前位置插入栈顶;若该位置是出口位置,则结束;否则切换当前位置的东临方块为新的当前位置;} 否则 {若栈不空且栈顶位置尚有其他方向未被探索,则设定新的的当前位置为沿顺时针方向旋转找到的栈顶位置的下一相邻块若栈不空但栈顶位置的四周均不可通,则{删去栈顶位置;若栈不空,则重新测试新的栈顶位置,直至找到一个可通的相邻块或出栈至栈空。
} }} while( 栈不空 )三. 详细设计栈的设计: typedef struct { Node *base,*top; int length; }Stack;Stack *initstack(); // 初始化栈 void printstack(Stack *s); // 打印栈Status destroy(Stack *); // 销毁整个栈Status deltop(Stack *s); // 出栈Status pushelem(Stack *,ElemType ,ElemType); // 进栈1. 主程序模块:int main(){printf(" 随机产生一个12× 12 的迷宫, X 字符表示障碍,空符表示通路:\n");Maze a[N][N];makemaze(a);printf(" 输入回车键显示路径 ,* 字符表示路径。
\n"); getchar();findpath(a); while(1); return 0;}2. 迷宫生产模块;void makemaze(Maze (*p)[N]){int i,j,conter; for(i=0;i<N;++i) for(j=0;j<N;++j) {(*(p+i)+j)->pos=0;(*(p+i)+j)->freq=0;(*(p+i)+j)->move[0]=0;(*(p+i)+j)->move[1]=0;(*(p+i)+j)->move[2]=0;(*(p+i)+j)->move[3]=0;}for(j=0;j<N;++j){(*p+j)->pos='X';(*(p+N-1)+j)->pos='X';} for(i=1;i<N-1;++i){(*(p+i))->pos='X'; (*(p+i)+N-1)->pos='X';} srand((int)time(NULL));for(conter=0;conter<20;++conter){i=rand()%(N-2);j=rand()%(N-2);(*(p+i)+j)->pos='X';if(i==1&&j==1||i==N-1&&j==N-1) { (*(p+i)+j)->pos=0;}}printmaze(p);}3. 路径查找模块。
Maze *testnewpos(Maze (*p)[N],Stack *s,int *i,int *j){Maze *q=NULL;int select=0;*i=*j=0;for(;q==NULL&&select<4;++select)// 在可行的方向上只选一个{switch(select){case 0:if( (*(p+s->top->x)+s->top->y)->move[0]!=1 ){(*(p+s->top->x)+s->top->y)->move[0]=1;q=*(p+s->top->x)+s->top->y+1;*i=s->top->x+0;*j=s->top->y+1;}// 退回前一步检查东方向是否可通break;case 1:if( (*(p+s->top->x)+s->top->y)->move[1]!=1 ){(*(p+s->top->x)+s->top->y)->move[1]=1;q=*(p+s->top->x+1)+s->top->y;*i=s->top->x+1;*j=s->top->y+0;}// 退回前一步检查南方向是否可通break;case 2:if( (*(p+s->top->x)+s->top->y)->move[2]!=1 ){(*(p+s->top->x)+s->top->y)->move[2]=1; q=*(p+s->top->x)+s->top->y-1; *i=s->top->x+0;*j=s->top->y-1;}// 退回前一步检查西方向是否可通 break;case 3:if( (*(p+s->top->x)+s->top->y)->move[3]!=1 ) {(*(p+s->top->x)+s->top->y)->move[3]=1; q=*(p+s->top->x-1)+s->top->y;*i=s->top->x-1;*j=s->top->y+0;}// 退回前一步检查北方向是否可通}}return q;}void printpath(Stack *s,Maze (*p)[N]){Node *n; int i,j,conter; conter=0; n=s->base; for(;n;n=n->next) {(*(p+n->x)+n->y)->pos='*';} for(i=0;i<N;++i) for(j=0;j<N;++j){++conter; printf(FORMAT,(*(p+i)+j)->pos); if(conter%12==0) TURNLINE;}TURNLINE;} 完整的程序: maze.h #ifndef MAZE_H #define MAZE_H #include "mazepath.h" #include <time.h>#define N 12//10+2#define FORMAT "%2c"#define TURNLINE printf("\n")typedef struct{char pos;int freq;int move[4];}Maze;void makemaze(Maze (*p)[N]);void printmaze(Maze (*p)[N]);void findpath(Maze (*p)[N]);Maze *testnewpos(Maze (*p)[N],Stack *,int *,int *); void printpath(Stack *s,Maze (*p)[N]);void makemaze(Maze (*p)[N]){int i,j,conter;for(i=0;i<N;++i)for(j=0;j<N;++j){(*(p+i)+j)->pos=0;(*(p+i)+j)->freq=0;(*(p+i)+j)->move[0]=0;(*(p+i)+j)->move[1]=0;(*(p+i)+j)->move[2]=0;(*(p+i)+j)->move[3]=0;}for(j=0;j<N;++j){(*p+j)->pos='X';(*(p+N-1)+j)->pos='X';}for(i=1;i<N-1;++i){(*(p+i))->pos='X';(*(p+i)+N-1)->pos='X';}srand((int)time(NULL));for(conter=0;conter<20;++conter) {i=rand()%(N-2);j=rand()%(N-2);(*(p+i)+j)->pos='X';if(i==1&&j==1||i==N-1&&j==N-1) {(*(p+i)+j)->pos=0;}}printmaze(p);}void printmaze(Maze (*p)[N]){int i,j,conter;conter=0;for(i=0;i<N;++i)for(j=0;j<N;++j){++conter;printf(FORMAT,(*(p+i)+j)->pos); if(conter%12==0) TURNLINE;}TURNLINE;}void findpath(Maze (*p)[N]){Maze *q=NULL;int i=1,j=1,*pi=&i,*pj=&j,success=0;Stack *s;s=initstack();// 初始化用来存储路径的栈q=*(p+1)+1;// 初始化当前位置为入口位置do{if(q->pos!='X'&&!(q->freq))// 当前位置通且在当前路径中未被访问过,则入栈{if(i==N-2&&j==N-2){pushelem(s,N-2,N-2);success=1;}else if(i==1&&j==1)pushelem(s,i,j);q->freq=1;// 当前位置已经进栈,作标记,不能再入栈,不然就只能兜死胡同了q->move[0]=1;// 切换下一位置为东邻位置 , 并做标记,东邻位置已经使用i=s->top->x+0;j=s->top->y+1;q=*(p+i)+j;}else{pushelem(s,i,j);q->freq=1;q=*(p+i)+j;}}else// 当前位置不通,则在前一步 ( 栈顶 ) 检查是否有其他方向可行{//printf("step here...");if(s->base!=s->top){do// 查找新的通路直到新通路出现或者回到初始位置{{q=testnewpos(p,s,&i,&j);// 返回其它三个方向的其中一个和新的当前位置的坐标if(q==NULL) deltop(s);// 栈顶没有可继续往下走的通路,删除栈顶,在新的栈顶找}while(q==NULL&&s->base!=s->top);}}}while(success!=1);printpath(s,p);}Maze *testnewpos(Maze (*p)[N],Stack *s,int *i,int *j){Maze *q=NULL;int select=0;*i=*j=0;for(;q==NULL&&select<4;++select)// 在可行的方向上只选一个{switch(select){case 0:if( (*(p+s->top->x)+s->top->y)->move[0]!=1 ){(*(p+s->top->x)+s->top->y)->move[0]=1; q=*(p+s->top->x)+s->top->y+1;*i=s->top->x+0;*j=s->top->y+1;}// 退回前一步检查东方向是否可通break;case 1:if( (*(p+s->top->x)+s->top->y)->move[1]!=1 ){(*(p+s->top->x)+s->top->y)->move[1]=1; q=*(p+s->top->x+1)+s->top->y;*i=s->top->x+1;*j=s->top->y+0;}// 退回前一步检查南方向是否可通break;case 2:if( (*(p+s->top->x)+s->top->y)->move[2]!=1 ){(*(p+s->top->x)+s->top->y)->move[2]=1; q=*(p+s->top->x)+s->top->y-1;*i=s->top->x+0;*j=s->top->y-1;}// 退回前一步检查西方向是否可通break;case 3:if( (*(p+s->top->x)+s->top->y)->move[3]!=1 ){(*(p+s->top->x)+s->top->y)->move[3]=1; q=*(p+s->top->x-1)+s->top->y;*i=s->top->x-1;*j=s->top->y+0;}// 退回前一步检查北方向是否可通}} return q;}void printpath(Stack *s,Maze (*p)[N]) {Node *n; int i,j,conter; conter=0; n=s->base; for(;n;n=n->next) {(*(p+n->x)+n->y)->pos='*';} for(i=0;i<N;++i) for(j=0;j<N;++j) { ++conter; printf(FORMAT,(*(p+i)+j)->pos);if(conter%12==0) TURNLINE;}TURNLINE;}#endif mazepath.h #ifndef MAZEPATH_H #define MAZEPATH_H#include<stdio.h> #include<stdlib.h> #define TRUE 1 #define FALSE 0 #define OK 1 #define ERROR 0 #define INFEASIBLE -1 #define OVERFLOW -2 typedef int ElemType; typedef int Status;typedef struct node {ElemType x;ElemType y; struct node *next;struct node *prior;}Node,*Postion; typedefstruct {Node *base,*top;int length;}Stack;Stack *initstack();//初始化栈void printstack(Stack *s);//打印栈Status destroy(Stack *);//销毁整个栈Status deltop(Stack *s);//出栈Status pushelem(Stack *,ElemType ,ElemType); //进栈Stack *initstack(){Stack *s;s=(Stack *)malloc(sizeof(Stack));if(!s) return ERROR; s->base=s->top=NULL; // 栈空 s->length=0;return s;}void printstack(Stack *s){Node *N;N=s->base;for(;N;N=N->next){printf("%2d %2d ",N->x,N->y);}printf("\n\n");}Status destroy(Stack *s){Node *p; p=s->base;while(s->base->next){s->base=s->base->next; //N=N->next 和 free(P) 不能倒换位置,当释放free(p); // 如果不将 N 移向下一个位置,将导致 N 指向的内存释放,不再有效p=s->base;} s->base=s->top=NULL;s->length=0;return OK;}Status deltop(Stack *s)p 时,N->next{Node *p; if(!s->length)printf("Underflow\n"); // 已经是空栈 else{p=s->top; s->top=p->prior;free(p);--s->length;s->top->next=NULL;} return OK;}Status pushelem(Stack *s,ElemType i,ElemType j) {Node *n;n=(Node *)malloc(sizeof(Node));if(!n) return ERROR; n->x=i;n->y=j ; if(s->length==0){ s->base=s->top=n; n->prior=NULL;}else{ n->prior=s->top;s->top->next=n; s->top=n;} n->next=NULL;++s->length;return OK;}#en difMyMai n.cpp#i nclude "maze.h"int mai n(){Printf(" 随机产生一个12× 12的迷宫,X字符表示障碍,空符表示通路:∖n"); MaZe a[N][N];makemaze(a);Printf(" 输入回车键显示路径:字符表示路径。