一、简介
队列,和栈一样,也是一种对数据的"存"和"取"有严格要求的线性存储结构。
与栈结构不同的是,队列的两端都"开口",要求数据只能从一端进,从另一端出,如图 1 所示:
通常,称进数据的一端为 "队尾",出数据的一端为 "队头",数据元素进队列的过程称为 "入队",出队列的过程称为 "出队"。
不仅如此,队列中数据的进出要遵循 “先进先出” 的原则,即最先进队列的数据元素,同样要最先出队列。拿图 1 中的队列来说,从数据在队列中的存储状态可以分析出,元素 1 最先进队,其次是元素 2,最后是元素 3。此时如果将元素 3 出队,根据队列 “先进先出” 的特点,元素 1 要先出队列,元素 2 再出队列,最后才轮到元素 3 出队列。
栈和队列不要混淆,栈结构是一端封口,特点是"先进后出";而队列的两端全是开口,特点是"先进先出"。
因此,数据从表的一端进,从另一端出,且遵循 “先进先出” 原则的线性存储结构就是队列。
二、分类
队列一般分为两类:链式队列和顺序队列
链式队列—链式队列即用链表实现的队列
顺序队列—顺序队列是用数组实现的队列,顺序队列通常必须是循环队列
三、队列常见的操作
入队: 通常命名为push()
出队: 通常命名为pop()
求队列中元素个数
判断队列是否为空
判断队列是否为满
获取队首元素
四、队列的伪算法
定义front为队列头元素的位置,rear为队列尾元素的位置,MAXSIZE为循环队列的最大长度。注意以下几点,循环队列迎刃而解:
A. 求元素的个数:(rear - front + MAXSIZE) % MAXSIZE
B. front/rear指向逻辑的下一个空间 front =(front+1)%MAXSIZE,rear = (rear+1)%MAXSIZE
C. 判空:front == rear
D. 判满:(rear+1) %MAXSZIE== front
五、实例分析
#include <QCoreApplication>
#include <QDebug>
#include <stdio.h>
//队列结构体
typedef struct queue{
int *val; //队列存储的数据
int front; //队头
int rear;//队尾
int size;//队列的大小
}QUEUE;
//队列的初始化
bool InitQueue(QUEUE *q,int size){
q->val = (int*)malloc(sizeof(int)*size);
if(q->val == NULL)
return false;
q->front = q->rear = 0;
q->size = size;
return true;
}
//判断队列是否为满
bool isFull(QUEUE *q){
if((q->rear+1)%q->size == q->front){
printf("queue full\n");
return true;
}
return false;
}
//入队
bool Push(QUEUE *q,int val){
//判断队列是否为满
if(isFull(q))
return false;
q->val[q->rear] = val;
q->rear = (q->rear+1)%q->size;
return true;
}
//判断队列是否为空
bool isEmpty(QUEUE *q){
if(q->rear == q->front){
printf("queue is empty\n");
return true;
}
return false;
}
//遍历队列所有元素
bool Queue_List(QUEUE *q){
if(isEmpty(q))
return false;
int i = q->front;
while(i%q->size != q->rear){
printf("i:%d val:%d\n",i,q->val[i]);
i++;
}
}
//出队
bool Pop(QUEUE *q){
if(isEmpty(q)){
return false;
}
q->front = (q->front+1)%q->size;
return true;
}
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
//初始化队列
QUEUE q;
InitQueue(&q,5);
//入队
Push(&q,10);
Push(&q,5);
Push(&q,15);
Push(&q,100);
Push(&q,200);
Push(&q,300);
Queue_List(&q);
//出队
Pop(&q);
Pop(&q);
Pop(&q);
Pop(&q);
Pop(&q);
Queue_List(&q);
return a.exec();
}
运行结果如下: