迷宫算法(经典广度优先搜索算法)

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

经典广度优先搜索算法,用parentx,parenty存储上一步的位置,规范化使用队列和栈。

迷宫暂定为8*6,动态生成,四周为一圈障碍,出口坐标为(8,6)。

坐标的定义类似图形编程的屏幕坐标,横向为x分量,垂直为y分量,左上角为原点。

可以向8个方向试探。

源代码(TC下编译运行通过):
#include <stdio.h>
#include <stdlib.h>
#define Status int
#define OK 1
#define ERROR 0
#define OVERFLOW -2
#define TRUE 1
#define FALSE 0
#define ROW 8 /*行列可自定*/
#define COLUM 10 /*行列可自定*/
#define OUT 8
#define STEPPED 2
#define MAXQSIZE 100
int maze[8][10]/*6行8列*/
={{1,1,1,1,1,1,1,1,1,1},
{1,0,1,1,1,1,0,0,0,1},
{1,0,1,0,0,1,1,0,0,1},
{1,0,0,0,1,0,1,0,0,1},
{1,1,1,0,1,0,1,0,0,1},
{1,0,0,0,0,0,0,0,0,1},
{1,0,0,0,0,0,0,1,OUT,1},
{1,1,1,1,1,1,1,1,1,1}};/*此处只是给一个初始化的例子,可以删去,后面的代码可以动态生成迷宫*/
void CreateRandomMaze()/*随机生成迷宫(可能产生走不通的迷宫)*/
{
int i,j;
srand((int)time());/*设置随机数种子,产生真随机数*/
for(i=0;i<ROW;i++)
{
for(j=0;j<COLUM;j++)
{
maze[i][j]=rand()%2;/*产生0~1的随机数*/
}
}
for(i=0;i<COLUM;i++)
{
maze[0][i]=1;
maze[ROW-1][i]=1;
}
for(i=0;i<ROW;i++)
{
maze[i][0]=1;
maze[i][COLUM-1]=1;
}
maze[1][1]=0;
maze[ROW-2][COLUM-2]=OUT;/*设置出口*/
}
void printMaze()/*打印迷宫*/
{
int i,j;
/*clrscr();*//*这个是turbo C的清屏函数,可以替代或忽略*/
for(i=0;i<ROW;i++)
{
for(j=0;j<COLUM;j++)
{
printf(" %d",maze[i][j]);
}
printf("\n");
}
/*delay(1000);*/
}
/*********************队列(非循环顺序队列)************************/
typedef struct
{
int x,y;
int parentx,parenty; /*记录上一个节点即路径中前驱节点,方便最后输出*/ }QNode,*QueuePtr;
typedef QNode ElemType;
typedef struct SqQueue
{
ElemType * base;
int front;
int rear;
}SqQueue;/*队列结构体*/
Status InitQueue(SqQueue *Q)/*初始化队列*/
{
Q->base = (ElemType *)malloc(MAXQSIZE *sizeof(ElemType)); if(!Q->base)
{exit(OVERFLOW);}
Q->front = Q->rear = 0;
return OK;
}
int QueueLength(SqQueue Q)
{
return Q.rear - Q.front;
}
Status QueueEmpty(SqQueue Q)
{
if(Q.front==Q.rear)
{return TRUE;}
return FALSE;
}
Status GetHead(SqQueue Q,ElemType *e)
{
if(Q.front==Q.rear)
{return ERROR;}
*e = Q.base[Q.front];
return OK;
}
Status EnQueue(SqQueue *Q,ElemType e)
{
if(Q->rear>MAXQSIZE-1)/*队列满*/
{return ERROR;}
Q->base[Q->rear]=e;
(Q->rear)++;
return OK;
}
Status DeQueue(SqQueue *Q,ElemType *e) {
if(Q->front == Q->rear)/*队列空*/
{return ERROR;}
*e = Q->base[Q->front];
(Q->front)++;
return OK;
}
/*********************栈**********************/ typedef struct
{
int top,base,count;
ElemType container[100];/*ROW*COLUM];*/ }SqStack;
Status InitStack(SqStack *s)
{
s->top=-1;
s->base=0;
s->count=0;
}
Status StackEmpty(SqStack s)
{
if(s.count!=0)
{return FALSE;}
return TRUE;
}
Status Push(SqStack *s,ElemType e)
{
s->top++;
s->container[s->top]=e;
s->count++;
return OK;
}
Status Pop(SqStack *s,ElemType *e)
{
if(s->top<s->base)
{return ERROR;}
*e = s->container[s->top];
s->count--;
}
/*******************************************/
main()
{
int dx[]={ 0, 1,1,1,0,-1,-1,-1}; /*方向偏移量*/
int dy[]={-1,-1,0,1,1, 1, 0,-1};
int direction,flag, /*找到出口标志*/
cx,cy, /*当前位置坐标*/
nx,ny; /*根据方向下一点坐标*/
SqQueue sqq;
SqStack sqs,sqsout;
ElemType start,et;
CreateRandomMaze();/*创建随机地图*/
printMaze();/*打印地图*/
InitQueue(&sqq); /*初始化队列sqq*/
InitStack(&sqs); /*初始化栈sqs*/
InitStack(&sqsout); /*初始化栈sqsout*/
start.x=1;
start.y=1;
start.parentx=-1;
start.parenty=-1;
EnQueue(&sqq,start); /*起始点入队*/
for(;(flag!=TRUE)&&(!QueueEmpty(sqq));)
{
GetHead(sqq,&et); /*取队首元素(不是出队)*/
cx=et.x;
cy=et.y;
for(direction=0;direction<8;direction++) /*朝八个方向试探*/
{
nx = cx+dx[direction]; /*nx = cx + 方向偏移量*/
ny = cy+dy[direction];
if(maze[ny][nx]==0||maze[ny][nx]==OUT) /*如果下一点坐标可通,或者是出口*/ {
et.y=ny;
et.parentx = cx; /*下一点的路径上的前驱是当前点*/
et.parenty = cy;
EnQueue(&sqq,et); /*将下一点入队*/
if(maze[ny][nx]!=OUT)
{maze[ny][nx]=STEPPED; /*访问过了*/}
}
if(maze[ny][nx]==OUT) /*如果下一点是出口*/
{
flag = TRUE; /*标志位置TRUE*/
break; /*路径已找到,不用在试探了,退出循环*/
}
}
DeQueue(&sqq,&et);/*出队*/
Push(&sqs,et);/*所有出队的元素都将别压入栈sqs*/
}
if(QueueEmpty(sqq)) /*如果每条路线都试过都没有找到出口,则队列为空,说明已经失败了*/ {
printf("failed!");
}
if(flag==TRUE) /*如果标记为是TRUE,那么说明已经找到路径了,广度优先所的路径即为最短路径*/ {
while(!QueueEmpty(sqq))
{
DeQueue(&sqq,&et);
Push(&sqs,et);
}
/******以下用到了两个栈,第一个栈sqs用来搜索最短路径并把其存入第二个栈,第二个栈sqsout用于顺序输出********/
Pop(&sqs,&start);
Push(&sqsout,start);
while(!StackEmpty(sqs))
{
Pop(&sqs,&et);
if(et.x==start.parentx && et.y==start.parenty)
{
start=et;
Push(&sqsout,et);
}
}
while(!StackEmpty(sqsout)) {
Pop(&sqsout,&et);
printf("(%d,%d)\t",et.x,et.y); }
}
}。

相关文档
最新文档