队列是一种先进先出的线性表,只允许在一端进行插入操作,另一端进行删除操作。队列顺序存储的基础操作和线性表顺序存储的基础操作几乎相同,但因为队列的增加和删除操作都需要让整个数组的数据进行移动,性能上并不理想。所以,一般都会采用循环队列,它也属于队列的顺序存储,但性能优化更好。定义循环队列需要定义两个指针,front指向队头,rear指向队列最后一个元素的下一个位置。这样,当front、rear指向同一个位置时,该队列为空。还需要设置队列的最大长度QueueSize,此时队列已满的条件就是(rear+1)%QueueSize==front,而计算队列的长度则是(rear-front+QueueSize)%QueueSize。到这里循环队列的实现基本就出来了,实现代码如下:
#include <stdio.h>
#include <stdlib.h>
#define MAXLENGTH 20//定义队列的最大长度
typedef int QEletype;//定义循环队列存储的数据类型
typedef struct{
QEletype data[MAXLENGTH];
int front;//定义队头
int rear;//定义队尾(队尾指向队列最后一个数据后面的位置)
}SqQueue;
//初始化循环队列
void init(SqQueue *sq){
sq->front=0;
sq->rear=0;
}
//获取队列当前长度
int getLength(SqQueue q){
return (q.rear-q.front+MAXLENGTH)%MAXLENGTH;//这个求队列长度的公式是固定的,如不理解,死记硬背也行
}
//向队列插入数据
void insertEle(SqQueue *q,QEletype e){
if((q->rear+1)%MAXLENGTH==q->front){//这个公式也是固定的,不理解的话记住就行
printf("该队列已满");
return ;
}else{
// if(q->rear==(MAXLENGTH-1)){
// q->rear=0;
// q->data[q->rear]=e;
// q->rear++;
// }else{
// q->data[q->rear]=e;
// q->rear++;
// }
//上面比较繁琐,推荐下面的写法
q->data[q->rear]=e;
q->rear=(q->rear+1)%MAXLENGTH;//让rear向队列后移动,如果到了最后,则指向数组头部
}
}
void deleteEle(SqQueue *q,QEletype *e){
if(q->rear==q->front){
printf("该队列为空");
return ;
}else{
*e=q->data[q->front];
q->front=(q->front+1)%MAXLENGTH;//让front向队列后移动,如果到了最后,则指向数组头部
}
}
void getEle(SqQueue q,QEletype *e){
if(q.rear==q.front){
printf("该队列为空,无法获取\n");
return ;
}else{
*e=q.data[q.front];
}
}
int main()
{
SqQueue q;
QEletype f,e=666,g=1314;
init(&q);
printf("初始化后队列长度:\n%d\n",getLength(q));
getEle(q,&e);
insertEle(&q,e);
insertEle(&q,g);
printf("插入数据后队列长度:\n%d\n",getLength(q));
getEle(q,&f);
printf("获取到的数据:\n%d\n",f);
deleteEle(&q,&e);
getEle(q,&f);
printf("删除队列头数据以后获取到的数据:\n%d\n",f);
return 0;
}