1、循环队列
一开始使用数组来表示队列,但是会造成很多的数据搬移,效率太低,所以考虑使用循环队列。
循环队列的约定如下:
- 用a[0] - a[maxsize - 1]来表示整个队列
- 最开始是rear == front ==0
- 空出一个字节,用来辨别空队列和满队列(当rear == front的时候,毫无疑问是空队列,当(rear + 1)%maxsize == front的时候,表示满队列)
如下图所示:
2、功能定义
#include <stdio.h>
#include <string.h>
#define MAXSIZE 100
/*因为普通数组来实现队列,需要涉及到很多数据搬移,所以使用循环队列
*而对于循环队列,在分辨其满和空时,会有一些困难。
*可以采用两种方法
*1、增加一个成员变量,来表明其满或者空
*2、空出一个数组成员,用来判别
*/
typedef struct{
int queue[MAXSIZE];
int front;
int rear;
// int state; //仅在循环队列中使用
} SqQueue;
void CreateQueue(SqQueue **p);
void InQueue(SqQueue *p, int value);
void OutQueue(SqQueue *p);
int IsEmpty(SqQueue *p);
int IsFull(SqQueue *p);
void PrintQueue(SqQueue *p);
3、函数实现(注意边界条件)
void main()
{
SqQueue *p;
CreateQueue(&p);
InQueue(p, 1);
InQueue(p, 2);
PrintQueue(p);
OutQueue(p);
}
void CreateQueue(SqQueue **p)
{
*p = (SqQueue *)malloc(sizeof(SqQueue));
(*p)->front = 0;
(*p)->rear = 0;
}
void InQueue(SqQueue *p, int value)
{
assert(!IsFull(p));
p->rear++;
p->rear = p->rear % MAXSIZE;
p->queue[p->rear] = value;
}
void OutQueue(SqQueue *p)
{
assert(!IsEmpty(p));
p->front = (p->front + 1) % MAXSIZE;
}
int IsFull(SqQueue *p)
{
return (p->rear + 1) % MAXSIZE == p->front;
}
int IsEmpty(SqQueue *p)
{
return p->rear == p->front;
}
打印函数
为什么这个函数要单独拿出来?
因为在编写该函数的时候,我曾多次的出现各种问题。
- 在循环输出的时候,直接对p->front和p->rear进行操作
- 在循环判断的时候,使用p->front%maxsize <=p->rear,却没有意识到做了余数后,该式会一直成立