一、队列模型
- 队列是一种特殊的线性表,它只允许在表的前端(front)进行删除操作,而在表的后端(rear)进行插入操作。也可称为先进先出(FIFO)表
- 队列的动画:http://liveexample.pearsoncmg.com/liang/animation/web/Queue.html
- 队列的应用
– Printer Queue
– Web Crawler
– System Buffer
– Any sequence maintained in a FIFO order
二、队列的数组实现
1. 队列的数据结构
typedef struct {
double *values; // 可以为任意数据类型
int front;
int rear;
int counter; // 队列中元素的数量
int maxSize; // 队列大小
} Queue;
2. 队列的创建
💡 这里我们初始化 rear = -1,则当我们入队第一个元素时 rear = 0,相对应于数组 A[0]
bool CreateQueue(Queue *queue, int size){
if (size < 1){
printf("Error: size should be positive.\n");
return false;
}
queue->values = (double*)malloc(sizeof(double) * size);
queue->front = 0;
queue->rear = -1;
queue->counter = 0;
queue->maxSize = size;
return true;
}
3. 入队和出队
- 为了使一个元素X入队,我们让 counter 和 rear 加1。
- 为了使一个元素X出队,我们让counter减 1,front 加1。
⚠️ 这种实现存在一个潜在的问题。经过 3 次入队后队列似乎是满了,因为 rear现在为 10,若下一次再入列就会是一个不存在的位置,但在这之前可能进行了几次出队的操作,这时队列中可能只有 1 个或 2 个元素。
💡 一个简单的解决方法使,当 front 或 rear 到达数组的尾端,他就又绕回开头。这叫做循环队列(circular queue)
- 入队
bool Enqueue(Queue *queue, double x){
if (IsFull(queue)){
return false;
}
// adds a new element with values x to the rear of the queue
queue->rear = (queue->rear + 1) % queue->maxSize;
queue->values[queue->rear] = x;
queue->counter++;
return true;
}
- 出队
bool Dequeue(Queue *queue, double *x){
if (IsEmpty(queue)){
return false;
}
// removes an element from the front of the queue
// passes the value of the front element to x
*x = queue->values[queue->front];
queue->front = (queue->front + 1) % queue->maxSize;
queue->counter--;
return true;
}
4. 其他基本操作
- 判空和判满
bool IsEmpty(Queue *queue){
return queue->counter == 0;
}
bool IsFull(Queue *queue){
return queue->counter == queue->maxSize;
}
- 历遍打印
void DisplayQueue(Queue *queue){
if (IsEmpty(queue)){
printf("The queue is empty!\n");
}
else{
printf("front-->");
int i=queue->front;
int a=0;
for(a = 0 ; a<queue->counter; a++){
if (a<queue->counter-1){
printf("%f\n\t", queue->values[(queue->front+a)%queue->maxSize]);
}
else{
printf("%f", queue->values[(queue->front+a)%queue->maxSize]);
}
}
printf("<--rear\n");
}
}
- 销毁
void DestroyQueue(Queue *queue){
free(queue->values);
queue->counter = 0;
queue->front = 0;
queue->rear = -1;
queue->values = NULL;
}
5. 完整代码
- queue.h
#include <stdbool.h>
typedef struct {
double *values;
int front;
int rear;
int counter;
int maxSize;
} Queue;
bool CreateQueue(Queue *queue, int size);
bool IsEmpty(Queue *queue);
bool IsFull(Queue *queue);
bool Enqueue(Queue *queue, double x);
bool Dequeue(Queue *queue, double *x);
void DisplayQueue(Queue *queue);
void DestroyQueue(Queue *queue);
- queue.c
#include <stdbool.h>
#include <stdlib.h>
#include <stdio.h>
#include "queue.h"
bool CreateQueue(Queue *queue, int size){
if (size < 1){
printf("Error: size should be positive.\n");
return false;
}
queue->values = (double*)malloc(sizeof(double) * size);
queue->front = 0;
queue->rear = -1;
queue->counter = 0;
queue->maxSize = size;
return true;
}
bool IsEmpty(Queue *queue){
return queue->counter == 0;
}
bool IsFull(Queue *queue){
return queue->counter == queue->maxSize;
}
bool Enqueue(Queue *queue, double x){
if (IsFull(queue)){
return false;
}
// adds a new element with values x to the rear of the queue
queue->rear = (queue->rear + 1) % queue->maxSize;
queue->values[queue->rear] = x;
queue->counter++;
return true;
}
bool Dequeue(Queue *queue, double *x){
if (IsEmpty(queue)){
return false;
}
// removes an element from the front of the queue
// passes the value of the front element to x
*x = queue->values[queue->front];
queue->front = (queue->front + 1) % queue->maxSize;
queue->counter--;
return true;
}
void DisplayQueue(Queue *queue){
if (IsEmpty(queue)){
printf("The queue is empty!\n");
}
else{
printf("front-->");
int i=queue->front;
int a=0;
for(a = 0 ; a<queue->counter; a++){
if (a<queue->counter-1){
printf("%f\n\t", queue->values[(queue->front+a)%queue->maxSize]);
}
else{
printf("%f", queue->values[(queue->front+a)%queue->maxSize]);
}
}
printf("<--rear\n");
}
}
void DestroyQueue(Queue *queue){
free(queue->values);
queue->counter = 0;
queue->front = 0;
queue->rear = -1;
queue->values = NULL;
}
- main.c
#include <stdio.h>
#include <stdbool.h>
#include "queue.h"
int main(void) {
Queue queue;
double value;
CreateQueue(&queue, 5);
puts("Enqueue 5 items.");
for(int x = 0; x < 5; x++)
Enqueue(&queue, x);
puts("Now attempting to enqueue again...");
Enqueue(&queue, 5.0);
DisplayQueue(&queue);
printf("\n");
Dequeue(&queue, &value);
printf("Retrieved element = %f\n", value);
printf("\n");
DisplayQueue(&queue);
printf("\n");
Enqueue(&queue, 7.0);
DisplayQueue(&queue);
printf("\n");
DestroyQueue(&queue);
return 0;
}
- 结果显示
🚩 以上均为个人学习数据结构算法时的小笔记,如有错误请多多指正