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

news2024/9/28 3:27:41

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

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


可用两种方法实现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;								//定义栈st
	InitStack(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);						//取栈顶方块e
		i=e.i; j=e.j; di=e.di;
		if (i==xe && j==ye)					//找到了出口,输出该路径
		{ 
			printf("一条迷宫路径如下:\n");
			k=0;							//累计路径中的方块个数 
			while (!StackEmpty(st))
			{
				Pop(st,e);					//出栈方块e
				path[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++;						//队尾增1
	q->data[q->rear]=e;				//rear位置插入元素e
	return 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;						//定义顺序队指针qu
	InitQueue(qu);					//初始化队列qu
	e.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.coloradmin.cn/o/1334156.html

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

相关文章

压力应变电桥信号隔离放大变送器差分输入变送直流模块0-10mV/0-20mV/0-±10mV/0-±20mV转0-5V/0-10V/4-20mA

主要特性 DIN11 IPO 压力应变桥信号处理系列隔离放大器是一种将差分输入信号隔离放大、转换成按比例输出的直流信号导轨安装变送模块。产品广泛应用在电力、远程监控、仪器仪表、医疗设备、工业自控等行业。此系列模块内部嵌入了一个高效微功率的电源&#xff0c;向输入端和输…

TikTok音频书籍:通过短音频探索全新阅读体验

在数字时代&#xff0c;社交媒体平台不仅改变了人们获取信息的方式&#xff0c;还推动了传统媒体的创新。TikTok&#xff0c;作为一款全球短视频平台&#xff0c;不仅塑造了用户的娱乐方式&#xff0c;还成为一种创新的阅读平台。本文将深入探讨TikTok音频书籍的兴起&#xff0…

第二证券:A股“磨底”中等待向上突破

A股“磨底”中等候向上打破。从A股两市成交额、首要指数估值和风险溢价看&#xff0c;当时A股处于中长时刻底部区间&#xff0c;投资者倾向于将中长时刻问题在短期定价&#xff0c;市场风险偏好还有待修正。工作装备上&#xff0c;年底板块轮动加速将成为首要特征&#xff0c;大…

【数据结构和算法】删掉一个元素以后全为 1 的最长子数组

其他系列文章导航 Java基础合集数据结构与算法合集 设计模式合集 多线程合集 分布式合集 ES合集 文章目录 其他系列文章导航 文章目录 前言 一、题目描述 二、题解 2.1 方法一&#xff1a;滑动窗口 2.2 滑动窗口解题模板 三、代码 3.1 方法一&#xff1a;滑动窗口 四…

全平台跨境电商产品数据采集商品详情API接口

跨境电商模式&#xff0c;有很多的小伙伴们自己不备货&#xff0c;而是做搬货&#xff0c;电商数据运营的小伙伴们应该非常头疼每天的数据采集导出-整理的日常&#xff0c;今天介绍一款全平台电商数据采集API接口 独立站卖家导航&#xff1a; 独立站产品数据采集&#xff1a; …

微服务-springcloud(eureka实践, nacos实践)

Spring 体系图 版本关系 eureka 实践 1 父工程依赖 <parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.6.14</version> </parent> <dependencyManage…

【每日一题】不浪费原料的汉堡制作方案

文章目录 Tag题目来源解题思路方法一&#xff1a;解方程 写在最后 Tag 【解方程】【2023-12-25】 题目来源 1276. 不浪费原料的汉堡制作方案 解题思路 方法一&#xff1a;解方程 思路 这是一个简单的解决二元一次方程的问题。 根据题意有以下关系式&#xff1a; { t o t …

【MybatisPlus快速入门】(2)SpringBoot整合MybatisPlus 之 标准数据层开发 代码示例

目录 1 标准CRUD使用2 新增3 删除4 修改5 根据ID查询6 查询所有7 MyBatis-Plus CRUD总结 之前我们已学习MyBatisPlus在代码示例与MyBatisPlus的简介&#xff0c;在这一节中我们重点学习的是数据层标准的CRUD(增删改查)的实现与分页功能。代码比较多&#xff0c;我们一个个来学习…

C++ boost planner_cond_.wait(lock) 报错1225

1.如下程序段 boost unique_lock doesn’t own the mutex: Operation not permitted 问题&#xff1a; 其中makePlan是一个线程。这里的unlock导致错误这个报错 boost unique_lock doesn’t own the mutex: Operation not permitted bool navigation::makePlan(){ //cv::named…

如何挑选便宜好用的VPS?解读Amazon Lightsail的优势

随着云计算技术的不断发展&#xff0c;VPS&#xff08;Virtual Private Server&#xff0c;虚拟私有服务器&#xff09;已成为许多企业和个人网站托管的首选。VPS将服务器资源隔离&#xff0c;使得用户可以获得更高的安全性和独立性&#xff0c;同时提供了更好的性能和扩展性。…

图片素材管理软件Eagle for mac提高素材整理维度

Eagle for mac是一款图片素材管理软件&#xff0c;支持藏网页图片&#xff0c;网页截屏&#xff0c;屏幕截图和标注&#xff0c;自动标签和筛选等功能&#xff0c;让你设计师方便存储需要的素材和查找&#xff0c;提供工作效率。 Eagle mac软件介绍 Eagle mac帮助你成为更好、…

springCould中的zookeeper-从小白开始【3】

目录 1.启动zookeeper❤️❤️❤️ 2.创建8004模块 ❤️❤️❤️ 3.临时节点还是永久节点❤️❤️❤️ 4.创建zk80消费模块❤️❤️❤️ 1.启动zookeeper❤️❤️❤️ 进入自己zookeeper的bin目录下 分别使用命令&#xff1a; ./zkServer.sh start 和 ./zkCli.sh -serve…

RHCE9学习指南 第8章 用户管理

8.1 基本概念 用户在操作系统中是非常重要的一块&#xff0c;我们登录系统&#xff0c;访问共享文件夹等都需要用户进行验证。所以&#xff0c;掌握管理用户的知识是非常有必要的。 说到用户&#xff0c;我们会提到两个名词账户信息和木马信息。 账户信息&#xff1a;我们可以…

TikTok与环保:短视频如何引领可持续生活方式?

在数字时代&#xff0c;社交媒体平台扮演着塑造文化和价值观的关键角色。而TikTok&#xff0c;作为一款全球短视频平台&#xff0c;不仅塑造着用户的娱乐方式&#xff0c;还在悄然地引领着可持续生活方式的潮流。本文将深入探讨TikTok与环保之间的关系&#xff0c;分析短视频如…

Vue编写登录注册页面前端校验

登录注册校验 template页面 <div class"app-login"><!--登录 --><div class"form"><el-form ref"form" size"large" autocomplete"off" v-if"isLogin" :model"registerData" :r…

2023.12.24 关于 Redis 中 String 类型内部编码 及 应用场景

目录 String 类型内部编码 3 种内部编码方式 String 类型应用场景 Cache 缓存 键名命名规则 计数&#xff08;Counter&#xff09; 共享会话&#xff08;Session &#xff09; 手机验证码 总结 String 类型内部编码 3 种内部编码方式 int&#xff1a;用来表示 64 位 —…

计算机网络基础知识分享

计算机网络基础知识分享 发送一个http请求&#xff0c;从客户端到服务器端&#xff0c;都经历了什么? **Ⅰ&#xff0c;浏览器生成消息 ** &#xff08;1&#xff09;浏览器输入网址 我们的探索之旅从在浏览器中输入网址开始&#xff0c;网址&#xff0c;准确来说应该叫 UR…

鸿蒙4.0基础开发教程

开发准备 熟悉鸿蒙官网安装DevEco studio开发工具 熟悉官网和安装开发工具视频,本套笔记基于这套视频所写 ArkTS语言 ArkTs语言文档 例如在页面做个按钮并带有点击效果需要html,css,js共同完成 html(按钮标签)-css(按钮样式)-js(控制按钮点击操作) 当学完了ArkTs即可以同时…

K8S三台服务器一键部署总结

随着互联网、云计算技术的深入发展&#xff0c;为降低企业大规模云应用建设的难度和成本&#xff0c;支持云应用开发、运行与运维一体化的云应用平台软件应运而生。在数通家族中对企业集成套件的云平台开发、部署、管理、运维进行统一管理&#xff0c;实现数据集成和共享的平台…

【Linux系统基础】(6)在Linux上大数据NoSQL数据库HBase集群部署、分布式内存计算Spark环境及Flink环境部署详细教程

大数据NoSQL数据库HBase集群部署 简介 HBase 是一种分布式、可扩展、支持海量数据存储的 NoSQL 数据库。 和Redis一样&#xff0c;HBase是一款KeyValue型存储的数据库。 不过和Redis设计方向不同 Redis设计为少量数据&#xff0c;超快检索HBase设计为海量数据&#xff0c;…