目录
队列的概念
画图理解队列
代码图理解
代码展示(注意这个队列是单链表的结构实现)
Queue.h(队列结构)
Queue.c(函数/API实现)
main.c(测试文件)
队列的概念
队列(Queue)是一种基础的数据结构,它遵循先进先出(First In First Out, FIFO)的原则。这意味着最早进入队列的元素也将是最先离开队列的元素。队列常被比喻为现实生活中的排队场景,比如在超市收银台前排队结账,先到的人先结账。
队列有两个主要的操作:
- 入队(Enqueue):将一个元素添加到队列的末尾。这相当于一个人加入到队伍的最后面。
- 出队(Dequeue):从队列的前端移除一个元素,并返回该元素。这相当于队伍最前面的人完成相应操作后离开队伍。
画图理解队列
这就是队列的一个基本结构,队尾入队,队头出队。在生活中也有这样的结构,请个看例图(希望可以给你带来印象):
生活中队列的例子非常普遍,以下是一些典型的实例:
超市结账:顾客在超市收银台前排队等待付款,先到的顾客先完成结账离开,后来的顾客依次跟进。
银行服务窗口:客户在银行的服务窗口前排队办理业务,遵循先来先服务的原则。
公共交通:在公交站、火车站或地铁站的候车队伍,乘客按照到达的先后顺序上车。
餐厅排队:在餐厅,特别是快餐店,顾客排队等待点餐和取餐,先排队的顾客先完成点餐流程。
打印机任务队列:在办公室,多个人提交打印任务时,打印机会按照任务提交的顺序依次执行打印。
医院挂号:病人在医院挂号处排队等待挂号,通常也是按照到达顺序进行服务。
网上购票系统:虽然看不见实体队伍,但在高峰时段购买热门活动或交通工具票务时,请求会被按接收顺序处理。
ATM机取款:人们在ATM机前排队取现金,每个人完成交易后下一个人才能使用。
代码图理解
代码展示(注意这个队列是单链表的结构实现)
数据结构:单链表-CSDN博客文章浏览阅读1.6k次,点赞36次,收藏15次。链表是一种基本的数据结构,它用于存储一系列元素(节点),每个节点不仅包含数据元素,还包含一个指向下一个节点的指针。在链表中,数据并非连续地存储在内存中,而是通过每个节点的指针链接起来形成一个逻辑上的线性序列通过前面我们学习的顺序表我们现在延伸一个链表我们会发现顺序表的一些缺点。https://blog.csdn.net/2302_78381559/article/details/137829309
Queue.h(队列结构)
#pragma once
/*--头文件--*/
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include<stdbool.h>
typedef int DataType;
//创建队列结构
typedef struct QueueNode
{
struct QueueNode* Next;
DataType val;
}QueueNode;
//创建一个结构体来确定头/尾,可以避免使用二级指针,也可以用哨兵来避免使用二级指针
typedef struct Queue {
QueueNode* head;//头
QueueNode* tail;//尾
int size;//计数
}Queue;
/*--函数实现--*/
//初始化
void Q_Init(Queue* p);
//入队
void Q_Push(Queue* p, DataType x);
//出队
void Q_Pop(Queue* p);
//节点数
int Q_Size(Queue* p);
//获取头部
DataType Q_Front(Queue* p);
//获取尾部
DataType Q_Back(Queue* p);
//判断是否为空
bool Q_Empty(Queue* p);
//销毁
void Q_Destroy(Queue* p);
Queue.c(函数/API实现)
#define _CRT_SECURE_NO_WARNINGS 1
//函数实现
#include"Queue.h"
//初始化
void Q_Init(Queue* p) {
//断言
assert(p);
//初始化结构体
p->head = NULL;
p->tail = NULL;
p->size = 0;
}
//入队
void Q_Push(Queue* p, DataType x) {
//开辟一个节点
QueueNode* newnode = (QueueNode*)malloc(sizeof(QueueNode));
if (newnode == NULL)//判断是否开辟成功
{
assert("malloc");
return;
}
//进行插入操作
newnode->Next = NULL;
newnode->val = x;
if (p->tail == NULL)
{
p->head = p->tail = newnode;
}
else
{
p->tail->Next = newnode;
p->tail = newnode;//更新tail的指向
}
p->size++;//push一下节点个数++
}
//出队
void Q_Pop(Queue* p) {
assert(p);
assert(p->size);//节点不能为空
//进行出队
if (p->head->Next == NULL)//一个节点
{
free(p->head);
p->head = p->tail = NULL;
}
else//多个节点
{
QueueNode* tmp = p->head->Next;//用临时变量存储head的下一个节点
free(p->head);//释放head的节点
p->head = tmp;//在更新head指向
}
p->size--;//pop一个节点个数--
}
//节点数
int Q_Size(Queue* p) {
assert(p);
assert(p->size);
return p->size;
}
//获取头部
DataType Q_Front(Queue* p) {
assert(p);
assert(p->size);
//直接返回head的元素
return p->head->val;
}
//获取尾部
DataType Q_Back(Queue* p) {
assert(p);
assert(p->size);
//直接返回tail的元素
return p->tail->val;
}
//判断是否为空
bool Q_Empty(Queue* p) {
assert(p);
//return p->size == 0;
return !p->size;
}
//销毁
void Q_Destroy(Queue* p) {
assert(p);
QueueNode* cur = p->head;
while (cur)
{
//存储下一个位置
QueueNode* tmp = cur->Next;
free(cur);
cur = tmp;
}
//指针制空
p->head = p->tail = NULL;
p->size = 0;
}
main.c(测试文件)
#define _CRT_SECURE_NO_WARNINGS 1
//测试
#include"Queue.h"
#if 0
int main1() {
Queue s1;
Q_Init(&s1);
Q_Push(&s1, 1);
Q_Push(&s1, 2);
Q_Push(&s1, 3);
Q_Push(&s1, 4);
while (!Q_Empty(&s1))
{
printf("%d ", Q_Front(&s1));
Q_Pop(&s1);
}
Q_Destroy(&s1);
}
#endif // 0
int main() {
//测试一个数据
Queue s1;
Q_Init(&s1);
Q_Push(&s1, 1);
Q_Push(&s1, 2);
Q_Push(&s1, 3);
while (!Q_Empty(&s1))
{
printf("%d ", Q_Front(&s1));
Q_Pop(&s1);
}
Q_Destroy(&s1);
}