声明:这道题在李春葆数据结构教材上有主函数的样例代码,本博客直接引用了书上的代码,仅仅是将前面函数部分和主函数整理组合在一起。
有一个小小地方要注意就是主函数中队列中第一个元素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");
}