队列是线性数据结构中的一种。采用顺序存储的队列则称为顺序队列
队列是一种先进先出的结构
循环队列是指将队列看作是连续存储空间“首尾相接”的圆环
那么,我们先来看一下循环顺序队列的抽象数据类型
其中,队头队尾位标是我们需要管理好的,因为这决定着新元素入队列的位置与先进入队列的元素的移出以及队列是否已满
#define OVERFLOW -1
#define OK 1
#define ERROR 0
#define TRUE 2
#define FALSE -2
typedef char ElemType;
typedef struct {
ElemType *base; // 存储空间的基址
int front; // 队头位标
int rear; // 队尾位标,指示队尾元素的下一位置
int maxSize; // 最大长度
} SqQueue;
typedef int Status;
Status InitQueue_Sq(SqQueue& Q, int size);
Status EnQueue_Sq(SqQueue& Q, ElemType e);
Status DeQueue_Sq(SqQueue& Q, ElemType& e);
Status QueueEmpty_Sq(SqQueue Q);
void reverseQueue_Sq(SqQueue& Q);
下面我们来看看其关键操作
//初始化一个空的循环队列
Status InitQueue_Sq(SqQueue& Q, int size) { // 构造一个空队列
//Add your code here
Q.base = (ElemType *)malloc(size*sizeof(ElemType));
Q.front = 0;
Q.rear = 0;
Q.maxSize = size;
return OK;
}
//进队列操作
Status EnQueue_Sq(SqQueue& Q, ElemType e) {
// 若当前队列不满,在队列的尾元素之后,插入元素 e 为新的队列尾元素
if ((Q.rear+1)%Q.maxSize == Q.front)
return ERROR;
Q.base[(Q.rear)%Q.maxSize] = e;
Q.rear=(Q.rear+1) % Q.maxSize;
return OK;
}
//出队列操作
Status DeQueue_Sq(SqQueue& Q, ElemType& e) {
// 若队列不空,则删除队列Q中的头元素,用 e 返回其值
if (Q.front==Q.rear)
return ERROR; // 队空报错
e = Q.base[Q.front];
Q.front = (Q.front + 1) % Q.maxSize; // Q.front循环加1
return OK;
}
//判断队列是否为空
Status QueueEmpty_Sq(SqQueue Q) { // 判断队列Q是否空,若空则返回TRUE,否则FALSE
if (Q.front==Q.rear)
return TRUE;
else
return FALSE;
}
其中,在出入队列的操作中,使用(Q.rear + 1) % Q.maxSize 以及(Q.front + 1) % Q.maxSize来控制头尾位标的位置来实现循环。
注意rear队尾位标,指向的是队尾元素的下一个位置
特别要注意当rear与front相等时那么当前队列一定是空的。