队列
概念
队列是一种只允许在一端插入数据操作,另一端进行删除数据操作的特殊线性表,队列具有先进先出FIFO(First In First Out)的原则
入队列:进行插入操作的一端称为队尾
出队列:进行删除操作的一端称为队头
队列的结构就像商店排队结账一样,先排队的先结账
如下图的入队顺序1,2,3,那么出队顺序依然是1,2,3
因为考虑到头删和尾插,链队列书写起来更加容易,因此在本篇文章中我们按照链队列进行讲解
关于链表的基础知识可以看我之前的文章: 链表
接下来我们用代码来实现队列的结构和操作
代码实现
结构
链队列中的每个数据通过指针前后链接,用QueueNode作为存放数据的队列节点
队列结构体Queue用于存放头节点、尾节点、队列大小(节点数量)
1 | typedef int QDataType;//方便修改储存的数据类型 |
初始化
对队列的结构初始化
函数接口传入队列的指针
1.断言队列指针
2.头指针、尾指针置空
3.队列大小置0
1 | void QueueInit(Queue* pq) |
销毁
对队列的空间占用销毁
函数接口传入队列的指针
1.断言队列指针
2.创建指针cur指向头节点
3.在while中,用指针next指向cur的下一节点,释放cur,令cur指向next。以此销毁整个队列链表
4.头节点、尾节点置空
5.队列大小置0
1 | void QueueDestroy(Queue* pq) |
尾插
从队尾插入数据
函数接口传入队列指针和新数据val
1.断言队列指针
2.利用malloc为新节点开辟空间,并判断是否开辟成功
3.新节点next指针置空,数据赋值为val
4.如果队列中没有节点,此时尾节点指针为NULL,那么将头节点和尾节点指针指向新节点
5.如果队列中有节点,那么将新节点尾插在链表中,最后将尾节点指针指向新节点
6.将队列大小加1
1 | void QueuePush(Queue* pq, QDataType val) |
头删
将队头节点删除
函数结构传入队列指针
1.断言队列指针
2.断言队列大小不为零
3.如果头节点的下一节点为空,那么直接释放头节点,将头尾节点置空
4.如果头节点下一节点不为空,那么用next指针保存头节点的下一节点,释放头节点,将next指向的节点设为头节点
5.将队列大小减1
1 | void QueuePop(Queue* pq) |
队列元素数量
获取队列元素的数量
函数接口传入队列指针,返回整型
1.断言队列指针
2.直接返回size
1 | int QueueSize(Queue* pq) |
获取队列头
获取队列头数据
函数接口传入队列指针,返回储存的数据类型
1.断言队列指针
2.直接返回头节点的数据
1 | QDataType QueueFront(Queue* pq) |
获取队列尾
获取队列尾数据
函数接口传入队列指针,返回储存的数据类型
1.断言队列指针
2.直接返回尾节点的数据
1 | QDataType QueueBack(Queue* pq) |
判空
判断队列是否为空
函数接口传入队列指针,返回bool类型
1.断言队列指针
2.直接返回比较结果
1 | bool QueueEmpty(Queue* pq) |
注意
所有对结构体和类的操作一定要通过封装的方法实现,即使像判空这种只有一行代码,因为没有函数内部加以限制,直接访问可能会错误修改数据或者访问的并不是想要的数据