用栈和队列分别实现求解迷宫问题(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;								//定义栈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;

}

总结:

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

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


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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

rhel7/centos7升级openssh到openssh9.5-p1

openssh9.3-p2以下版本有如下漏洞 在rhel7.4/7.5/7.6均做过测试。 本文需要用到的rpm包如下&#xff1a; https://download.csdn.net/download/kadwf123/88652359 升级步骤 1、升级前启动telnet ##升级前启动telnet服务 yum -y install telnet-server yum -y install xinetd…

四、UART_阻塞发送中断接收

1、开发环境 (1)Keil MDK: V5.38.0.0 (2)MCU: mm320163D7P 2、实验目的&原理图 2.1、实验目的 (1)上位机串口助手给MCU发送信息&#xff0c;MCU串口通过通过串口助手接收后&#xff0c;将接收到的内容通过串口助手发送到上位机。 (2)串口在whil循环中每隔1秒发送一次…

制作自己的 Docker 容器

软件开发最大的麻烦事之一&#xff0c;就是环境配置。用户必须保证操作系统的设置&#xff0c;各种库和组件的安装&#xff0c;只有它们都正确&#xff0c;软件才能运行。docker从根本上解决问题&#xff0c;软件安装的时候&#xff0c;把原始环境一模一样地复制过来。 以 koa-…

Python 序列之列表

系列文章目录 Python序列之元组 Python序列之列表 系列文章目录[TOC](Python序列之列表) 前言一、序列是什么&#xff1f;二、列表1.列表简介2.列表创建&#xff08;1&#xff09;[]创建&#xff08;2&#xff09;list创建&#xff08;3&#xff09;range()创建整数列表&#…

VS2010推荐字体设置

fixedsys excelsior是VS2010推荐字体。下载地址为 链接&#xff1a;https://pan.baidu.com/s/16OFbjBEF35zRfQe04Jfuag 提取码&#xff1a;wzjj下载成功后将ttf文件复制粘贴到C盘Windows中的font文件夹中自动安装指定字体&#xff0c;此时就可以在VS2010的工具&#xff0c;选…

多维时序 | MATLAB实CNN-Mutilhead-Attention卷积神经网络融合多头注意力机制多变量时间序列预测

多维时序 | MATLAB实CNN-Mutilhead-Attention卷积神经网络融合多头注意力机制多变量时间序列预测 目录 多维时序 | MATLAB实CNN-Mutilhead-Attention卷积神经网络融合多头注意力机制多变量时间序列预测预测效果基本介绍模型描述程序设计参考资料 预测效果 基本介绍 多维时序 | …

下定决心了,从字节跳动离职

今天在脉脉上看到这么一条内容&#xff1a; 看完感触很深&#xff0c;想起了我在帝都上班的那几年时光。 我记得我去帝都上班的时候&#xff0c;第一次坐帝都的地铁&#xff0c;那时候是找工作面试&#xff0c;在地铁里第一次感受到了大城市的上班速度&#xff0c;每个人都急匆…

龙芯杯个人赛串口——做一个 UART串口——RS-232

文章目录 Async transmitterAsync receiver1. RS-232 串行接口的工作原理DB-9 connectorAsynchronous communicationHow fast can we send data? 2.波特率时钟生成器Parameterized FPGA baud generator 3.RS-232 transmitter数据序列化完整代码&#xff1a; 4.RS-232 receiver…

Dijkstra(迪杰斯特拉)算法总结

知识概览 Dijkstra算法适用于解决所有边权都是正数的最短路问题。Dijkstra算法分为朴素的Dijkstra算法和堆优化版的Dijkstra算法。朴素的Dijkstra算法时间复杂度为&#xff0c;适用于稠密图。堆优化版的Dijkstra算法时间复杂度为&#xff0c;适用于稀疏图。稠密图的边数m和是一…

tensorboard可视化——No dashboards are active for the current data set.

No dashboards are active for the current data set. 出现问题的原因是事件的路径未用绝对路径&#xff0c;tensorboard --logdir./runs --port6007 改为tensorboard --logdirD:\Code\Python\Study\CL\hat-master\hat-master\run s\one --port6007就好了

