数据结构学习之队列破解迷宫
数据结构学习之队列破解迷宫
0x1 问题描述
目的:掌握队列在求解迷宫问题中的应用。
内容:编写一个程序,求第一条最短路径长度及最短路径。
0x2 解答代码
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <stack>
#define MaxSize 10000+7
#define M 8
#define N 8
using namespace std;
typedef int ElemType;
//typedef ElemType Box;
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; //position
int pre; //前面指针
}Box; //type of block
int next[4][2] ={{-1,0},{0,1},{1,0},{0,-1}};
typedef struct
{
Box data[MaxSize]; //domain of data
int front,rear;
}QuType; //type of queue
//Init queue
void InitQueue(QuType *&q)
{
q = (QuType *)malloc(sizeof(QuType));
q->front=q->rear=-1;
return;
}
//Entry queue
bool EnQueue(QuType *&q, Box e)
{
//if full?
if(q->rear==MaxSize-1)
return false;
q->rear++;
q->data[q->rear]=e;
return true;
}
//Leave queue
bool DeQueue(QuType *&q, Box &e)
{
// if empty
if(q->front==q->rear)
return false;
q->front++;
e=q->data[q->front];
return true;
}
// judge empty
bool EmptyQueue(QuType *q)
{
return(q->rear==q->front);
}
// Destroy queue
void DestroyQueue(QuType *&q)
{
free(q);
}
void print(QuType *q,int front)
{
//stack<Box> s;
int k=front,j,ns=0;
//cout<< k <<endl;
/*
while(k>0)
{
printf("k:%d (%d,%d) pre:%d\n",k,q->data[k].i,q->data[k].j,q->data[k].pre);
k--;
}
*/
do
{
j=k;
k=q->data[k].pre;
//cout<< k <<endl;
q->data[j].pre=-1;
}while(k!=0);
//return;
printf("一条迷宫路径如下: \n");
k=0;
while(k<MaxSize)
{
if(q->data[k].pre==-1)
{
ns++;
printf("\t(%d,%d)",q->data[k].i,q->data[k].j);
if(ns%5==0)
printf("\n");
}
k++;
}
printf("\n");
/*
int k=front;
while(q->data[front].pre!=-1)
{
//s.push(q->data[front]);
q->data[front+1].pre=-1;
q->front=q->data[front].pre;
}
//s.push(q->data[1]);
printf("the least path of map:\n");
int ns=1;
while(!s.empty())
{
//s.pop();
ns++;
//printf("%\t(%d,%d)",e.i,e.j);
if(ns%5==0)
printf("\n");
}
*/
printf("Length:%d",ns);
}
void myprint(QuType *q,int front)
{
stack<Box> s;
while(q->front!=-1)
{
s.push(q->data[q->front]);
q->front=q->data[q->front].pre;
}
printf("一条迷宫路径如下:\n");
int ns=0;
while(!s.empty())
{
Box e=s.top();
s.pop();
ns++;
printf("\t(%d,%d)",e.i,e.j);
if(ns%5==0)
printf("\n");
}
printf("\nLength:%d\n",ns);
}
bool mgpath(int x,int y,int ex,int ey)
{
Box e;
//use a queue
QuType *q;
InitQueue(q);
// enter queue
e.i=x;
e.j=y;
e.pre=-1;
EnQueue(q,e);
mg[x][y]=-1;
while(!EmptyQueue(q))
{
DeQueue(q,e);
//cout<< e.i << e.j<<endl;
//break;
//出错重灾区,遍历应该用新的变量
int il=e.i,jl=e.j;
if(il==ex && jl==ey)
{
//print(q,q->front); //书本例题 感觉太浪费了
myprint(q,q->front);
DestroyQueue(q);
return true;
}
for(int i=0;i<4;i++)
{
//cout<<next[i][0]<<","<<next[i][1]<<endl;
int xi=il + next[i][0];
int yi=jl + next[i][1];
//cout<< xi << "," <<yi <<endl;
if(mg[xi][yi]==0)
{
//cout<< xi <<","<< yi<<endl;
e.pre=q->front;
e.i=xi;
e.j=yi;
EnQueue(q,e);
mg[xi][yi]=-1;
}
}
}
DestroyQueue(q);
return false;
}
int main()
{
int sx=1,sy=1,ex=8,ey=8;// start point and end point
if(!mgpath(sx,sy,ex,ey))
printf("can't solve this problem!");
return 0;
}
0x3 结果
0x4 总结
这个BFS我调试了3.4个小时,原因竟然是在for循环遍历外圈的时候,没有新建变量去接收int new=e.i+next[i][0]
导致变量被覆盖,一直没解出结果,归根到底还是自己学的太水了。