一、 队列定义
队列(Queue)是一种先进先出(FirstInFirstOut,FIFO)的线性表,只允许在表的前端(front)进行删除操作,而在表的后端(rear)进行插入操作。
二、队列的溢出
顺序队列中的溢出现象:
(1)"下溢"现象:当队列为空时,做出队运算产生的溢出现象。“下溢”是正常现象,常用作程序控制转移的条件。
(2)"真上溢"现象:当队列满时,做进栈运算产生空间溢出的现象。“真上溢”是一种出错状态,应设法避免。
(3)"假上溢"现象:由于入队和出队操作中,头尾指针只增加不减小,致使被删元素的空间永远无法重新利用。当队列中实际的元素个数远远小于向量空间的规模时,也可能由于尾指针已超越向量空间的上界而不能做入队操作。该现象称为"假上溢"现象。
三、队列实现
// 循环队列(Queue)
#include <stdio.h>
#include <stdlib.h>
#define MAX_SIZE 10
typedef struct {
int *base;
int front;// 对头
int rear;// 对尾
} sQueue;
// 初始化
void InitQ(sQueue *Q) {
Q->base = (int *)malloc(MAX_SIZE * sizeof(int));
Q->front = 0;
Q->rear = 0;
printf("队列初始化完成...\n");
}
// 判断是否为空队
int QEmpty(sQueue *Q) {
return Q->front == Q->rear ? 1 : 0;
}
// 判断是否为满队
int QFull(sQueue *Q) {
return ((Q->rear + 1) % MAX_SIZE) == Q->front ? 1 : 0;
}
// 队长
int QLength(sQueue *Q) {
return (Q->rear - Q->front + MAX_SIZE) % MAX_SIZE;
}
// 入队
void EnQueue(sQueue *Q, int val) {
if(QFull(Q)) {
printf("队列已满,入队失败...\n");
return;
}
Q->base[Q->rear]=val;
Q->rear = (Q->rear + 1) % MAX_SIZE; // 实现循环
}
// 出队
int DeQueue(sQueue *Q) {
if(QEmpty(Q)) {
printf("队列为空,无元素可出队...\n");
}
int e = Q->front;
Q->front = (Q->front+ 1) % MAX_SIZE; // 实现循环
}
// 销毁
void DestroyQueue(sQueue *Q){
free(Q);
printf("队列已销毁...\n");
}
// 清空
void ClearQueue(sQueue *Q){
Q->front = 0;
Q->rear = 0;
printf("队列已清空...\n");
}
// 打印队列
void display(sQueue *Q){
printf("打印队列顺序为:Front->Rear\n");
int i = Q->front;
for(i;i!=Q->rear;i=(i+1)%MAX_SIZE){
printf("%d ",Q->base[i]);
}
printf("\n");
}
main() {
sQueue Q;
srand((unsigned)time(0)); // 随机数种子
InitQ(&Q);
printf("队列是否为空:%s\n", QEmpty(&Q) ? "true":"false");
printf("队列是否已满:%s\n", QFull(&Q) ? "true":"false");
printf("队列长度为:%d\n", QLength(&Q));
printf("生成随机数入队中...\n");
int i;
for(i=0; i<MAX_SIZE-1; i++) {
EnQueue(&Q, rand() % 100); // 生成随机数
}
display(&Q);
printf("队列是否为空:%s\n", QEmpty(&Q) ? "true":"false");
printf("队列是否已满:%s\n", QFull(&Q) ? "true":"false");
printf("队列长度为:%d\n", QLength(&Q));
DeQueue(&Q); // 出队
display(&Q);
ClearQueue(&Q);
printf("队列长度为:%d\n", QLength(&Q));
}