浅谈Dubbo核心概念及架构流程

浅谈Dubbo核心概念及架构流程 前言重要概念1、SPI2、ServiceBean3、URL4、Invoker 整体流程1、架构图2、调用链路 笔者碎碎言&#xff0c;我们学习Dubbo应该学的是什么&#xff1f; 笔者是一名业务开发&#xff0c;认为一切目的都要为我们的目标服务&#xff0c;即日常工作有帮…

Android 13 - Media框架(26)- OMXNodeInstance(三)

上一节我们了解了OMXNodeInstance中的端口定义&#xff0c;这一节我们一起来学习ACodec、OMXNode、OMX 组件使用的 buffer 到底是怎么分配出来的&#xff0c;以及如何关联起来的。&#xff08;我们只会去了解 graphic buffer的创建、input bytebuffer的创建、secure buffer的创…

20231223使用Rockchip原厂的Android11调通Firefly的AIO-3399J开发板上的AP6356S

20231223使用Rockchip原厂的Android11调通Firefly的AIO-3399J开发板上的AP6356S 2023/12/23 14:14 开发板&#xff1a;Firefly的AIO-3399J【RK3399】 SDK&#xff1a;rk3399-android-11-r20211216.tar.xz【Android11】 Android11.0.tar.bz2.aa【ToyBrick】 Android11.0.tar.bz2…

[Angular] 笔记 8:list/detail 页面以及@Input

1. list 页面 list/detail 是重要的 UI 设计模式。 vscode terminal 运行如下命令生成 detail 组件&#xff1a; PS D:\Angular\my-app> ng generate component pokemon-base/pokemon-detail --modulepokemon-base/pokemon-base.module.ts CREATE src/app/pokemon-base/p…

SQL进阶:子查询

一般情况下,我们都是直接对表进行查询,但有时候,想要的数据可能通过一次select 获取不到,需要嵌套select,这样就形成了子查询。 子查询可以位于查询语句的任意位置,主要的注意点在于用于不同的位置,和不同的关键字一起使用时,需要注意返回的列的数量和行的数量。 位于…

大一C语言查缺补漏 12.24

遗留问题&#xff1a; 6-1 1 在C语言中&#xff0c;如果要保留小数的话&#xff0c;一定要除以2.0&#xff0c;而不是2。 设整型变量m,n,a,b的值均为1&#xff0c;执行表达式&#xff08;m a>b&#xff09;||(n a<b)后&#xff0c;表达式的值以及变量m和n的值是&#…

redis怎么查看bigkey

通过docker-compose启动一个redis服务器 docker-compose.yml文件的内容如下&#xff1a; version: 3 services:redis:image: redisports:- 6379:6379docker-compose up -d 启动redis容器 在服务器上安装redis-cli工具 这里我是ubuntu服务器&#xff0c;centos用yum代替apt安…

[机器人-2]:开源MIT Min cheetah机械狗设计(二):机械结构设计

目录 1、四肢朝向的选择 2、电机布局形式的选择 3、电机的选型及测试&#xff08;非常重要&#xff09; 4、结构优化 5、尺寸效应 6、其他 1、四肢朝向的选择 机械狗的结构设计&#xff0c;第一个摆在我们面前的就说四肢的朝向问题&#xff0c;如下图&#xff0c;我们是…

C++类的继承

目录 什么是继承&#xff1f; 父类与子类对象的赋值转换 继承中的作用域问题 子类的默认成员函数问题 如何使一个类不能被继承&#xff1f; 父类的友元和静态成员变量 多重继承与菱形继承 继承和组合 什么是继承&#xff1f; 继承 (inheritance) 机制是面向对象程序设…

继承易错总结

1.继承会将所有的成员继承下来&#xff0c;但是继承方式限定的是继承下来成员的可见类型(如果是private继承&#xff0c;那么他不论哪里都是不可见的&#xff1b;如果是protected继承在类中是可见的&#xff0c;在类外是不可见的&#xff1b;如果是public继承&#xff0c;在任何…