用栈和队列分别实现求解迷宫问题(c++,c)

求解迷宫问题:给定一个迷宫要求输出其路径。

给出的迷宫如下(可自行更改)


可用两种方法实现1.栈2.队列

用栈只能找到路但路不是最简的最简的要用队列实现

用栈实现(解析都在代码里了)

c++(实现)

记得要给迷宫加个边防止访问越界

//用栈求解迷宫问题
#include <stdio.h>
#include <malloc.h>
#define MaxSize 100
#define M 8
#define N 8
int mg[M+2][N+2]=
{	{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}
};
//---------------------------------------------------------
//--迷宫栈基本运算---------------------------------------
//---------------------------------------------------------
typedef struct
{int i;				//当前方块的行号int j;				//当前方块的列号int di;				//di是下一可走相邻方位的方位号
} Box;
typedef struct
{Box data[MaxSize];	//存放方块int top;			//栈顶指针
} StType;				//定义栈类型void InitStack(StType *&s)		//初始化栈
{	s=(StType *)malloc(sizeof(StType));s->top=-1;
}
void DestroyStack(StType *&s)	//销毁栈
{free(s);
}
bool StackEmpty(StType *s)		//判断栈是否为空
{return(s->top==-1);
}
bool Push(StType *&s,Box e)	//进栈元素e
{if (s->top==MaxSize-1)return false;s->top++;s->data[s->top]=e;return true;
}
bool Pop(StType *&s,Box &e)	//出栈元素e
{if (s->top==-1)	return false;e=s->data[s->top];s->top--;return true;
}
bool GetTop(StType *s,Box &e)	//取栈顶元素e
{if (s->top==-1)	return false;e=s->data[s->top];return true;
}
//---------------------------------------------------------
bool mgpath(int xi,int yi,int xe,int ye)	//求解路径为:(xi,yi)->(xe,ye)
{Box path[MaxSize], e;int i,j,di,i1,j1,k;bool find;StType *st;								//定义栈stInitStack(st);							//初始化栈顶指针e.i=xi; e.j=yi;	e.di=-1;				//设置e为入口Push(st,e);								//方块e进栈mg[xi][yi]=-1;							//入口的迷宫值置为-1避免重复走到该方块while (!StackEmpty(st))					//栈不空时循环{GetTop(st,e);						//取栈顶方块ei=e.i; j=e.j; di=e.di;if (i==xe && j==ye)					//找到了出口,输出该路径{ printf("一条迷宫路径如下:\n");k=0;							//累计路径中的方块个数 while (!StackEmpty(st)){Pop(st,e);					//出栈方块epath[k++]=e;				//将e添加到path数组中}while (k>0){printf("\t(%d,%d)",path[k-1].i,path[k-1].j);if ((k+1)%5==0)				//每输出每5个方块后换一行printf("\n");  k--;}printf("\n");DestroyStack(st);				//销毁栈return true;					//输出一条迷宫路径后返回true}find=false;//最难想到的一步while (di<4 && !find)				//找相邻可走方块(i1,j1){	di++;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) find=true;	//找到一个相邻可走方块,设置find我真}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;					//(i1,j1)的迷宫值置为-1避免重复走到该方块}else								//没有路径可走,则退栈{	Pop(st,e);						//将栈顶方块退栈mg[e.i][e.j]=0;					//让退栈方块的位置变为其他路径可走方块}}DestroyStack(st);						//销毁栈return false;							//表示没有可走路径,返回false
}
int main()
{mgpath(1,1,M,N);return 1;
}

c实现:

#define  _CRT_SECURE_NO_WARNINGS 1
//顺序栈
#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>
#define M 8
#define N 8
int mg[M + 2][N + 2] =
{{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}
};
typedef struct
{int i;int j;int di;
}Box;
typedef Box ElemType;
typedef struct
{ElemType data[100];int top;
}SqStack;
SqStack* InitStack()
{SqStack* s = (SqStack*)malloc(sizeof(SqStack));s->top = -1;return s;
}
void DestroyStack(SqStack* s)
{free(s);
}
bool StackEmpty(SqStack* s)
{return (s->top == -1);
}
bool Push(SqStack* s, ElemType e)
{if (s->top == 100 - 1)return false;s->top++;s->data[s->top] = e;return true;
}
bool Pop(SqStack* s, ElemType* e)
{if (s->top == -1) return false;*e = s->data[s->top];s->top--;return true;
}
bool GetTop(SqStack* s, ElemType* e)
{if (s->top == -1) return false;*e = s->data[s->top];return true;
}
bool mgpath(int xi, int yi, int xe, int ye)
{SqStack* st = InitStack();Box path[100];Box e;Box* p = &e;e.i = xi, e.j = yi, e.di = -1;Push(st, *p);mg [xi][yi] = -1;int i, j;//存储当前的坐标int k = 0;int di = -1;int ix=0, jy=0;bool find=false;while (!StackEmpty(st)){GetTop(st, p);i = p->i, j = p->j;di = p->di;if (i == xe && j == ye){printf("路线为\n");while (!StackEmpty(st)){Pop(st, p);path[k++] = *p;}while (k > 0){printf("(%d,%d) ", path[k - 1].i, path[k - 1].j);k--;if ((k+2) % 5 == 0) printf("\n");}DestroyStack(st);return true;}find = false;while (di < 4&&!find){di++;switch (di){case 0:{ix = i - 1, jy = j;break;}case 1:{ix = i, jy = j + 1;break;}case 2:{ix = i + 1, jy = j;break;}case 3:{ix = i, jy = j - 1;break;}}if (mg[ix][jy] == 0) find = true;}if (find){e.i = ix, e.j = jy, e.di = -1;st->data[st->top].di = di;Push(st, *p);mg[ix][jy] = -1;}else{Pop(st, p);mg[p->i][p->j] = 0;}}DestroyStack(st);return false;}
int main()
{if (!mgpath(1, 1, M, N))printf("无解\n");return 0;
}

用队列实现

c++实现:

//用队列求解迷宫问题
#include <stdio.h>
#include <malloc.h>
#define MaxSize 100
#define M 8
#define N 8
int mg[M+2][N+2]=
{	{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}
};
//----------------------------------------------------------
//-非环形队列的基本运算算法---------------------------------
//----------------------------------------------------------
typedef struct 
{	int i,j;						//方块的位置int pre;						//本路径中上一方块在队列中的下标
} Box;								//方块类型
typedef struct
{Box data[MaxSize];int front,rear;					//队头指针和队尾指针
} QuType;							//顺序队类型void InitQueue(QuType *&q)			//初始化队列
{	q=(QuType *)malloc (sizeof(QuType));q->front=q->rear=-1;
}
void DestroyQueue(QuType *&q)		//销毁队列
{free(q);
}
bool QueueEmpty(QuType *q)			//判断队列是否为空
{return(q->front==q->rear);
}
bool enQueue(QuType *&q,Box e)		//进队列
{	if (q->rear==MaxSize-1)			//队满上溢出return false;				//返回假q->rear++;						//队尾增1q->data[q->rear]=e;				//rear位置插入元素ereturn true;					//返回真
}
bool deQueue(QuType *&q,Box &e)	//出队列
{	if (q->front==q->rear)			//队空下溢出return false;q->front++;e=q->data[q->front];return true;
}
//----------------------------------------------------------void dispapath(QuType *qu,int front)	//从队列qu找到一条迷宫路径并输出
{Box path[MaxSize]; int p=front,k=0,i;while(p!=-1)							//搜索反向路径path[0..k-1]{path[k++]=qu->data[p];p=qu->data[p].pre;}printf("一条迷宫路径如下:\n");for(i=k-1;i>=0;i--) 					//反向输出path构成正向路径{printf("\t(%d,%d)",path[i].i,path[i].j);if ((k-i)%5==0) printf("\n");		//每输出每5个方块后换一行}printf("\n");
}
bool mgpath1(int xi,int yi,int xe,int ye)	//搜索路径为:(xi,yi)->(xe,ye)
{Box e;int i,j,di,i1,j1;QuType *qu;						//定义顺序队指针quInitQueue(qu);					//初始化队列que.i=xi; e.j=yi; e.pre=-1;enQueue(qu,e);					//(xi,yi)进队mg[xi][yi]=-1;					//将其赋值-1,以避免回过来重复搜索while (!QueueEmpty(qu))			//队不空且循环{	deQueue(qu,e);				//出队方块e,非环形队列中元素e仍在队列中i=e.i; j=e.j;if (i==xe && j==ye)			//找到了出口,输出路径{	dispapath(qu,qu->front);	//调用dispapath函数输出路径DestroyQueue(qu);		//销毁队列return true;			//找到一条路径时返回真}for (di=0;di<4;di++)		//循环扫描每个方位,把每个可走的方块插入队列中{	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){e.i=i1; e.j=j1; e.pre=qu->front;	//指向路径中上一个方块的下标enQueue(qu,e);		//(i1,j1)方块进队mg[i1][j1]=-1;		//将其赋值-1,以避免回过来重复搜索}}}DestroyQueue(qu);			//销毁队列return false;				//未找到任何路径时返回假
}
int main()
{mgpath1(1,1,M,N);return 1;
}

c实现

#define  _crt_secure_no_warnings 1
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
//求解迷宫问题
#define m 8
#define n 8
#define maxsize 2000
int ma[m+2][n+2] = {{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}
};
typedef struct
{int i, j;//当前坐标int pre;//前一个步在队列中的下标int di;
}box;//每一个结点的数据
typedef struct
{box data[maxsize];int front, rear;	
}sqqueue;
sqqueue* initqueue()
{sqqueue* s = (sqqueue*)malloc(sizeof(sqqueue));s->front = s->rear = -1;return;
}
bool enqueue(sqqueue* s, box e)
{if (s->rear == maxsize - 1) return false;s->rear++;s->data[s->rear] = e;return true;
}
bool queueempty(sqqueue* s)
{return (s->front == s->rear);
}
bool dequeue(sqqueue* s, box* e)
{if (s->front == s->rear) return false;s->front++;*e = s->data[s->front];return true;
}
void destroyqueue(sqqueue* s)
{free(s);
}
bool mgpath(int xi, int yi, int xe, int ye)
{void print(sqqueue * s, int front);int front;sqqueue* s = initqueue();box* e = (box*)malloc(sizeof(box));int i=0, j=0, di=-1;e->i = xi, e->j = yi, e->di = -1,e->pre = -1;int i1=0, j1=0;enqueue(s,*e);ma[xi][yi] = -1;while (!queueempty(s)){dequeue(s, e);i = e->i, j = e->j;di = e->di;if (i == xe && j == ye){printf("迷宫路径如下:\n");print(s,s->front);return true;}while (di < 3){di++;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 (!ma[i1][j1]){e->i = i1, e->j = j1, e->di =-1, e->pre = s->front;enqueue(s, *e);ma[i1][j1] = -1;}}}destroyqueue(s);return false;
}
void print(sqqueue* s,int front)
{box path[maxsize];int p = front, k = 0;int i;while (p != -1){path[k++] = s->data[p];p = s->data[p].pre;}for (i = k - 1; i >= 0; i--){printf("\t(%d,%d) ", path[i].i, path[i].j);if ((k - i) % 5 == 0) printf("\n");}printf("\n");
}
int main()
{if (!mgpath(1, 1, 8, 8)) printf("此迷宫无解\n");return 0;}

总结:

总结此题利用队列和栈的特点来解决,需要对栈和队列有一定的理解,如果还没学到栈和队列的话建议学完再完成。

最后给(本蒟蒻)点个赞哒


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/524105.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

高达100亿美元!美国国防部将IBM和甲骨文双双踢出了云计算合同;华为任正非说了,华为对向苹果等对手出售5G芯片保持开放的态度...

关注并标星星CSDN云计算极客头条&#xff1a;速递、最新、绝对有料。这里有企业新动、这里有业界要闻&#xff0c;打起十二分精神&#xff0c;紧跟fashion你可以的&#xff01;每周三次&#xff0c;打卡即read更快、更全了解泛云圈精彩newsgo go go 微软全数位版本Xbox One S&a…

OpenGL 灰度图

目录 一.OpenGL 灰度图 1.IOS Object-C 版本1.Windows OpenGL ES 版本2.Windows OpenGL 版本 二.OpenGL 灰度图 GLSL Shader三.猜你喜欢 零基础 OpenGL ES 学习路线推荐 : OpenGL ES 学习目录 >> OpenGL ES 基础 零基础 OpenGL ES 学习路线推荐 : OpenGL ES 学习目录 &…

将Github中Fork的代码,克隆到本地

将Github中Fork的代码&#xff0c;克隆到本地 1. 在Github打开Fork的工程2. 单击clone or download按钮&#xff0c;复制Github克隆链接3.进入本地需要存储应用源程序的路径 将源代码clone到本地 1. 在Github打开Fork的工程 登录Github&#xff0c;点击Fork的项目即可&#xf…

Windows OpenGL ES 图像灰度图

目录 一.OpenGL ES 图像灰度图 1.原始图片2.效果演示 二.OpenGL ES 图像灰度图源码下载三.猜你喜欢 零基础 OpenGL ES 学习路线推荐 : OpenGL ES 学习目录 >> OpenGL ES 基础 零基础 OpenGL ES 学习路线推荐 : OpenGL ES 学习目录 >> OpenGL ES 特效 零基础 Open…

VMware竟然出了一款防火墙

戳蓝字“CSDN云计算”关注我们哦&#xff01;极客头条&#xff1a;速递、最新、绝对有料。这里有企业新动、这里有业界要闻&#xff0c;打起十二分精神&#xff0c;紧跟fashion你可以的&#xff01;防火墙&#xff0c;这个在安全界“恐龙时代”就存在的产品&#xff0c;相信但凡…

qt项目中的某一个类的输出中文信息乱码,其它类中文输出正常

问题描述 qtcreate5.13.2中整个项目中通过添加头文件&#xff0c;使用qDebug()输出中文打印信息&#xff0c;输出中文都是正常的&#xff0c;但是有一个类的输出中文是乱码。 解决方法 修改该类的编码格式。由于项目默认采用的是utf-8编码&#xff0c;但此类的编码采用的是G…

Navicat创建数据库表 、导入sql文件,生成表结构

Navicat创建数据库表 、导入sql文件&#xff0c;生成表结构 1.打开Navicat2.远程连接mysql连接3.创建数据库4.导入sql文件5.生成表结构 1.打开Navicat 2.远程连接mysql连接 3.创建数据库 4.导入sql文件 导入源代码中的sql文件 5.生成表结构

将本地源代码程序推送远程Github仓库

将本地源代码程序推送远程Github仓库 1.查看改动文件的状态2.将修改的代码从工作区添加至暂存区3.将暂存区的代码添加至本地仓库4.将本地仓库中的代码Push到Github5.登录Github&#xff0c;查看是否推送代码成功 1.查看改动文件的状态 git status2.将修改的代码从工作区添加至…

OpenStack网络的下一步原来这么走 | 技术头条

戳蓝字“CSDN云计算”关注我们哦&#xff01;技术头条&#xff1a;干货、简洁、多维全面。更多云计算精华知识尽在眼前&#xff0c;get要点、solve难题&#xff0c;统统不在话下&#xff01;最新版本的OpenStack Stein很快就要发布了&#xff0c;社区将在4月10日一起庆祝。对于…

qt5.13.2输出中文乱码

qt5使用qDebug()输出中文乱码&#xff0c;可以在.pro文件中添加以下的代码&#xff1a; #解决中文编译没法通过&#xff0c;输出中文乱码 msvc {QMAKE_CFLAGS /utf-8QMAKE_CXXFLAGS /utf-8 }

Windows OpenGL 图像灰度图

目录 一.OpenGL 图像灰度图 1.原始图片2.效果演示 二.OpenGL 图像灰度图源码下载三.猜你喜欢 零基础 OpenGL ES 学习路线推荐 : OpenGL ES 学习目录 >> OpenGL ES 基础 零基础 OpenGL ES 学习路线推荐 : OpenGL ES 学习目录 >> OpenGL ES 特效 零基础 OpenGL ES …

Spring精华问答 | 什么是Spring inner beans?

Spring框架是一个开源的Java平台,它提供了非常容易,非常迅速地开发健壮的Java应用程序的全面的基础设施支持。今天就让我们来看看关于Spring的精华问答吧。1Q&#xff1a;请解释Spring Bean的生命周期&#xff1f;A&#xff1a;Spring Bean的生命周期简单易懂。在一个bean实例被…

gb-heima/order 项目 处理

gb-heima/order 项目 处理 1. 用Intellij Idea打开克隆好的项目2. 代码源程序简要说明3. 使用Maven构建该项目 1. 用Intellij Idea打开克隆好的项目 2. 代码源程序简要说明简要说明代码源程序 3. 使用Maven构建该项目 在Intellij Idea中使用Maven构建该项目Maven 构建项目

qt使用自带的日志输出实例输出日志时,在日志中显示行数

当使用qInstallMessageHandler&#xff08;&#xff09;安装回调函数&#xff0c;通过回调函数来输出日志时&#xff0c;日志文件中没有行数和文件信息。可以在.pro文件中添加以下代码&#xff1a; #release中在日志添加行数&#xff0c;文件信息 DEFINES QT_MESSAGELOGCONTE…

Windows OpenGL ES 图像单色

目录 一.OpenGL ES 图像单色 1.原始图片2.效果演示 二.OpenGL ES 图像单色源码下载三.猜你喜欢 零基础 OpenGL ES 学习路线推荐 : OpenGL ES 学习目录 >> OpenGL ES 基础 零基础 OpenGL ES 学习路线推荐 : OpenGL ES 学习目录 >> OpenGL ES 特效 零基础 OpenGL E…

要闻君说:特斯拉重磅推出影响力报告;三星官宣完成5纳米EUV工艺研发还承诺提供样品;国内首条5G智能制造生产线正式“上马”...

关注并标星星CSDN云计算极客头条&#xff1a;速递、最新、绝对有料。这里有企业新动、这里有业界要闻&#xff0c;打起十二分精神&#xff0c;紧跟fashion你可以的&#xff01;每周三次&#xff0c;打卡即read更快、更全了解泛云圈精彩newsgo go go 连续三天跌停的视觉中国股票…

运行Jenkins部署任务

一、运行Jenkins部署任务 1. 执行Jenkins部署任务2. 打开浏览器访问部署应用程序3. 确定发布结果的正确性4. 确认执行结果成功 1. 执行Jenkins部署任务 查看控制台输出 异常信息如下&#xff1a; Started by user admin Running as SYSTEM Building remotely on TestEnv in w…

Windows OpenGL 图像单色

目录 一.OpenGL 图像单色 1.原始图片2.效果演示 二.OpenGL 图像单色源码下载三.猜你喜欢 零基础 OpenGL ES 学习路线推荐 : OpenGL ES 学习目录 >> OpenGL ES 基础 零基础 OpenGL ES 学习路线推荐 : OpenGL ES 学习目录 >> OpenGL ES 特效 零基础 OpenGL ES 学习…

QMap删除其中的保存的元素本身,并删除容器中保存的元素

前言 qmap删除元素可以采用erase(),但使用过程中却必须注意以下&#xff1a; qmap中的元素被删除后&#xff0c;其迭代器自动指向下一个元素&#xff1b; 示例 要求删除创建时保存在QMap中的指针&#xff0c;并将qmap中的元素删除。下面直接上代码。 QMap<int,QPushButt…

创建Jenkins自动化部署任务

创建Jenkins自动化部署任务 1. 创建Jenkins任务2. 填写Server信息3. 配置Git参数4. 填写构建语句&#xff0c;实际部署测试环境 1. 创建Jenkins任务 【新建Item】-【输入任务名称】 添加任务描述 限制项目的运行节点 2. 填写Server信息 【登录github】-【打开order项目】-【复…