队列的概念介绍:
队列就像是一群排队等待进入某个地方的人群,每个人都按照先来后到的顺序排队等候。在队列中,第一个进入队列的人最先被服务,而最后一个进入队列的人最后才能被服务。队列的特点就是先进先出,简称FIFO(First In, First Out)。
比如在购物超市结账时的场景,顾客们排成一条长龙,第一个顾客先进入结账台,依次往后,最后一个才能被服务。这种排队方式就是队列的典型应用。以及医院和其他场景的一些叫号机也是同样的原理,这样确保了排队的公平性,先进的就一定先出,队列有头和尾,不像栈那样可能会有多出出栈的顺序。
下面是一张方便理解的示意图:(图片是博主上网随便找的,如有侵权及时联系修改)
代码实现队列的基本算法:
注:
数据结构没有明确规定实现队列的代码就应该怎么这么样,下面是仅供参考的代码,只要能实现同样的功能即可。
基本算法的几种算是约定俗成的,根据实际需要而产生的,基本上与之前的顺序表,链表,栈很类似。
考虑到队伍的头删和尾插,在选择上显然更多时候使用链表会比数组更合适。
头文件Queue.h:
#include<stdbool.h>
#include<assert.h>
#include<stdlib.h>
#include<stdio.h>
typedef int QDataType;
//链表/队列的节点
typedef struct QueueNode {
int val;
struct QueueNode* next;
}QNode;
//队列
typedef struct Queue {
QNode* phead;
QNode* ptail;
int size;
}Queue;
void QueueInit(Queue* pq);
void QueueDestroy(Queue* pq);
//入队列
void QueuePush(Queue* pq, QDataType x);
//出队列
void QueuePop(Queue* pq);
QDataType QueueFrond(Queue* pq);
QDataType QueueBack(Queue* pq);
bool QueueEmpty(Queue* pq);
int QueueSize(Queue* pq);
源文件Queue.c:
#include"Queue.h"
void QueueInit(Queue* pq) {
assert(pq);
pq->phead = NULL;
pq->ptail = NULL;
pq->size = 0;
}
void QueueDestroy(Queue* pq) {
assert(pq);
//保留头结点
QNode* cur = pq->phead;
//循环释放队列的每个节点
while (cur) {
QNode* next = cur->next;
free(cur);
cur = next;
}
//重置队列数据
pq->phead = pq->ptail = NULL;
pq->size = 0;
}
//入队列
void QueuePush(Queue* pq, QDataType x) {
assert(pq);
//创建一个新节点
QNode* newnode = (QNode*)malloc(sizeof(QNode));
if (newnode == NULL) {
perror("malloc fail");
return;
}
newnode->val = x;
newnode->next = NULL;
//链表的尾插,分两种情况讨论,链表不为空和为空
if (pq->ptail != NULL) {
pq->ptail->next = newnode;
pq->ptail = newnode;
}
else {
pq->phead = pq->ptail = newnode;
}
pq->size++;
}
//出队列
void QueuePop(Queue* pq) {
assert(pq);
//不但要检查传过来的pq是否为空,还要检查pq中的节点是否为空
assert(pq->phead);
//只有一个节点时
if (pq->phead->next == NULL) {
free(pq->phead);
pq->phead = pq->ptail = NULL;
}
//有多个节点
else {
QNode* next = pq->phead;
//free(pq->phead);
//pq->phead = next;
pq->phead = pq->phead->next;
free(next);
}
pq->size--;
}
QDataType QueueFrond(Queue* pq) {
assert(pq);
assert(pq->phead != NULL);
return pq->phead->val;
}
QDataType QueueBack(Queue* pq) {
assert(pq);
assert(pq->ptail != NULL);
return pq->ptail->val;
}
bool QueueEmpty(Queue* pq) {
assert(pq);
return pq->size == 0;
}
int QueueSize(Queue* pq) {
assert(pq);
return pq->size;
}
test.c测试一下:
#include"Queue.h"
int main() {
Queue q;
QueueInit(&q);
QueuePush(&q, 1);
QueuePush(&q, 2);
QueuePush(&q, 3);
printf("%d ", QueueFrond(&q));
//QueuePop(&q);
QueuePush(&q, 4);
QueuePush(&q, 5);
while (!QueueEmpty(&q)) {
printf("%d ", QueueFrond(&q));
QueuePop(&q);
}
QueueDestroy(&q);
return 0;
}
希望我的博客可以帮到你,如果有什么问题或者建议欢迎在评论区讨论,谢谢支持~