利用栈实现迷宫地求解

合集下载

迷宫问题栈算法c++代码

迷宫问题栈算法c++代码

迷宫问题栈算法c++代码迷宫问题是一个经典的寻路问题,目标是从迷宫的入口找到出口的路径。

栈是一个常用的数据结构,可以用来实现迷宫问题的解决方法。

下面是使用栈算法解决迷宫问题的C++代码。

```cpp#include <iostream>#include <stack>#include <vector>using namespace std;// 定义迷宫的大小const int N = 5;const int M = 5;// 定义迷宫的地图,0 表示可通行的路径,1 表示墙壁int maze[N][M] = {{0, 1, 0, 0, 0},{0, 1, 0, 1, 0},{0, 0, 0, 0, 0},{0, 1, 1, 1, 0},{0, 0, 0, 1, 0}};// 定义方向数组,分别表示右、下、左、上四个方向移动int dx[] = {1, 0, -1, 0};int dy[] = {0, 1, 0, -1};// 定义迷宫中的点struct Point {int x, y;};// 判断某个点是否在迷宫内且可通行bool isValid(int x, int y) {return x >= 0 && x < N && y >= 0 && y < M && maze[x][y] == 0;}// 使用栈算法寻找迷宫路径vector<Point> findPath(int startX, int startY, int endX, int endY) {stack<Point> s;vector<Point> path;bool visited[N][M] = {false};// 将起点加入栈中s.push({startX, startY});visited[startX][startY] = true;while (!s.empty()) {// 获取栈顶点Point current = s.top();s.pop();// 判断是否到达终点if (current.x == endX && current.y == endY) { path.push_back(current);break;}// 遍历四个方向for (int i = 0; i < 4; i++) {int nextX = current.x + dx[i];int nextY = current.y + dy[i];// 判断下一个点是否合法且未访问过 if (isValid(nextX, nextY)&& !visited[nextX][nextY]) {s.push({nextX, nextY});visited[nextX][nextY] = true; }}// 如果栈为空,说明无法到达终点if (s.empty()) {cout << '无法找到路径!' << endl; return path;}}// 反向输出路径while (!s.empty()) {path.push_back(s.top());s.pop();}return path;}int main() {int startX, startY, endX, endY;cout << '请输入起点坐标(以空格分隔):';cin >> startX >> startY;cout << '请输入终点坐标(以空格分隔):';cin >> endX >> endY;vector<Point> path = findPath(startX, startY, endX, endY);if (!path.empty()) {cout << '找到路径!路径长度为:' << path.size() << endl; cout << '路径为:';for (int i = path.size() - 1; i >= 0; i--) {cout << '(' << path[i].x << ', ' << path[i].y << ')';if (i != 0) {cout << ' -> ';}}}return 0;}```以上代码通过栈算法实现了迷宫问题的解决方法。

用栈解决迷宫问题

用栈解决迷宫问题

⽤栈解决迷宫问题⼀、因为栈是后进先出的特性,所以说⼀般⽤栈都是通过dfs来解决迷宫问题。

如果⽤队列的话就是通过bfs来解决。

⼆、c++代码:1 #include<iostream>2 #include<cstdio>3 #include<stdio.h>4 #include<string.h>5 #include<windows.h>6using namespace std;7const int maxn=1005;8#define MaxSize 100005 //栈最多元素个数9int M=4,N=4;10int w[6][6]=11 {12 {1,1,1,1,1,1}13 ,{1,0,0,0,1,1}14 ,{1,0,1,0,0,1}15 ,{1,0,0,0,1,1}16 ,{1,1,0,0,0,1}17 ,{1,1,1,1,1,1}18 };19int mg[maxn][maxn];20char s[maxn][maxn];21struct migong22 {23int i; //路径横坐标24int j; //路径纵坐标25int di; //⽅向26 } Stack[MaxSize],Path[MaxSize]; //定义栈和存放最短路径的数组27int top=-1; //栈顶指针28int counts=1; //路径数计数29int minlen=MaxSize; //最短路径长度30void mgpath() //路径为:(1,1)->(M,N)31 {32int i,j,di,finds,k;33 top++;34 Stack[top].i=1;35 Stack[top].j=1;36 Stack[top].di=-1;37 mg[1][1]=-1; //初始结点进栈38while(top>-1) //栈不空时循环39 {40 i=Stack[top].i;41 j=Stack[top].j;42 di=Stack[top].di;43if(i==M && j==N) //找到了出⼝,输出路径44 {45// cout<<counts<<": ";46// counts++;47// for(k=0; k<=top; k++)48// {49// cout<<"("<<Stack[k].i<<","<<Stack[k].j<<")"<<" ";50//51// }52// cout<<endl;53if(top+1<minlen) //⽐较输出最短路径54 {55for(k=0; k<=top; k++)56 Path[k]=Stack[k];57 minlen=top+1;58 }59 mg[Stack[top].i][Stack[top].j]=0; //让该位置变为其他路径的可⾛结点60 top--;61 i=Stack[top].i;62 j=Stack[top].j;63 di=Stack[top].di;64 }65 finds=0;66while(di<4 && finds==0) //找下⼀个可⾛结点67 {68 di++;69switch(di)70 {71case0:72 i=Stack[top].i-1;73 j=Stack[top].j;74break; //上⾯75case1:76 i=Stack[top].i;77 j=Stack[top].j+1;78break; //右边79case2:80 i=Stack[top].i+1;82break; //下⾯83case3:84 i=Stack[top].i;85 j=Stack[top].j-1;86break; //左边87 }88if(mg[i][j]==0) //因为地图外边围了⼀层墙,所以不需要判断边界89 finds=1;90 }91if(finds == 1) //找到了下⼀个可⾛结点92 {93 Stack[top].di=di; //修改原栈顶元素的di值94 top++; //下⼀个可⾛结点进栈95 Stack[top].i=i;96 Stack[top].j=j;97 Stack[top].di=-1;98 mg[i][j]=-1; //避免重复⾛到该结点99 }100else101 {102 mg[Stack[top].i][Stack[top].j]=0; //让该位置变为其他路径的可⾛结点103 top--;104 }105 }106 cout<<"最短路径如下(输出结果以坐标显⽰)"<<endl;107 cout<<"长度: "<<minlen<<endl;108 cout<<"路径: "<<endl;109for(k=0; k<minlen; k++)110 {111 cout<<"("<<Path[k].i<<","<<Path[k].j<<")"<<"";112 }113 }114int main()115 {116int x;117while(1)118 {119 system("cls");120 printf ( " 迷宫系统 \n");121 printf ( " \n");122 printf ( " \n");123 printf ("-------------------------------------- \n");124 printf ("--------------------------------------\n");125 printf ("--------⼁[0]重构地图⼁---\n");126 printf ("--------⼁[1]使⽤默认地图⼁---\n");127 printf ("--------⼁[2]结束⼁---\n");128 printf ("----------输⼊相应数字----------------\n");129 printf ("--------------------------------------- \n");130 printf ( " \n");131 printf ( " \n");132 scanf("%d",&x);133if(x==0)134 {135 system("cls");136 printf(" 重构地图\n");137 printf("输⼊内容请以空格或者换⾏分隔开,且0代表此处可⾛,1代表此处不可⾏\n"); 138 printf("\n现在请输⼊地图是⼏⾏⼏列\n");139int n,m;140 memset(mg,0,sizeof(mg));141 scanf("%d%d",&n,&m);142int flag=0;143 printf("\n请输⼊地图,请保证左上⾓和右下⾓都为0\n");144for(int i=1; i<=n; ++i)145 {146147 scanf("%s",s[i]+1);148 mg[i][0]=mg[i][m+1]=1;149 }150for(int j=1; j<=m; ++j)151 {152 mg[0][j]=mg[n+1][j]=1;153 }154for(int i=1;i<=n;++i)155 {156for(int j=1;j<=m;++j)157 {158 mg[i][j]=s[i][j]-'0';159 }160 }161 M=n;162 N=m;163164//cout<<"迷宫所有路径如下:"<<endl;165 mgpath();166 system("pause");167 }168else if(x==1)169 {171 M=N=4;172for(int i=0; i<6; ++i) 173 {174for(int j=0; j<6; ++j) 175 {176 mg[i][j]=w[i][j]; 177 }178 }179 mgpath();180 system("pause"); 181 }182else break;183 }184return0;185 }View Code。

