目录
一、队列的概念
应用场景:比如我们去银行取号办理业务,首先要先取一个号,然后开始排队等待。比我们先取号的先办理业务,比我们慢取号的排在我们后面等待。
以上就是队列的一个特性:先进先出。
二、基本实现逻辑
使用单向链表实现。
入队操作:在链表尾部添加一个新节点
出队操作:在链表头部删除一个节点
1、接口设计
typedef struct {
int id;
char name[32];
}Data; // 储存数据的结构体
typedef struct QueueNode{
Data data; // 数据域
struct QueueNode *next; // 指针域
}QNode;
typedef struct {
QNode *front; // 队首索引, 头删(出队)
QNode *rear; // 队尾索引, 尾增(入队)
int size; // 当前队列大小
} Queue;
// 初始化队列
Queue* initQueue();
// 检查队列是否为空
bool isEmpty(Queue* q);
// 入队操作
void enqueue(Queue* q, Data *data);
// 出队操作
void dequeue(Queue* q);
// 查看队首元素
int peek(Queue* q);
// 销毁队列
void destroyQueue(Queue* q);
2、接口实现
// 初始化队列
Queue* initQueue()
{
Queue *q = calloc(1, sizeof(Queue));
if(NULL == q)
return NULL;
q->front = NULL;
q->rear = NULL;
q->size = 0;
return q;
}
// 检查队列是否为空
bool isEmpty(Queue* q)
{
if(NULL == q->front && \
NULL == q->rear && \
0 == q->size)
return true;
return false;
}
// 入队操作
void enqueue(Queue* q, Data *data)
{
QNode *newNode = NULL;
if(NULL == q)
return;
newNode = calloc(1, sizeof(QNode));
if(NULL == newNode)
return;
memcpy(&newNode->data, data, sizeof(Data));
newNode->next = NULL;
if(isEmpty(q))
{
q->front = newNode;
q->rear = newNode;
}
else
{
q->rear->next = newNode;
q->rear = newNode;
}
q->size ++;
printf("enqueue succ: name(%s), id(%d)\n", newNode->data.name, newNode->data.id);
}
// 出队操作
void dequeue(Queue* q)
{
QNode *tmpNode = NULL;
if(NULL == q)
return;
if(isEmpty(q))
return;
printf("dequeue succ: name(%s), id(%d)\n", q->front->data.name, q->front->data.id);
tmpNode = q->front->next;
free(q->front);
q->front = tmpNode;
q->size --;
if(NULL == q->front)
q->rear = NULL;
}
// 查看队首元素
int peek(Queue* q)
{
if(NULL == q)
return -1;
if(isEmpty(q))
return -1;
printf("peek: name(%s), id(%d)\n", q->front->data.name, q->front->data.id);
return 0;
}
// 销毁队列
void destroyQueue(Queue* q)
{
if(NULL == q)
return;
while(0 != q->size)
dequeue(q);
free(q);
}
3、接口验证
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
int main(void)
{
Queue *q = initQueue();
Data data1 = {1, "test1"};
Data data2 = {2, "test2"};
Data data3 = {3, "test3"};
Data data4 = {4, "test4"};
Data data5 = {5, "test5"};
if(NULL == q)
printf("initQueue error\n");
if(isEmpty(q))
printf("Queue is empty now\n");
// 入队
enqueue(q, &data1);
enqueue(q, &data2);
enqueue(q, &data3);
enqueue(q, &data4);
enqueue(q, &data5);
peek(q);
// 出队
dequeue(q);
dequeue(q);
peek(q);
destroyQueue(q);
return 0;
}
编译&执行:
注:一个使用单向链表实现队列的可视化链接:Linked List Queue Visualization