转载请注明出处:http://blog.youkuaiyun.com/droyon/article/details/9840779
栈操作的top指针在Push时增大而在Pop时减小,栈空间是可以重复利用的,而队列的head、tail指针都在一直增大,虽然前面的元素已经出队了,但它所占的存储空间却不能重复利用,这样对存储空间的利用效率很低。
环形队列(Circular Queue):把queue数组想像成一个圈,head和tail指针仍然是一直增大的,当指到数组末尾时就自动回到数组开头。就像两个人围着操场赛跑,沿着它们跑的方向看,从head到tail之间是队列的有效元素,从tail到head之间是可以被利用的存储位置。head追上tail就表示队列空了,tail追上head就表示队列的存储空间满了。
使用循环队列实现广度搜索。背景介绍见:http://blog.youkuaiyun.com/droyon/article/details/9840617
测试例子:
#include<stdio.h>
#define MAX_ROW 5
#define MAX_COL 5
#define MAX_LENGTH 8//循环队列的空间大小
int curIndex = 0;
struct point {
int x, y;
}queue[MAX_LENGTH];
int maze[MAX_ROW][MAX_COL] = {
{0, 1, 0, 0, 0},
{0, 1, 0, 1, 0},
{0, 0, 0, 0, 0},
{0, 1, 1, 1, 0},
{0, 0, 0, 1, 0},
};
void print_maze()
{
int i = 0, j = 0;
printf("第%d次操作结果**************************\n",
++curIndex);
for (i = 0; i < MAX_ROW; i++) {
for (j = 0; j < MAX_COL; j++) {
if (maze[i][j] == 0) {
printf("%c\t", '#');
} else if (maze[i][j] == 2) {
printf("%s\t", "<0>");
} else {
printf("%c\t", '|');
}
}
printf("\n");
}
printf("**********************************\n");
}
int head=0,tail=0;
void enqueue(struct point p){
printf("enqueue **** tail :%d,head :%d\n",tail,head);
queue[tail] = p;
if(tail+1<MAX_LENGTH)tail++;
else if(head!=0){
tail = 0;
}
printf("enqueue #### tail :%d,head : %d\n",tail,head);
}
struct point dequeue(void){
if(head +1 <=MAX_LENGTH)head++;
else if(tail != 0){
head = 0;
head++;
}
return queue[head-1];
}
int isEmpty(void){
return head == tail;
}
void visit(int row,int col){
maze[row][col] = 2;
struct point visit_point = {row,col};
enqueue(visit_point);
print_maze();
}
int main(void){
struct point p = { 0, 0 };
maze[0][0] = 2;
enqueue(p);
while (!isEmpty()) {
p = dequeue();
if (p.x == MAX_ROW - 1 && p.y == MAX_COL - 1) {
continue;
}
if (p.x + 1 < MAX_ROW && maze[p.x + 1][p.y] == 0) {
visit(p.x + 1, p.y);
}
if (p.x - 1 > -1 && maze[p.x - 1][p.y] == 0) {
visit(p.x - 1, p.y);
}
if (p.y + 1 < MAX_COL && maze[p.x][p.y + 1] == 0) {
visit(p.x, p.y + 1);
}
if (p.y - 1 > -1 && maze[p.x][p.y - 1] == 0) {
visit(p.x, p.y - 1);
}
}
int i = 0;
for(i=0;i<MAX_LENGTH;i++){
struct point pp = queue[i];
printf("pointx:%d,pointy:%d\n",pp.x,pp.y);
}
return 0;
}
打印:
enqueue **** tail :0,head :0
enqueue #### tail :1,head : 0
enqueue **** tail :1,head :1
enqueue #### tail :2,head : 1
第1次操作结果**************************
<0> | # # #
<0> | # | #
# # # # #
# | | | #
# # # | #
**********************************
enqueue **** tail :2,head :2
enqueue #### tail :3,head : 2
第2次操作结果**************************
<0> | # # #
<0> | # | #
<0> # # # #
# | | | #
# # # | #
**********************************
enqueue **** tail :3,head :3
enqueue #### tail :4,head : 3
第3次操作结果**************************
<0> | # # #
<0> | # | #
<0> # # # #
<0> | | | #
# # # | #
**********************************
enqueue **** tail :4,head :3
enqueue #### tail :5,head : 3
第4次操作结果**************************
<0> | # # #
<0> | # | #
<0> <0> # # #
<0> | | | #
# # # | #
**********************************
enqueue **** tail :5,head :4
enqueue #### tail :6,head : 4
第5次操作结果**************************
<0> | # # #
<0> | # | #
<0> <0> # # #
<0> | | | #
<0> # # | #
**********************************
enqueue **** tail :6,head :5
enqueue #### tail :7,head : 5
第6次操作结果**************************
<0> | # # #
<0> | # | #
<0> <0> <0> # #
<0> | | | #
<0> # # | #
**********************************
enqueue **** tail :7,head :6
enqueue #### tail :0,head : 6
第7次操作结果**************************
<0> | # # #
<0> | # | #
<0> <0> <0> # #
<0> | | | #
<0> <0> # | #
**********************************
enqueue **** tail :0,head :7
enqueue #### tail :1,head : 7
第8次操作结果**************************
<0> | # # #
<0> | <0> | #
<0> <0> <0> # #
<0> | | | #
<0> <0> # | #
**********************************
enqueue **** tail :1,head :7
enqueue #### tail :2,head : 7
第9次操作结果**************************
<0> | # # #
<0> | <0> | #
<0> <0> <0> <0> #
<0> | | | #
<0> <0> # | #
**********************************
enqueue **** tail :2,head :8
enqueue #### tail :3,head : 8
第10次操作结果**************************
<0> | # # #
<0> | <0> | #
<0> <0> <0> <0> #
<0> | | | #
<0> <0> <0> | #
**********************************
enqueue **** tail :3,head :1
enqueue #### tail :4,head : 1
第11次操作结果**************************
<0> | <0> # #
<0> | <0> | #
<0> <0> <0> <0> #
<0> | | | #
<0> <0> <0> | #
**********************************
enqueue **** tail :4,head :2
enqueue #### tail :5,head : 2
第12次操作结果**************************
<0> | <0> # #
<0> | <0> | #
<0> <0> <0> <0> <0>
<0> | | | #
<0> <0> <0> | #
**********************************
enqueue **** tail :5,head :4
enqueue #### tail :6,head : 4
第13次操作结果**************************
<0> | <0> <0> #
<0> | <0> | #
<0> <0> <0> <0> <0>
<0> | | | #
<0> <0> <0> | #
**********************************
enqueue **** tail :6,head :5
enqueue #### tail :7,head : 5
第14次操作结果**************************
<0> | <0> <0> #
<0> | <0> | #
<0> <0> <0> <0> <0>
<0> | | | <0>
<0> <0> <0> | #
**********************************
enqueue **** tail :7,head :5
enqueue #### tail :0,head : 5
第15次操作结果**************************
<0> | <0> <0> #
<0> | <0> | <0>
<0> <0> <0> <0> <0>
<0> | | | <0>
<0> <0> <0> | #
**********************************
enqueue **** tail :0,head :6
enqueue #### tail :1,head : 6
第16次操作结果**************************
<0> | <0> <0> <0>
<0> | <0> | <0>
<0> <0> <0> <0> <0>
<0> | | | <0>
<0> <0> <0> | #
**********************************
enqueue **** tail :1,head :7
enqueue #### tail :2,head : 7
第17次操作结果**************************
<0> | <0> <0> <0>
<0> | <0> | <0>
<0> <0> <0> <0> <0>
<0> | | | <0>
<0> <0> <0> | <0>
**********************************
pointx:0,pointy:4
pointx:4,pointy:4
pointx:4,pointy:2
pointx:0,pointy:2
pointx:2,pointy:4
pointx:0,pointy:3
pointx:3,pointy:4
pointx:1,pointy:4