栈和队列的应用——迷宫问题(深度、广度优先搜索)

栈和队列的应用——迷宫问题(深度、广度优先搜索)

栈和队列的应⽤——迷宫问题(深度、⼴度优先搜索)⼀、迷宫问题 给⼀个⼆维列表,表⽰迷宫(0表⽰通道,1表⽰围墙)。

给出算法,求⼀条⾛出迷宫的路径。

maze = [[1,1,1,1,1,1,1,1,1,1],[1,0,0,1,0,0,0,1,0,1],[1,0,0,1,0,0,0,1,0,1],[1,0,0,0,0,1,1,0,0,1],[1,0,1,1,1,0,0,0,0,1],[1,0,0,0,1,0,0,0,0,1],[1,0,1,0,0,0,1,0,0,1],[1,0,1,1,1,0,1,1,0,1],[1,1,0,0,0,0,0,0,0,1],[1,1,1,1,1,1,1,1,1,1]] 1代表墙,0代表路,图⽰如下:⼆、栈——深度优先搜索 应⽤栈解决迷宫问题,叫做深度优先搜索(⼀条路⾛到⿊),也叫做回溯法。

1、⽤栈解决的思路 思路:从上⼀个节点开始,任意找下⼀个能⾛的点,当找不到能⾛的点时,退回上⼀个点寻找是否有其他⽅向的点。

使⽤栈存储当前路径。

后进先出,⽅便回退到上⼀个点。

2、⽤栈代码实现maze = [[1,1,1,1,1,1,1,1,1,1],[1,0,0,1,0,0,0,1,0,1],[1,0,0,1,0,0,0,1,0,1],[1,0,0,0,0,1,1,0,0,1],[1,0,1,1,1,0,0,0,0,1],[1,0,0,0,1,0,0,0,0,1],[1,0,1,0,0,0,1,0,0,1],[1,0,1,1,1,0,1,1,0,1],[1,1,0,0,0,0,0,0,0,1],[1,1,1,1,1,1,1,1,1,1]]# 四个移动⽅向dirs = [lambda x,y: (x+1, y), # 下lambda x,y: (x-1, y), # 上lambda x,y: (x, y-1), # 左lambda x,y: (x, y+1) # 右]def maze_path(x1, y1, x2, y2): # (x1,y1)代表起点;(x2,y2)代表终点stack = []stack.append((x1, y1))while(len(stack)>0):curNode = stack[-1] # 当前的节点(栈顶)if curNode[0] ==x2 and curNode[1] == y2: # 判断是否⾛到终点# ⾛到终点,遍历栈输出路线for p in stack:print(p)return True"""搜索四个⽅向"""for dir in dirs:nextNode = dir(curNode[0], curNode[1])# 如果下⼀个阶段能⾛if maze[nextNode[0]][nextNode[1]] == 0:stack.append(nextNode) # 将节点加⼊栈maze[nextNode[0]][nextNode[1]] = 2 # 将⾛过的这个节点标记为2表⽰已经⾛过了break # 找到⼀个能⾛的点就不再遍历四个⽅向else:# ⼀个都找不到,将该位置标记并该回退maze[nextNode[0]][nextNode[1]] = 2stack.pop()else:print("没有路")return Falsemaze_path(1,1,8,8)"""(1, 1) (2, 1) (3, 1) (4, 1) (5, 1) (5, 2) (5, 3) (6, 3) (6, 4)(6, 5) (7, 5) (8, 5) (8, 6) (8, 7) (8, 8)""" 总结算法就是:创建⼀个空栈,⾸先将⼊⼝位置进栈。

迷宫问题利用栈和队列求解(数据结构设计)

