2021年实训(队列)
今天学习了手打队列,为下个学期的数据结构做准备,例题是一个迷宫问题。
程序设计综合实训-迷宫问题(II)
顺序队列
#include <stdio.h>
#include <stdlib.h>
#define MAX 2505
typedef struct
{
int x;
int y;
int len;
}pos;
typedef struct
{
int front;
int rear;
pos queue[MAX];
}Queue;
typedef Queue * PQueue;
int m,n;
int dir[4][2]={-1,0,1,0,0,-1,0,1},maze[55][55];
PQueue pqueue;
PQueue InitQueue()
{
PQueue pqueue;
pqueue=(PQueue)malloc(sizeof(Queue));
if(pqueue==NULL)
{
printf("InitQueue Error!\n");
exit(1);
}
pqueue->front=0;
pqueue->rear=0;
return pqueue;
}
int IsEmpty(PQueue pqueue)
{
if(pqueue->front==pqueue->rear)
return 1;
else
return 0;
}
void PushQueue(PQueue pqueue,int x,int y,int len)
{
if((pqueue->rear+1)%MAX==pqueue->front)
{
printf("PushQueue Error!\n");
exit(1);
}
pqueue->queue[pqueue->rear].x=x;
pqueue->queue[pqueue->rear].y=y;
pqueue->queue[pqueue->rear].len=len;
pqueue->rear=(pqueue->rear+1)%MAX;
}
void PopQueue(PQueue pqueue,int *x,int *y,int *len)
{
if(IsEmpty(pqueue))
{
printf("PopQueue Error!\n");
exit(1);
}
*x=pqueue->queue[pqueue->front].x;
*y=pqueue->queue[pqueue->front].y;
*len=pqueue->queue[pqueue->front].len;
pqueue->front=(pqueue->front+1)%MAX;
}
int bfs(int start_x,int start_y,int end_x,int end_y)
{
int i,x,y,len,xx,yy;
PushQueue(pqueue,start_x,start_y,0);
maze[start_x][start_y]=1;
while(IsEmpty(pqueue)==0)
{
PopQueue(pqueue,&x,&y,&len);
if(x==end_x&&y==end_y)
return len;
for(i=0;i<4;i++)
{
xx=x+dir[i][0];
yy=y+dir[i][1];
if(xx>-1&&xx<m&&yy>-1&&yy<n&&maze[xx][yy]==0)
{
PushQueue(pqueue,xx,yy,len+1);
maze[xx][yy]=1;
}
}
}
return -1;
}
int main()
{
int i,j,start_x,start_y,end_x,end_y,ans;
scanf("%d%d",&m,&n);
for(i=0;i<m;i++)
for(j=0;j<n;j++)
scanf("%d",&maze[i][j]);
scanf("%d%d%d%d",&start_x,&start_y,&end_x,&end_y);
pqueue=InitQueue();
ans=bfs(start_x,start_y,end_x,end_y);
if(ans>=0)
printf("%d",ans);
else
printf("no path!");
free(pqueue);
return 0;
}
链式队列
#include <stdio.h>
#include <stdlib.h>
#define MAX 2505
typedef struct
{
int x;
int y;
int len;
}pos;
typedef struct Queue
{
pos zb;
struct Queue *next;
}Queue;
typedef Queue * PQueue;
int m,n;
int dir[4][2]={-1,0,1,0,0,-1,0,1},maze[55][55];
PQueue front,rear;
PQueue InitQueue()
{
PQueue head;
head=(PQueue)malloc(sizeof(Queue));
if(head==NULL)
{
printf("InitQueue Error!\n");
exit(1);
}
head->next=NULL;
return head;
}
int IsEmpty(PQueue front,PQueue rear)
{
if(front==rear)
return 1;
else
return 0;
}
PQueue PushQueue(PQueue front,PQueue rear,int x,int y,int len)
{
PQueue pqueue;
pqueue=(PQueue)malloc(sizeof(Queue));
if(pqueue==NULL)
{
printf("PushQueue Error!\n");
exit(1);
}
pqueue->zb.x=x;
pqueue->zb.y=y;
pqueue->zb.len=len;
pqueue->next=NULL;
rear->next=pqueue;
rear=pqueue;
return rear;
}
PQueue PopQueue(PQueue front,PQueue rear,int *x,int *y,int *len)
{
PQueue pqueue;
if(IsEmpty(front,rear))
{
printf("PopQueue Error!\n");
exit(1);
}
pqueue=front->next;
*x=pqueue->zb.x;
*y=pqueue->zb.y;
*len=pqueue->zb.len;
front->next=pqueue->next;
if(rear==pqueue)
rear=front;
free(pqueue);
return rear;
}
int bfs(int start_x,int start_y,int end_x,int end_y)
{
int i,x,y,len,xx,yy;
rear=PushQueue(front,rear,start_x,start_y,0);
maze[start_x][start_y]=1;
while(IsEmpty(front,rear)==0)
{
rear=PopQueue(front,rear,&x,&y,&len);
if(x==end_x&&y==end_y)
return len;
for(i=0;i<4;i++)
{
xx=x+dir[i][0];
yy=y+dir[i][1];
if(xx>-1&&xx<m&&yy>-1&&yy<n&&maze[xx][yy]==0)
{
rear=PushQueue(front,rear,xx,yy,len+1);
maze[xx][yy]=1;
}
}
}
return -1;
}
int main()
{
int i,j,start_x,start_y,end_x,end_y,ans;
scanf("%d%d",&m,&n);
for(i=0;i<m;i++)
for(j=0;j<n;j++)
scanf("%d",&maze[i][j]);
scanf("%d%d%d%d",&start_x,&start_y,&end_x,&end_y);
front=rear=InitQueue();
ans=bfs(start_x,start_y,end_x,end_y);
if(ans>=0)
printf("%d",ans);
else
printf("no path!");
free(front);
return 0;
}
讲解
两种队列的实现都差不多,链式队列更实用一些,这里以链式队列为例讲解队列的基本操作。
队列的基本操作有初始化队列、判断队列是否为空、入队、出队等。
初始化队列
PQueue InitQueue()
{
PQueue head;
head=(PQueue)malloc(sizeof(Queue));
if(head==NULL)
{
printf("InitQueue Error!\n");
exit(1);
}
head->next=NULL;
return head;//front指针和rear指针接收head的返回值
}
判断队列是否为空
int IsEmpty(PQueue front,PQueue rear)
{
if(front==rear)
return 1;
else
return 0;
}
入队
PQueue PushQueue(PQueue front,PQueue rear,int n)
{
PQueue pqueue;
pqueue=(PQueue)malloc(sizeof(Queue));
if(pqueue==NULL)
{
printf("PushQueue Error!\n");
exit(1);
}
pqueue->data=n;
pqueue->next=NULL;
rear->next=pqueue;
rear=pqueue;
return rear;
}
出队
PQueue PopQueue(PQueue front,PQueue rear,int *n)
{
PQueue pqueue;
if(IsEmpty(front,rear))
{
printf("PopQueue Error!\n");
exit(1);
}
pqueue=front->next;
*n=pqueue->data;
front->next=pqueue->next;
if(rear==pqueue)
rear=front;
free(pqueue);
return rear;
}
这道题本身并不难,没什么好讲的。