【李春葆教材】用队列实现求解迷宫从入口到出口的一条最短路径(15 分)

声明:这道题在李春葆数据结构教材上有主函数的样例代码,本博客直接引用了书上的代码,仅仅是将前面函数部分和主函数整理组合在一起。

有一个小小地方要注意就是主函数中队列中第一个元素pre值应该赋值为0而不是-1,否则与书中之前列出的队列常用函数中front的初值不匹配,则不能输出结果。

求解迷宫从入口到出口的一条最短路径。输入一个迷宫,求从入口通向出口的一条可行最短路径。为简化问题,迷宫用二维数组 int maze[10][10]来存储障碍物的分布,假设迷宫的横向和纵向尺寸的大小是一样的,并由程序运行读入, 若读入迷宫大小的值是n(3<n<=10),则该迷宫横向或纵向尺寸都是n,规定迷宫最外面的一圈是障碍物,迷宫的入口是maze[1][1],出口是maze[n-2][n-2], 若maze[i][j] = 1代表该位置是障碍物,若maze[i][j] = 0代表该位置是可以行走的空位(0<=i<=n-1, 0<=j<=n-1)。求从入口maze[1][1]到出口maze[n-2][n-2]可以走通的路径。要求迷宫中只允许在水平或上下四个方向的空位上行走,走过的位置不能重复走,规定必须按向右、向下、向左、向上的顺序向前搜索试探,输出先到达出口的最短路径。 如下这样一个迷宫:

 

输入格式:

输入迷宫大小的整数n, 以及n行和n列的二维数组(数组元素1代表障碍物,0代表空位)。

输出格式:

输出按规定搜索试探顺序先到达出口的首条最短路径,依次输出从入口到出口可行最短路径每个位置的行列下标(i,j),每个位置间用“,”分隔。若没有通路,输出:NO。

输入样例1:

4
1 1 1 1
1 0 1 1
1 0 0 1
1 1 1 1

输出样例1:

(1,1)(2,1)(2,2)

这道题在李春葆数据结构教材上有主函数的样例代码,本博客仅仅是将前面函数部分和主函数整理组合在一起。

有一个小小地方要注意就是队列中第一个元素pre值应该赋值为0而不是-1,否则与书中之前列出的队列常用函数中front的初值不匹配,则不能输出结果。

#include<bits/stdc++.h>
#define LL long long
#define el '\n'
#define MaxSize 105

using namespace std;
int mg[11][11];int N;
typedef struct {
	int i,j;
	int pre;
}Box;
typedef Box ElemType;
typedef struct   // 顺序循环队列结点定义
{
    ElemType data[MaxSize];   
    int front,rear;        //队首和队尾指针
} SqQueue;
void InitQueue(SqQueue *&q);   //初始化队列;
void DestroyQueue(SqQueue *&q);  //销毁队列;
bool QueueEmpty(SqQueue *q);  //判定队列为空时返回true; 否则返回false;
bool enQueue(SqQueue *&q,ElemType *&e);  // e 入队;成功入队返回true; 否则返回false;
bool deQueue(SqQueue *&q,ElemType *&e);  //出队,返回出队元素e,且成功出队返回true,否则返回false;
bool path(int x1,int yi,int xe,int ye);
void print(SqQueue *qu,int front);
int main()
{
	int i,j;
	cin>>N;
	for(i=0;i<N;i++)
	for(j=0;j<N;j++)
	cin>>mg[i][j];
	if(!path(1,1,N-2,N-2))
    printf("NO");
	return 0;
}
void InitQueue(SqQueue *&q)   //初始化队列;
{
    q = new SqQueue;
	q->front=0;q->rear=0;
} 
void DestroyQueue(SqQueue *&q) //销毁队列;
{
	q->front = (q->rear + 1) % MaxSize;
} 
bool QueueEmpty(SqQueue *q)//判定队列为空时返回true; 否则返回false;
{
	if(q->rear==q->front)return true;
	else return false;
} 
bool enQueue(SqQueue *&q,ElemType &e) // e 入队;成功入队返回true; 否则返回false;
{
  if((q->rear+1)%MaxSize==q->front)	return false;
  { 
	q->rear = (q->rear+1)%MaxSize;
  	q->data[q->rear]=e;
	return true;
	}
}

bool deQueue(SqQueue *&q,ElemType &e) //出队,返回出队元素e,且成功出队返回true,否则返回false;
{
	if(q->front == q->rear)return false;
	q->front = (q->front+1)%MaxSize;
		e= q->data[q->front];
		return true;
}
bool path(int xi,int yi,int xe,int ye){
	Box e;
	int i,j,di,i1,j1;
	SqQueue *qu;
	InitQueue(qu);
	e.i=xi;e.j=yi;e.pre=0;//注意这里pre要定义为0,书上写的定义为-1不对 
	enQueue(qu,e);
	mg[xi][yi]=-1;
	while(!QueueEmpty(qu)){
		deQueue(qu,e);
		i=e.i;j=e.j;
		if(i==xe&&j==ye){
			print(qu,qu->front);
			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);
				mg[i1][j1]=-1;
			}
		}
	}
	DestroyQueue(qu);
	return false;
}
void print(SqQueue *qu,int front){
	int k=front,j,ns=0;
	do{
		j=k;
		k=qu->data[k].pre;
		qu->data[j].pre=-1;
		
	}while(k!=0);
	k=0;
	while(k<MaxSize){
		if(qu->data[k].pre==-1){
			ns++;
			printf("(%d,%d)",qu->data[k].i,qu->data[k].j);
			
		}
		k++;
	}
	printf("\n");
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值