迷宫问题利用栈和队列求解(数据结构设计)
void Push(sqstack *s, Elemtype e)//入栈
{
if(s->top==max-1)
{printf("full");return;}
#include<stdio.h>
#include<stdlib.h>
#define M 6
#define N 8
#define max 100
#define Max M*N
typedef struct //定义迷宫内坐标类型
{
int x,y;
}item;
typedef struct //顺序栈元素
s->top++;
s->data[s->top].x=e.x;
s->data[s->top].y=e.y;
{
int x,y,d;//d 下一步方向
}Elemtype;
typedef struct node // 栈的类型定义
{
Elemtype data[max];
int top;
}sqstack;
typedef struct //队列的类型定义
{ int x,y;
int pre;
{1,1,1,1,1,1,1,1,1,1},
{1,0,1,1,1,0,1,1,1,1},
{1,1,0,1,0,1,1,1,1,1},
{1,0,1,0,0,0,0,0,1,1},
{1,0,1,1,1,0,1,1,1,1},
{1,1,0,0,1,1,0,0,0,1},
printf("请选择......\n");

《数据结构》上机实验报告—利用栈实现迷宫求解

《数据结构》上机实验报告—利用栈实现迷宫求解
typedef struct{
SElemType* base;//栈基址,构造前销毁后为空
SElemType* top;//栈顶
int stackSize; //栈容量
}Stack; //栈类型
Status InitStack(Stack &S){ //构造空栈s
S.base=(SElemType*)malloc(INIT_SIZE *sizeof(SElemType));
Stack S;
PostType curpos;
int curstep;//当前序号
SElemType e;
InitStack(S);
InitStack(Path);
curpos=start; //设置"当前位置"为"入口位置"
curstep=1; //探索第一步
do{
if(Pass(maze,curpos)){//当前位置可以通过,即是未曾走到过的通道
福州大学数计学院
《数据结构》上机实验报告
专业和班级:信息计算科学与应用数学6班
学号
姓名
成绩
实验名称
栈、队列
实验内容
利用栈实现迷宫求解







【实验目的】
应用栈结构来解决应用问题,加深对栈结构特点的认识和应用。
【基本要求】
首先实现一个以链表作存储结构的栈类型,然后编写一个求解迷宫的非递归程序。求得的通路以三元组(i,j,d)的形式输出,其中:(i,j)指示迷宫中的一个坐标,d表示走到下一坐标的方向。如:对于下列数据的迷宫,输出的一条通路为;(1,1,1),(1,2,2),(2,2,2),(3,2,3),(3,1,2),....

数据结构_迷宫求解_实验报告 北邮

数据结构_迷宫求解_实验报告 北邮

数据结构实验报告实验名称:实验二——利用栈结构实现迷宫求解问题学生姓名:班级:班内序号:学号:日期: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、如有遍历一下栈,看是否已经进栈,一进栈就舍弃,寻求下一个;无就让其进栈。

数据结构 迷宫求解

数据结构 迷宫求解

数据结构迷宫求解数据结构迷宫求解1- 引言本文档旨在介绍使用数据结构解决迷宫问题的方法。

迷宫求解是一个经典的问题,涉及到遍历、图论等算法知识。

通过本文档的学习,读者将能够了解如何使用数据结构来解决迷宫问题,以及相关的算法和实现。

2- 迷宫问题概述2-1 迷宫定义迷宫是一个有围墙和通道组成的结构,其中只有一个入口和一个出口。

迷宫的通道可以用坐标来表示,如(x, y),其中x和y分别表示迷宫中的行号和列号。

2-2 迷宫求解目标迷宫求解的目标是找到从入口到出口的一条路径。

路径应该遵循以下规则:●只能沿着通道移动,不能穿过墙壁。

●每一步只能向上、下、左、右四个方向移动。

●不允许走重复的路径。

3- 使用栈求解迷宫问题3-1 栈的定义栈是一种先进后出(Last In First Out, LIFO)的数据结构。

栈的主要操作包括入栈(push)和出栈(pop)。

3-2 解题思路使用栈来解决迷宫问题的基本思路如下:●从起点开始,将起点入栈。

●栈顶元素出栈,并将其标记为已访问。

●查找当前位置的相邻可访问的通道。

如果存在未访问的相邻通道,则将其入栈。

●重复以上步骤,直到找到终点位置或者栈为空。

●如果找到终点位置,则栈中的元素即为解决迷宫问题的路径。

4- 迷宫求解算法实现4-1 数据结构选择为了实现迷宫求解,我们可以使用以下数据结构:●二维数组:用于表示迷宫的结构。

●栈:用于保存访问路径。

4-2 伪代码以下是使用栈求解迷宫问题的伪代码示例:```function solveMaze(maze):Initialize an empty stackPush the entrance coordinates (startX, startY) onto the stackwhile the stack is not empty:Pop the top element from the stackSet the current coordinates (currX, currY) to the popped elementMark the current coordinates as visitedif the current coordinates are the exit:return the stack as the solution pathfor each neighboring cell (nextX, nextY) of the current cell:if the neighboring cell is a valid and unvisited path:Push the neighboring cell coordinates onto the stackreturn \。

应用栈解决迷宫问题的C语言实现

应用栈解决迷宫问题的C语言实现

应⽤栈解决迷宫问题的C语⾔实现题⽬来⾃于严蔚敏《数据结构》,参考伪代码实现的程序:1 #include <stdio.h>2 #include <malloc.h>3//记录通道块在迷宫矩阵当中的横、纵坐标4struct Position{5int x;6int y;7 };8//放⼊栈当中的通道块元素9struct SElement {10int ord;//记录此通道块在整个通道当中的次序11 Position p;//记录此通道块在矩阵当中的位置12int di;//记录下⼀次测试这⼀路径的临近路径的位置13 };14//创建栈数据结构15#define STACK_INIT_SIZE 10016#define STACKINCREMENT 1017struct MyStack{18 SElement* base;19 SElement* top;20int stacksize;21 };22//创建⼀个栈如果创建成功则返回1,否则就返回023int InitStack(MyStack* s)24 {25 s->base=(SElement*)malloc(STACK_INIT_SIZE*sizeof(SElement));//为栈分配初始空间26if(!s->base) return0;27 s->top=s->base;//设定为空栈28 s->stacksize=STACK_INIT_SIZE;29return1;30 }31//判断栈是否为空,如果是空的就返回0,否则就返回132int IsStackEmpty(MyStack* s)33 {34if(s->top==s->base) return true;35return false;36 }37//获取栈顶元素,如果栈为空就返回0 否则就返回138int GetTop(MyStack* s,SElement* e)39 {40if(IsStackEmpty(s)) return0;41 e=s->top-1;42return1;43 }44//获取栈的长度,并且通过程序返回45int StackLength(MyStack* s)46 {47return s->top-s->base;48 }49//插⼊元素e为新的栈顶元素,插⼊成功则返回1,否则返回050int Push(MyStack* s,SElement e)51 {52if(s->top-s->base>=STACK_INIT_SIZE)53 {54 s->base=(SElement*)realloc(s->base,(s->stacksize+STACKINCREMENT)*sizeof(SElement));55if(!s->base) return0;56 s->top=s->base+s->stacksize;57 s->stacksize+=STACKINCREMENT;58 }59 *(s->top)=e;60 s->top++;61return1;62 }63//弹出栈顶元素赋值给e弹出成功返回1,弹出失败返回064int Pop(MyStack* s,SElement* e)65 {66if(IsStackEmpty(s)) return0;67 *e=*(s->top-1);68 s->top--;69return1;70 }71//定义墙元素为2 可⾛路径为0 已知路径为curStep 不能够通过的路径为-172#define MazeScale 1073int Maze[MazeScale][MazeScale]={{2,2,2,2,2,2,2,2,2,2},{2,0,0,2,0,0,0,2,0,2},{2,0,0,2,0,0,0,2,0,2},{2,0,0,0,0,2,2,0,0,2},74 {2,0,2,2,2,0,0,0,0,2},{2,0,0,0,2,0,0,0,0,2},{2,0,2,0,0,0,2,0,0,2},{2,0,2,2,2,0,2,2,0,2},{2,2,0,0,0,0,0,0,0,2},{2,2,2,2,2,2,2,2,2,2}}; 75//辅助函数考察当前路径能否通过76bool Pass(Position posi)77 {78//只有路径所在位置的数字为0的是可以⾛的79if(Maze[posi.x][posi.y]==0)80 {81return true;82 }83return false;84 }85//按顺时针⽅向从东开始寻找矩阵当中某⼀个位置的临近位置86 Position NextPosition(Position now,int direction)87 {88 Position next;89int x=now.x;90int y=now.y;91switch(direction)92 {93//东94case1:{95 next.x=x;96 next.y=y+1;97break;98 }99//南100case2:{101 next.x=x+1;102 next.y=y;103break;104 }105//西106case3:{107 next.x=x;108 next.y=y-1;109break;110 }111//北112case4:113 {114 next.x=x-1;115 next.y=y;116break;117 }118default:break;119 }120return next;121 }122//留下⾜迹123void FootPrint(Position p,int step)124 {125 Maze[p.x][p.y]=step;126 }127//路径不可⾛的话就留下-1的标记128void MarkPrint(Position p)129 {130 Maze[p.x][p.y]=-1;131 }132int main()133 {134//打印出迷宫矩阵135for(int i=0;i<MazeScale;i++)136 {137for(int j=0;j<MazeScale;j++)138 {139 printf("%d ",Maze[i][j]);140 }141 printf("\n");142 }143//迷宫程序主体144 MyStack path;//记录路径的栈145 InitStack(&path);//初始化路径数组146 Position curp;//当前被试位置147//初始化当前位置为矩阵⼊⼝148 curp.x=1;149 curp.y=1;150int curStep=1;//被探索的步数151do152 {153if(Pass(curp))154 {155 FootPrint(curp,curStep);//可⾛就在迷宫⾥⾯留下⾜迹156//创建⼀个栈元素,存储可⾏路径的相关值,将这个元素存储到栈当中157 SElement e;158 e.di=1;//意味着下⼀个被试路块为这⼀个路块的正上⽅的路块159 e.ord=curStep;160 e.p.x=curp.x;161 e.p.y=curp.y;162 Push(&path,e);//将路径块⼊栈163if(curp.x==MazeScale-2 && curp.y==MazeScale-2) break; //如果被压⼊的路径块到了迷宫的终点就退出循环164//找到下⼀个被试块165 curp=NextPosition(curp,1);//找到前⼀个被试块东⾯的路径块作为被试块166 curStep++;//被探索的步数加⼀167 }else//如果当前被试路径不能够通过的话168 {169if(!IsStackEmpty(&path))170 {171 SElement e;172 Pop(&path,&e);173 curStep--;174//将这⼀段所有的周围路径都已经被测试过的路径从栈中清除175while(e.di==4 && !IsStackEmpty(&path)){176 MarkPrint(e.p);177 Pop(&path,&e);178 curStep--;179 }180//如果当前栈顶还有未被测试的路径就测试剩余的周围路径181if(e.di<4)182 {183 curp=NextPosition(e.p,e.di+1);184 e.di++;185 curStep++;186 Push(&path,e);187 }188 }189 }190 }while(!IsStackEmpty(&path));191 printf("\n");192//打印出结果迷宫矩阵193for(int i=0;i<MazeScale;i++)194 {195for(int j=0;j<MazeScale;j++)196 {197 printf("%d ",Maze[i][j]);198 }199 printf("\n");200 }201return0;202 }。

第3章栈和队列第4讲栈的应用用栈求迷宫问题

第3章栈和队列第4讲栈的应用用栈求迷宫问题

从入口(1,1)出发找到 一个可走方块(1,2)

15/20
if (find)
//找到了一个相邻可走方块(i1,j1)
{ st->data[st->top].di=di; //修改原栈顶元素的di值
e.i=i1; e.j=j1; e.di=-1;
Push(st,e);
//相邻可走方块e进栈
mg[i1][j1]=-1;
if ((k+2)%5==0) //每输出每5个方块后换一行
printf("\n");
}
printf("\n");
DestroyStack(st);//销毁栈
return true;
//输出一条迷宫路径后返回true
}
→→ ↓ ↓ ↓ →
4 4 -1 4 3 -11 23 43 -11 2 3 -121 1 3 -21 1 2 -11 1 1 -11 i j di
i j di
10/20
求解迷宫路径的过程:
前一方块
找 其 他 可 能 的 相 邻 方 块
× 当前方块
× 回溯 所有相邻方块都不能走
11/20
用栈求一条迷宫路径的算法: (xi,yi) (xe,ye)
bool mgpath(int xi,int yi,int xe,int ye) //求解路径为:(xi,yi)->(xe,ye)
//(i1,j1)迷宫值置为-1避免重复走到该方块
}
从入口(1,1)出发找到一个可走方 块(1,2):将(1,2,-1)进栈

1 2 -1 1 11 i j di
一个栈
16/20
else

用栈求解迷宫问题所有路径及最短路径程序c语言

用栈求解迷宫问题所有路径及最短路径程序c语言

用栈求解迷宫问题所有路径及最短路径程序c语言
摘要:
1.迷宫问题的背景和意义
2.栈的基本概念和原理
3.用栈解决迷宫问题的方法
4.C 语言编程实现步骤
5.程序示例及运行结果
正文:
【1.迷宫问题的背景和意义】
迷宫问题是计算机科学中的一个经典问题,它涉及到图论、数据结构和算法等多个领域。

在迷宫问题中,给定一个有向图,目标是找到从起点到终点的所有路径以及最短路径。

这个问题在现实生活中也有很多应用,例如地图导航、物流路径规划等。

【2.栈的基本概念和原理】
栈是一种线性数据结构,它遵循后进先出(LIFO)的原则。

栈可以用来存储序列中的元素,也可以用来表示函数调用关系。

栈的操作通常包括入栈、出栈、获取栈顶元素等。

【3.用栈解决迷宫问题的方法】
为了解决迷宫问题,我们可以使用栈来记录遍历过程中的路径。

具体步骤如下:
1.创建一个栈,用于存储遍历过程中的路径;
2.从起点开始,将当前节点的编号入栈;
3.遍历当前节点的所有相邻节点,如果相邻节点未被访问过,则将其入栈;
4.当栈不为空时,继续执行步骤3;否则,说明已到达终点,开始回溯,找到最短路径;
5.从栈顶弹出节点,将其添加到结果路径列表中;
6.如果栈为空,说明没有找到从起点到终点的路径;否则,返回结果路径列表。

《数据结构》上机实验报告—利用栈实现迷宫求解

《数据结构》上机实验报告—利用栈实现迷宫求解

《数据结构》上机实验报告—利用栈实现迷宫求解实验目的:掌握栈的基本操作和迷宫求解的算法,并能够利用栈实现迷宫求解。

实验原理:迷宫求解是一个常见的路径问题,其中最常见的方法之一是采用栈来实现。

栈是一种先进后出的数据结构,适用于这种类型的问题。

实验步骤:1.创建一个迷宫对象,并初始化迷宫地图。

2.创建一个栈对象,用于存储待探索的路径。

3.将起点入栈。

4.循环执行以下步骤,直到找到一个通向终点的路径或栈为空:a)将栈顶元素出栈,并标记为已访问。

b)检查当前位置是否为终点,若是则路径已找到,结束。

c)检查当前位置的上、下、左、右四个方向的相邻位置,若未访问过且可以通行,则将其入栈。

5.若栈为空,则迷宫中不存在通向终点的路径。

实验结果:经过多次实验,发现利用栈实现迷宫求解的算法能够较快地找到一条通向终点的路径。

在实验中,迷宫的地图可通过一个二维数组表示,其中0表示可通行的路径,1表示墙壁。

实验结果显示,该算法能够正确地找出所有可行的路径,并找到最短路径。

实验结果还显示,该算法对于大型迷宫来说,解决速度相对较慢。

实验总结:通过本次实验,我掌握了利用栈实现迷宫求解的算法。

栈作为一种先进后出的数据结构,非常适合解决一些路径的问题。

通过实现迷宫求解算法,我深入了解了栈的基本操作,并学会运用栈来解决实际问题。

此外,我还了解到迷宫求解是一个复杂度较高的问题,对于大型迷宫来说,解决时间较长。

因此,在实际应用中需要权衡算法的速度和性能。

在今后的学习中,我将进一步加深对栈的理解,并掌握其他数据结构和算法。

我还将学习更多的路径算法,以便更好地解决迷宫类问题。

掌握这些知识将有助于我解决更加复杂的问题,并提升编程能力。

数据结构设计——用栈实现迷宫问题的求解

数据结构设计——用栈实现迷宫问题的求解

数据结构设计——⽤栈实现迷宫问题的求解求解迷宫问题1,问题描述以⼀个m*n的长⽅阵表⽰迷宫,0和1分别表⽰迷宫中的通路和障碍。

迷宫问题要求求出从⼊⼝(1,1)到出⼝(m,n)的⼀条通路,或得出没有通路的结论。

基本要求:⾸先实现⼀个以链表作存储结构的栈类型,然后编写⼀个求迷宫问题的⾮递归程序,求得的通路,其中:(i,j)指⽰迷宫中的⼀个坐标, d表⽰⾛到下⼀坐标的⽅向。

左上⾓(1,1)为⼊⼝,右下⾓(m,n)为出⼝。

2.设计思路: ⽤栈实现迷宫问题的求解;3.实验代码:栈实现迷宫求解问题:************************************************************************************************************1//maze_stack.cpp2 #include<stdio.h>3 #include<stdlib.h>4 #include<windows.h>5 #include"seqstack.h"67#define MAX_ROW 128#define MAX_COL 14910int maze[12][14] = {111, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,121, 0, 1, 0, 0, 0, 1, 0, 1, 1, 0, 1, 1, 1,131, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 1,141, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1, 0, 0, 1,151, 0, 1, 1, 1, 0, 1, 0, 0, 0, 1, 0, 1, 1,161, 0, 0, 0, 1, 1, 1, 1, 0, 1, 1, 0, 0, 1,171, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 1, 1, 1,181, 1, 0, 1, 0, 1, 0, 1, 1, 0, 0, 0, 0, 1,191, 0, 0, 0, 0, 1 ,0 ,0, 0 ,0 ,1 ,0 ,1 ,1,201, 1, 0, 0, 1, 1, 0, 1, 1, 1, 1, 0, 0, 1,211, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1,221, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 123 };2425void print_line()26 {27 system("cls");28 printf("迷宫如下‘■’代表墙,数字或者‘☆’表⽰路径\n");29int i, j;30for (i = 0; i < MAX_ROW; i++){31for (j = 0; j < MAX_COL; j++)32if (maze[i][j] == 1) printf("■");33else if (maze[i][j] >= 3){34 printf("%2d", maze[i][j] - 2);35/*if (i == MAX_ROW-2 && j == MAX_COL-2) printf("★");36 else printf("☆");*/37 }38else printf("");39 printf("\n");40 }41 printf("已到达出⼝...\n");42 printf("可见使⽤栈求出的路径并⾮最优路径,根据我依次探索的⽅向不同,结果也将不同\n");43 }4445void visit(mark p,int sign, PSeqStack S)46 {47 Push_SeqStack(S,p);48switch (sign)49 {50case1: p.col++; Push_SeqStack(S, p); maze[p.row][p.col] = 2; break;//向右51case2: p.row++; Push_SeqStack(S, p); maze[p.row][p.col] = 2; break;//向下52case3: p.col--; Push_SeqStack(S, p); maze[p.row][p.col] = 2; break;//向左53case4: p.row--; Push_SeqStack(S, p); maze[p.row][p.col] = 2; break;//向上54 }55 }5657int main()59struct point p = { 1, 1 };60 maze[p.row][p.col] = 2;//遍历过的点设置为261 PSeqStack S = Init_SeqStack();62 Push_SeqStack(S,p);63while (!Empty_SeqStack(S))64 {65 Pop_SeqStack(S, &p);66if (p.row == MAX_ROW - 2 && p.col == MAX_COL - 2)67break;68if (p.col + 1 < MAX_COL - 1 && maze[p.row][p.col + 1] == 0)//向右69 {70 visit(p, 1, S);71continue;72 }73if (p.row + 1 < MAX_ROW - 1 && maze[p.row + 1][p.col] == 0)//向下74 {75 visit(p, 2, S);76continue;77 }78if (p.col - 1 >= 1 && maze[p.row][p.col - 1] == 0)//向左79 {80 visit(p, 3, S);81continue;82 }83if (p.row - 1 >= 1 && maze[p.row - 1][p.col] == 0)//向上84 {85 visit(p, 4, S);86continue;87 }//以上是对迷宫的四个⽅向进⾏操作88 }89if (p.row == MAX_ROW - 2 && p.col == MAX_COL - 2)//是否为出⼝90 {91int count = GetLength_SeqStack(S)+3;//为了与迷宫0,1,2的区别所以基数要以3开始92 printf("成功找到出⼝,路径倒序输出:\n");93 printf("(%d,%d)\n", p.row, p.col);94 maze[p.row][p.col] = count;95while (!Empty_SeqStack(S))//按照前驱进⾏查找96 {97 count--;98 Pop_SeqStack(S, &p);99 maze[p.row][p.col] = count;100 printf("(%d,%d)\n", p.row, p.col);101 }102 printf("3秒后打印路径......");103 Sleep(3000);104 print_line();105 }106else {107 printf("没有出路\n");108 }109 system("pause");110return0;111 }112//end maze_stack.cpp************************************************************************************************************* 1//seqstack.h2 #include<stdio.h>3 #include<stdlib.h>4#define MAXSIZE 10056 typedef struct point{7int row, col;8 }mark;910 typedef mark DataType;1112 typedef struct {13 DataType data[MAXSIZE];14int top;15 }SeqStack, * PSeqStack;1617 PSeqStack Init_SeqStack (void)18 {19 PSeqStack S;20 S = (PSeqStack)malloc(sizeof(SeqStack));21if (S)22 S->top = -1;23else24 exit(-1);25return S;26 }28int Empty_SeqStack(PSeqStack S)29 {30//return (S->top==-1);31if (S->top == -1)32return1;33else34return0;35 }3637int Push_SeqStack(PSeqStack S,DataType x)38 {39if (S->top == MAXSIZE - 1)40 {41 printf("栈满不能⼊栈\n");42return0;43 }44else45 {46 S->top++;47 S->data[S->top] = x;48return1;49 }50 }5152int Pop_SeqStack(PSeqStack S,DataType *x)53 {54if(Empty_SeqStack(S))55return0;56else57 {58 *x = S->data[S->top];59 S->top--;60return1;61 }62 }6364int GetTop_SeqStack(PSeqStack S ,DataType *x) 65 {66if(Empty_SeqStack(S))67return0;68else69 {70 *x = S->data[S->top];71return1;72 }73 }74int GetLength_SeqStack(PSeqStack S)75 {76return S->top + 1;77 }7879void Distory_SeqStack(PSeqStack *S)80 {81if(*S)82free(*S);83 *S = NULL;84 }//end seqstack.h4.运⾏结果:栈求解迷宫:。

利用栈实现迷宫求解

利用栈实现迷宫求解
迷宫求解数据结构迷宫求解求解迷宫问题栈的实现利用栈求表达式的值迷宫求解课程设计c语言实现栈结构力学求解器规划求解excel规划求解
利用栈实现迷宫的求解
一、要解决的四个问题:
1、表示迷宫的数据结构:
设迷宫为 m 行 n 列,利用 maze[m][n]来表示一个迷宫,maze[i][j]=0 或 1; 其中:0 表示 通路,1 表示不通,当从某点向下试探时,中间点有 4 个方向可以试探,(见图)而四个角 点有 2 个方向,其它边缘点有 3 个方向,为使问题简单化我们用 maze[m+2][n+2]来表示迷 宫,而迷宫的四周的值全部为 1。这样做使问题简单了,每个点的试探方向全部为 4,不用 再判断当前点的试探方向有几个,同时与迷宫周围是墙壁这一实际问题相一致。
Push_SeqStack ( s, temp ) ; x=i ; y=j ; maze[x][y]= -1 ; if (x= =m&&y= =n) return 1 ; /*迷宫有路*/ else d=0 ; } else d++ ; } /*while (d<4)*/ } /*while (! Empty_SeqStack (s ) )*/ return 0 ;/*迷宫无路*/ } 栈中保存的就是一条迷宫的通路。
素有两个域组成,x:横坐标增量,y:纵坐标增量。Move 数组如图 3 所示。 move 数组定义如下: typedef struct { int x ; //行 int y ; //列 } item ; item move[4] ; 这样对 move 的设计会很方便地求出从某点 (x,y) 按某一方法思想如下:
(1) 栈初始化; (2) 将入口点坐标及到达该点的方向(设为-1)入栈 (3) while (栈不空)

用栈方法解决迷宫问题

用栈方法解决迷宫问题
else
pastack->t--;
}
/*当pastack所指的栈不为空栈时,求栈顶元素的值*/
DataType top_seq( PSeqStack pastack ) {
return (pastack->s[pastack->t]);
}
void pushtostack(PSeqStack st, int x, int y, int d) {
1,0,0,0,0,0,1,0,0,1,1,
1,0,1,1,1,0,0,0,1,1,1,
1,0,0,0,1,0,1,1,0,1,1,
1,1,0,0,1,0,1,1,0,0,1,
1,1,1,0,0,0,0,0,0,0,1,
1,1,1,1,1,1,1,1,1,1,1
};
mazePath(maze,direction,1,1,6,9);
getchar();
return 0;
}
while(!isEmptyStack_seq(st)) {
element = top_seq(Leabharlann t);pop_seq(st);
printf("the node is: %d %d \n", element.x, element.y);
}
}
/*迷宫maze[M][N]中求从入口maze[x1][y1]到出口maze[x2][y2]的一条路径*/
#include <stdio.h>
#include <stdlib.h>
typedef struct {
int x;/*行下标*/
int y;/*列下标*/
int d;/*运动方向*/

迷宫求解与栈课程设计

迷宫求解与栈课程设计

迷宫求解与栈课程设计一、课程目标知识目标:1. 学生能理解栈的基本概念,掌握栈的特点及其在算法中的应用。

2. 学生能掌握利用栈求解迷宫问题的方法,理解其原理和步骤。

3. 学生能描述并比较不同的迷宫求解算法,了解其优缺点。

技能目标:1. 学生能够运用栈结构设计并实现简单的迷宫求解程序。

2. 学生能够通过编写代码,锻炼问题分析、逻辑思维和编程能力。

3. 学生能够通过小组合作,提高团队协作和沟通能力。

情感态度价值观目标:1. 学生对计算机科学产生兴趣,培养探究精神和创新意识。

2. 学生在学习过程中,培养克服困难的勇气和自信,增强解决问题的决心。

3. 学生通过小组合作,学会尊重他人意见,培养合作精神,提高人际交往能力。

课程性质:本课程为信息技术与学科整合的实践课程,旨在通过迷宫求解问题,让学生掌握栈的应用,培养编程思维和团队协作能力。

学生特点:学生为初中年级,具有一定的计算机基础和编程兴趣,好奇心强,喜欢动手实践。

教学要求:课程要求以学生为主体,注重实践操作,关注学生个体差异,鼓励学生积极参与,充分调动学生的主观能动性。

在教学过程中,将目标分解为具体的学习成果,以便进行有效的教学设计和评估。

二、教学内容本课程依据课程目标,结合教材第四章“数据结构”相关内容,组织以下教学大纲:1. 栈的基本概念与原理- 栈的定义、特点和应用场景- 栈的顺序存储结构及其操作- 栈的链式存储结构及其操作2. 迷宫求解问题分析- 迷宫问题的定义和求解方法- 栈在迷宫求解中的应用原理3. 迷宫求解算法实现- 算法步骤及流程图设计- 代码编写与调试- 迷宫求解算法优化4. 算法比较与分析- 不同迷宫求解算法的优缺点对比- 效率分析及适用场景5. 实践操作与小组合作- 设计并实现迷宫求解程序- 小组讨论、协作与成果展示教学内容安排与进度:第1课时:栈的基本概念与原理第2课时:迷宫求解问题分析第3课时:迷宫求解算法实现(上)第4课时:迷宫求解算法实现(下)第5课时:算法比较与分析、实践操作与小组合作教学内容确保科学性和系统性,注重理论与实践相结合,培养学生编程思维和解决问题的能力。

栈和队列的应用函数调用栈迷宫求解等

栈和队列的应用函数调用栈迷宫求解等

栈和队列的应用函数调用栈迷宫求解等栈和队列的应用:函数调用栈、迷宫求解等栈(Stack)和队列(Queue)是常用的数据结构,在计算机科学中有广泛的应用。

本文将讨论它们的应用,包括函数调用栈和迷宫求解。

一、函数调用栈的应用函数调用栈是程序执行时用于管理函数调用的一种数据结构。

当一个函数被调用时,函数的执行现场(包括局部变量、函数参数等)需要被保存,以便在函数执行完毕后能够恢复到调用该函数之前的状态。

函数调用栈的应用之一是递归函数。

递归函数是指在函数的定义中调用函数本身。

在递归函数中,每一次的函数调用都会将其执行现场保存到栈中,以便能够在递归结束后正确返回。

例如,下面是一个计算斐波那契数列的递归函数:```pythondef fibonacci(n):if n <= 1:return nelse:return fibonacci(n-1) + fibonacci(n-2)```在调用`fibonacci(5)` 时,函数调用栈中会保存多个函数的执行现场,包括函数参数 `n` 的值以及函数返回地址。

通过不断弹出栈顶元素,递归函数可以依次返回上一层的结果,最终得到 `fibonacci(5)` 的值。

除了递归函数,函数调用栈还广泛应用于程序调试和异常处理。

当程序运行出错时,我们可以通过查看函数调用栈来确定错误发生的位置和调用关系,有助于快速定位和修复bug。

二、迷宫求解的应用迷宫求解是一个经典的问题,通过使用栈和队列作为辅助数据结构,可以高效地找到迷宫的路径。

在迷宫求解中,迷宫可以看做是一个二维网格,其中包括起点、终点以及墙壁。

我们需要找到一条从起点到终点的路径,路径可以通过上下左右移动。

使用栈或者队列来辅助求解迷宫问题。

当使用栈时,我们将当前位置的周围可行的下一个位置入栈,并继续向前搜索。

当使用队列时,我们将当前位置的周围可行的下一个位置入队,然后依次处理队列中的元素。

下面是一个使用栈求解迷宫的示例代码:```pythondef maze_solver(maze):stack = [(0, 0)] # 起点入栈visited = set() # 记录已访问的位置while stack:x, y = stack[-1] # 获取栈顶位置if (x, y) == (len(maze)-1, len(maze[0])-1):return True # 找到终点found = Falsefor dx, dy in [(0, 1), (0, -1), (1, 0), (-1, 0)]:nx, ny = x + dx, y + dy # 计算下一个位置if 0 <= nx < len(maze) and 0 <= ny < len(maze[0]) and (nx, ny) not in visited and maze[nx][ny] == 0:stack.append((nx, ny)) # 下一个位置入栈visited.add((nx, ny)) # 标记为已访问found = Truebreakif not found:stack.pop() # 无法继续前进,回溯return False # 未找到路径```在上述的代码中,我们使用栈来保存前进过程中的路径,并使用集合 `visited` 记录已经访问过的位置。

数据结构之迷宫问题求解(一)利用栈与递归求解出口

数据结构之迷宫问题求解(一)利用栈与递归求解出口

数据结构之迷宫问题求解(⼀)利⽤栈与递归求解出⼝ 本⽂适合于对迷宫问题已有初步研究,或阅读代码能⼒较强的⼈. 因此,如果你对迷宫问题⼀⽆所知,请参考其他更详细的资料. 迷宫问题,是⼀个对栈(Stack)典型应⽤的例⼦之⼀. 假如,有如下10X10的迷宫(0代表通路,1代表障碍),我们需要⽤写程序来找出迷宫的出⼝.1 1 1 1 1 1 1 1 1 11 1 1 0 1 1 1 0 1 10 0 0 0 1 0 0 0 1 11 1 0 1 1 0 1 0 0 11 1 0 1 0 0 1 0 1 11 1 0 1 1 1 1 0 0 11 1 0 0 0 0 0 0 1 11 1 0 1 0 1 1 0 1 11 1 0 1 0 1 1 0 1 11 1 1 1 1 1 1 0 1 1那么,我们可以通过两种⽅式完成.⽅式⼀:通过利⽤栈FILO(First In Last Out)的特性核⼼代码/**函数说明:通过栈来进⾏迷宫求解*参数说明:* Maze:迷宫地图数组* sz:迷宫⼤⼩* entry:迷宫⼊⼝点* path:⽤于寻找迷宫出⼝的栈*返回值:找到出⼝返回true,没找到返回false.*/bool FindMazePath(int *Maze,size_t sz,Pos &entry,stack<Pos>& path){//将⼊⼝压栈path.push(entry);//如果栈不为空while(!path.empty()){//获取栈顶元素,即上⼀次⾛的路径Pos cur = path.top();//将其标记为已⾛过Maze[cur.x*sz+cur.y] = 3;//找到出⼝if(sz-1==cur.x){return true;}Pos next = cur;//下⼀步,向右移动next.x += 1;if(CheckIsAccess(Maze,sz,next)){//可以向右移动,将当前步⼊栈path.push(next);continue;}next = cur;//下⼀步,向左移动next.x -= 1;if(CheckIsAccess(Maze,sz,next)){//可以向左移动,⼊栈path.push(next);continue;}//下⼀步,向上移动next = cur;next.y += 1;if(CheckIsAccess(Maze,sz,next)){//可以向上移动path.push(next);continue;}next = cur;//向下移动next.y -= 1;if(CheckIsAccess(Maze,sz,next)){//可以向下移动path.push(next);continue;}//上、下、左、右都不能⾛path.pop();}return false;}⽅式⼆:通过递归核⼼代码/**函数说明:根据递归寻找迷宫出⼝*参数说明* Maze:迷宫地图* sz:迷宫⼤⼩* entry:迷宫⼊⼝* path:⽤来判断是否存在出⼝的栈*返回值:⽆(如果存在出⼝,栈为空;如果不存在出⼝,栈中存在起点坐标)*/void FindMazePathR(int *Maze,size_t sz,Pos &entry,stack<Pos> & path){//将⼊⼝压栈path.push(entry);Pos cur = entry;//将已⾛过的路标记为3Maze[cur.x*sz+cur.y] = 3;//找到出⼝,直接返回if(sz-1==entry.x){//将起点坐标弹出path.pop();return ;}Pos next = cur;//右next.x += 1;if(CheckIsAccess(Maze,sz,next)){//以当前位置为起点,递归进⾏下⼀步FindMazePathR(Maze,sz,next,path);}next = cur;//左next.x -= 1;if(CheckIsAccess(Maze,sz,next)){FindMazePathR(Maze,sz,next,path);}//上next = cur;next.y += 1;if(CheckIsAccess(Maze,sz,next)){FindMazePathR(Maze,sz,next,path);}//下next = cur;next.y -= 1;if(CheckIsAccess(Maze,sz,next)){FindMazePathR(Maze,sz,next,path);}path.pop();}最后,附上整个程序的完整代码(代码量较少,声明与实现我就不分⽂件了)迷宫问题求解完整代码//相关函数的声明与实现#ifndef __MAZE_H__#define __MAZE_H__#include<iostream>#include<iomanip>#include<stack>#include<assert.h>namespace Maze{using namespace std;//迷宫⼤⼩static const int N = 10;//迷宫地图⽂件名static const char *const FILENAME = "MazeMap.txt";//坐标struct Pos{int x; //横坐标(本质是数组arr[i][j]的j)int y; //纵坐标(本质是数组arr[i][j]的i)};/*函数说明:从⽂件中获取迷宫地图参数说明:Maze:迷宫地图数组sz:迷宫⼤⼩返回值:⽆*/void GetMaze(int *Maze,size_t sz){FILE *fp = fopen(FILENAME,"r");//打开失败if(NULL==fp){//输出错误信息perror(FILENAME);//结束程序exit(1);}//将⽂件中的迷宫地图读⼊Maze数组内for(size_t i=0; i<sz; ++i){for(size_t j=0; j<sz;){//从⽂件流中获取字符char tmp = getc(fp);//字符为0或为1时,导⼊数组if(tmp=='0'||tmp=='1'){Maze[i*sz+j]=tmp -'0';++j;}else if(EOF==tmp){//⽂件已读完,循环还未停⽌//说明此处⽂件中的迷宫地图存在问题assert(false);return ;}}}//关闭⽂件fclose(fp);}/*函数说明:打印迷宫参数说明:Maze:迷宫地图数组sz:迷宫⼤⼩返回值:⽆*/void PrintMaze(int *Maze,size_t sz){cout<<setw(2);for(size_t i=0; i<sz; ++i){for(size_t j=0; j<sz; ++j){cout<<Maze[i*sz+j]<<setw(2);}cout<<endl;}}/*函数说明:检测当前位置是否可以通过参数说明:Maze:迷宫地图数组sz:迷宫⼤⼩cur:当前所在位置返回值:可以通过返回true,不能通过返回false.*/bool CheckIsAccess(int *Maze,size_t sz,Pos cur){if(cur.x>=0 && cur.x<sz && //⾏坐标是否越界cur.y>=0 && cur.y<sz && //列坐标是否越界Maze[cur.x*sz+cur.y]==0 ){ //所在⾏列是否可以通过return true;}return false;}/*函数说明:通过栈来进⾏迷宫求解参数说明:Maze:迷宫地图数组sz:迷宫⼤⼩entry:迷宫⼊⼝点path:⽤于寻找迷宫出⼝的栈返回值:找到出⼝返回true,没找到返回false.*/bool FindMazePath(int *Maze,size_t sz,Pos &entry,stack<Pos>& path){ //将⼊⼝压栈path.push(entry);//如果栈不为空while(!path.empty()){//获取栈顶元素,即上⼀次⾛的路径Pos cur = path.top();//将其标记为已⾛过Maze[cur.x*sz+cur.y] = 3;//找到出⼝if(sz-1==cur.x){return true;}Pos next = cur;//下⼀步,向右移动next.x += 1;if(CheckIsAccess(Maze,sz,next)){//可以向右移动,将当前步⼊栈path.push(next);continue;}next = cur;//下⼀步,向左移动next.x -= 1;if(CheckIsAccess(Maze,sz,next)){//可以向左移动,⼊栈path.push(next);continue;}//下⼀步,向上移动next = cur;next.y += 1;if(CheckIsAccess(Maze,sz,next)){//可以向上移动path.push(next);continue;}next = cur;//向下移动next.y -= 1;if(CheckIsAccess(Maze,sz,next)){//可以向下移动path.push(next);continue;}//上、下、左、右都不能⾛path.pop();}return false;}/**函数说明:根据递归寻找迷宫出⼝*参数说明* Maze:迷宫地图* sz:迷宫⼤⼩* entry:迷宫⼊⼝* path:⽤来判断是否存在出⼝的栈*返回值:⽆(如果存在出⼝,栈为空;如果不存在出⼝,栈中存在起点坐标)*/void FindMazePathR(int *Maze,size_t sz,Pos &entry,stack<Pos> & path){ //将⼊⼝压栈path.push(entry);Pos cur = entry;//将已⾛过的路标记为3Maze[cur.x*sz+cur.y] = 3;//找到出⼝,直接返回if(sz-1==entry.x){//将起点坐标弹出path.pop();return ;}Pos next = cur;//右next.x += 1;if(CheckIsAccess(Maze,sz,next)){//以当前位置为起点,递归进⾏下⼀步FindMazePathR(Maze,sz,next,path);}next = cur;//左next.x -= 1;if(CheckIsAccess(Maze,sz,next)){FindMazePathR(Maze,sz,next,path);}//上next = cur;next.y += 1;if(CheckIsAccess(Maze,sz,next)){FindMazePathR(Maze,sz,next,path);}//下next = cur;next.y -= 1;if(CheckIsAccess(Maze,sz,next)){FindMazePathR(Maze,sz,next,path);}path.pop();}}#endif迷宫求解测试代码#include"Maze.h"using namespace Maze;void MazeTest(){int arr[N][N]; //迷宫地图Pos entry = {2,0}; //起点坐标stack<Pos> path; //栈GetMaze((int *)arr,N); //将⽂件中迷宫导⼊到arr数组中PrintMaze((int *)arr,N);//打印迷宫FindMazePath((int *)arr,N,entry,path);//找迷宫出⼝cout<<endl<<endl; //换⾏处理(使界⾯更整齐)PrintMaze((int *)arr,N);//打印⾛过的迷宫}int main(){MazeTest();return 0;}总结: 1.利⽤栈去寻找迷宫出⼝,栈内最终会保存从⼊⼝到出⼝的所有路径. 2.利⽤递归去寻找迷宫出⼝,传进去的栈仅仅只是⽤来判断迷宫是否有出⼝, 3.利⽤递归去寻找出⼝时,因为递归的特性,将会遍历完迷宫内的所有路径. 最后,还有⼀个问题:如果⼀个迷宫存在多条路径可以到达出⼝,那么如何得到迷宫到出⼝的最短路径 有机会的话,我将会在下篇⽂章讨论此事.。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

利用栈实现迷宫的求解一、要解决的问题:以一个m*n的长方阵表示迷宫,0和1分别表示迷宫中的通路和障碍,设计一个程序,对任意设定的迷宫,求出一条从入口到出口的通路,或得出没有通路的结论。

二:算法基本思想描述:用一个字符类型的二维数组表示迷宫,数组中每个元素取值“0”(表示通路)或“1”(表示墙壁)。

二维数组的第0行、第m+1行、第0列、第m+1列元素全置成“1”,表示迷宫的边界;第1行第1列元素和第m行第n列元素置成“0”,表示迷宫的入口和出口走迷宫的过程可以模拟为一个搜索的过程:每到一处,总让它按东、南、西、北4个方向顺序试探下一个位置;用二维数组move记录4个方向上行下标增量和列下标增量,则沿第i个方向前进一步,可能到达的新位置坐标可利用move数组确定:Px=x+move[i][0]Py=y+move[i][1]如果某方向可以通过,并且不曾到达,则前进一步,在新位置上继续进行搜索;如果4个方向都走不通或曾经到达过,则退回一步,在原来的位置上继续试探下一位置。

三:设计:1:数据结构的设计:(1)定义三元数组元素的结构typedef struct MazeDirect{int Dx; //行标int Dy; //列标int direct; //走到下一个坐标点的方向}MazeDirect;(2)定义链表节点的结构组成typedef struct LinkNode{elemtype data; //数据域struct LinkNode *next; //指针域}LinkNode;(3)定义链栈的头指针typedef struct{LinkNode *top; //栈的头指针}LinkStack;(4)移动数组结构的定义typedef struct{int x,y;//x为行标,y为列标}Direction_increm;2:算法的设计:【1】迷宫图的设计设迷宫为m行n列,利用maze[m][n]来表示一个迷宫,maze[i][j]=0或1; 其中:0表示通路,1表示不通,当从某点向下试探时,中间点有4个方向可以试探,(见图)而四个角点有2个方向,其它边缘点有3个方向,为使问题简单化我们用maze[m+2][n+2]来表示迷宫,而迷宫的四周的值全部为1。

这样做使问题简单了,每个点的试探方向全部为4,不用再判断当前点的试探方向有几个,同时与迷宫周围是墙壁这一实际问题相一致。

假设有6行8列的迷宫,如下图为maze[8][10]构造的迷宫【2】试探方向的设计:在上述表示迷宫的情况下,每个点有4个方向去试探,如当前点的坐标(x , y),与其相邻的4个点的坐标都可根据与该点的相邻方位而得到,如图2所示。

因为出口在(m,n),因此试探顺序规定为:从当前位置向前试探的方向为从正东沿顺时针方向进行。

为了简化问题,方便的求出新点的坐标,将从正东开始沿顺时针进行的这4个方向(用0,1,2,3表示东、南、西、北)的坐标增量放在一个结构数组move [ 4 ]中,在move 数组中,每个元素有两个域组成,x:横坐标增量,y:纵坐标增量。

Move数组如图3所示。

move数组定义如下:typedef struct {int x ; //行 int y ; //列 } item ; item move[4] ;这样对move 的设计会很方便地求出从某点 (x ,y ) 按某一方向 v (0≤v ≤3) 到达的新点(i ,j )的坐标:i =x + move[v].x ,j = y + move[v].y 。

【3】栈的设计:当到达了某点而无路可走时需返回前一点,再从前一点开始向下一个方向继续试探。

因此,压入栈中的不仅是顺序到达的各点的坐标,而且还要有从前一点到达本点的方向,即每走一步栈中记下的容为(行,列,来的方向)。

对于图1所示迷宫,依次入栈为:栈中每一组数据是所到达的每点的坐标及从该点沿哪个方向向下走的,对于图3迷宫,走的路线为:(1,1,0)→(2,1,1)→(2,2,0)→(3,2,1)→(3,3,0)→(3,4,0)(下脚标表示方向),当无路可走,则应回溯,对应的操作是出栈,沿下一个方向即方向继续试探。

栈中元素是一个由行、列、方向组成的三元组,栈元素的设计如下: typedef struct{int x , y , d ;/* 横纵坐标及方向*/ }datatype ;栈的定义为: SeqStack s ;x y1 2 3top —>图3 增量数组move(x ,y)图2 与点(x ,y)相邻的4个点及坐标(x ,y+1)(x,y-1) (x+1,y)(x-1,y)【4】. 如何防止重复到达某点,以避免发生死循环:一种方法是另外设置一个标志数组mark[m][n],它的所有元素都初始化为0,一旦到达了某一点( i , j )之后,使mark[ i ][ j ] 置1,下次再试探这个位置时就不能再走了。

另一种方法是当到达某点(i , j)后使maze[ i ][ j ] 置-1,以便区别未到达过的点,同样也能起到防止走重复点的目的,此处采用后一方法,算法结束前可恢复原迷宫。

四:详细设计;1. 算法的设计思想及流程图(1)主要函数的功能说明void ini_stack(LinkStack *)/*初始化链栈*/int empty_Stack(LinkStack *)/*判断是否为空栈*/void push_Stack(LinkStack *,elemtype)/*入栈*/elemtype pop_Stack(LinkStack *) /*出栈*/int size_stack(LinkStack ) /*栈的规模大小*/(2)算法描述【伪代码描述】迷宫求解算法思想如下:(1)栈初始化;(2)将入口点坐标及到达该点的方向(设为-1)入栈(3)while (栈不空){ 栈顶元素=>(x , y , d)出栈;求出下一个要试探的方向d++ ;//当遇到死路的时候就出栈,寻找原来点的下一个方向while (还有剩余试探方向时){ if (d方向可走)则{ (x , y , d)入栈;求新点坐标(i, j ) ;将新点(i , j)切换为当前点(x , y);if ( (x ,y)= =(m,n) ) 结束;else 重置d=0 ;}else d++ ;}}五:源程序清单;#include <stdio.h>#include <stdlib.h>int m,n;typedef struct MazeDirect{int Dx;int Dy;int direct;}MazeDirect; /*定义三元数组元素的结构*/typedef MazeDirect elemtype;typedef struct LinkNode{elemtype data;struct LinkNode *next; /*定义链表节点的结构组成*/ }LinkNode;typedef struct{LinkNode *top; /*定义链栈的头指针*/}LinkStack;void ini_stack(LinkStack *stack)/*初始化链栈*/{stack->top=NULL;}int empty_Stack(LinkStack *stack)/*判断是否为空栈*/{if (stack->top!=NULL)return 0;elsereturn 1;}void push_Stack(LinkStack *stack,elemtype x)/*入栈*/{LinkNode *s;s=(LinkNode *)malloc(sizeof(LinkNode));s->data=x;s->next=stack->top;stack->top=s;}elemtype pop_Stack(LinkStack *stack) /*出栈*/ {elemtype x;LinkNode *p;elemtype tmpNull={0,0,0};if (stack->top==NULL){return tmpNull;//(NULL)}else{x=stack->top->data;p=stack->top;stack->top=p->next;free(p);return (x);}}int size_stack(LinkStack stack) /*栈的规模大小*/ {int i;LinkNode *Numb;i=0;Numb=stack.top;while(Numb!=NULL){Numb=Numb->next;i++;}return i;}int w,t,maze[100][100];typedef struct{int x,y;//x为行标,y为列标}Direction_increm;Direction_increm MazeMove[4]={{0,1},{1,0},{0,-1},{-1,0}};typedef MazeDirect TmpType;int Maze_path(){MazeDirect tmp,path;LinkStack s;int x,y,Px,Py,d,flag=0;ini_stack(&s);tmp.Dx=1;tmp.Dy=1;tmp.direct=-1;push_Stack(&s,tmp);while (!empty_Stack(&s)){tmp=pop_Stack(&s);x=tmp.Dx;y=tmp.Dy;d=tmp.direct+1;//遇到死路的时候,回溯(通过出栈完成)while (d<4){Px=x+MazeMove[d].x;Py=y+MazeMove[d].y;if (maze[Px][Py]==0){tmp.Dx=x;tmp.Dy=y;tmp.direct=d;push_Stack(&s,tmp);x=Px;y=Py;maze[x][y]=-1;/*标记,防止重复点*/if(x==m&&y==n){flag=1;printf("\n到达迷宫出口:%d,%d",x,y);printf("\n经过的节点有:%d个",size_stack(s));while(!empty_Stack(&s)){path=pop_Stack(&s);printf("\n(%d,%d,%d)",path.Dx,path.Dy,path.direct);}break;}else d=0;}//结束ifelse d++;}//结束部while}//结束外部whilereturn flag;}void main(){printf("请输入迷宫图的行数和列数(输入格式为i,j):\n");scanf("%d,%d",&m,&n);printf("创建迷宫图:\n");for(w=0;w<m+2;w++){for(t=0;t<n+2;t++){scanf("%d",&maze[w][t]);getchar();}}printf("\n找到迷宫的路径(yes/1,no/0):%d",Maze_path());getch();}运行结果:。

相关文档
最新文档