当前位置: 首页 > news >正文

数据结构(6)——队列

目录

前言

一、队列的概念及其结构

二、实现

 2.1结构体定义

2.2初始化

2.3销毁链表

2.4尾插入(入队)

2.5头删(出队)

2.6个数

2.7检验是否为空

2.8取队头数据

2.9取队尾数据

三、检验

总结


前言

本文介绍队列,以及实现的代码。


一、队列的概念及其结构

相对于栈来说,队列跟栈就是相反的。

队列只允许在一端插入数据,在另一端进行删除数据操作的特殊线性表,队列具有先进先出的特性。(First In First Out,FIFO),队列常用于实现缓冲区、任务调度等场景。

入队列:进行插入操作的一端称为队尾

出队列:进行删除操作的一端称为队头

下面是一个简单的图形,方便理解:

这里如果实现链表的话,使用一个单链表就可以,使用数组的话不方便。

二、实现

这里要实现的功能有:

void QueueInit(Queue* pq);//初始化
void QueueDestroy(Queue* pq);//删除销毁
void QueuePush(Queue* pq, QDatatype x);//尾插入
void QueuePop(Queue* pq);//头删
void QueueSize(Queue* pq);//个数
bool QueueEmpty(Queue* pq);//检验是否为空
QDatatype QueueFront(Queue* pq);//队头数据
QDatatype QueueBack(Queue* pq);//队尾数据

 2.1结构体定义

结构体定义,因为使用的是单链表,所以也就是定义一个单链表的结构体节点:

typedef int QDatatype;//数据类型typedef struct QueueNode
{struct QueueNode* Next;//节点QDatatype data;//数据
}QNode;

因为队列的定义是先进先出,队尾进,队头出,所以我们要实现这个功能,需要链表的头和尾,这里为了传入参数的方便,用另一个结构体封装一下头尾指针,传参只需要传这个结构体就可以获取头尾指针了。

typedef struct Queue
{QNode* head;//头指针QNode* tail;//尾指针
}Queue;

2.2初始化

初始化只需要初始化这个结构体就可以,因为我们后期需要节点结构体往这里创建连接节点,从而实现head和tail的移动,方便后期的使用。

void QueueInit(Queue* pq)//初始化
{assert(pq);pq->head =pq->tail = NULL;pq->size = 0;
}

此时,pq这个实例头尾指针因为没有指向,所以初始化给NULL(当然也避免野指针的问题),然后里面的节点数量给0,这样就实现了一个带头尾指针单链表的初始化。

2.3销毁链表

销毁链表,需要把链表中每一个节点都销毁掉,否则出现了内存泄漏。

void QueueDestroy(Queue* pq)//删除销毁
{assert(pq);QNode* cur = pq->head;while (cur){QNode* next = cur->next;free(cur);cur = next;}pq->head = pq->tail = NULL;pq->size = 0;
}

首先可以检查一下链表中是否有数据,这里通过一个遍历,把链表中的每一个节点free掉,最后回到初始化状态。当循环结束,也就是把里面的节点全部free了。

2.4尾插入(入队)

尾插就是链表的尾插,只不过这里加入了头尾指针的问题。

依旧是首先要malloc一个空间用来存放节点,检验一下节点是否创建成功,如果没成功就输出错误信息并结束,如果成功了,就把x传入data。

void QueuePush(Queue* pq, QDatatype x)//尾插入
{QNode* newnode = (QNode*)malloc(sizeof(QNode));if (newnode == NULL){perror("malloc fail");return;}newnode->data = x;//newnode->next=NULL;if (pq->head == NULL){assert(pq->tail == NULL);pq->head = pq->tail = newnode;}else{pq->tail->next = newnode;pq->tail = newnode;}pq->tail->next = NULL;pq->size++;
}

然后判断head和tail是否都为null,如果都为null,就代表里面没有节点,就直接把newnode赋给tail和head就可以,接下来,如果里面有节点了,就把新newnode赋给tail(尾节点)的下一个,然后更新tail的指针,最后把tail的下一个赋为空,防止内存泄漏(避免next为野指针),这里需要留意,然后把size++,更新一下里面数据节点的数量。

2.5头删(出队)

这里了进行分开判断,首先对节点和实例进行了检验,然后通过判断是否是一个节点还是多个节点进行分开判断,如果多个节点就按照else里的处理,如果只有一个节点就可以直接删除此节点,最后size--,把数量更新一下。

void QueuePop(Queue* pq)//头删
{assert(pq);assert(pq->head!=NULL);if (pq->head == pq->tail){free(pq->head);pq->head = pq->tail = NULL;}else{QNode* cur = pq->head->next;free(pq->head);pq->head = cur;}pq->size--;
}

2.6个数

这里之前定义的size就有用了,我们可以直接返回size就可以了。

void QueueSize(Queue* pq)//个数
{assert(pq);printf("个数:%d\n", pq->size);
}

2.7检验是否为空

检验是否为空也就是检验size是否为0。

bool QueueEmpty(Queue* pq)//检验是否为空
{assert(pq);return pq->size == 0;
}

2.8取队头数据

QDatatype QueueFront(Queue* pq)//队头数据
{assert(pq);assert(!QueueEmpty(pq));return pq->head->data;
}

2.9取队尾数据

QDatatype QueueBack(Queue* pq)//队尾数据
{assert(pq);assert(!QueueEmpty(pq));return pq->tail->data;
}

三、检验

我们可以通过一个test.c文件来验证一下刚才写的函数,也可以帮助理解。

#include"Queue.h"
int main()
{Queue st;QueueInit(&st);QueuePush(&st, 1);QueuePush(&st, 2);QueuePush(&st, 3);QueuePush(&st, 4);QueuePush(&st, 5);QueueSize(&st);QueuePop(&st);QueuePop(&st);QueueSize(&st);//打印输出while(!QueueEmpty(&st)){printf("%d ", QueueFront(&st));QueuePop(&st);}printf("\n");QueueDestroy(&st);//销毁return 0;
}

道爷我成了!

当然这里只是基本的东西,有很多地方可以改善和添加功能,这里只对简单的队列进行原理的学习。


总结

队列是一种先进先出(FIFO)的数据结构,常用于实现缓冲区、任务调度等场景。队列的基本操作包括初始化、销毁、入队、出队、获取队列大小、检验队列是否为空以及获取队头和队尾元素。

队列的实现可以通过链表或数组来完成,本文介绍了使用单链表实现队列的基本操作。在实现过程中,需要定义队列节点结构体以及队列结构体,同时实现各种操作函数来对队列进行操作。

通过编写测试代码,可以验证队列的各项功能是否正常运行,帮助加深对队列数据结构的理解。

相关文章:

  • 10软件测试需求分析案例-查询学习信息
  • 基于蚁群算法的柔性车间调度最优化设计
  • 实用指南:如何找到完美契合的视频素材
  • AI 驱动抗生素发现:从靶点到化合物测试
  • 88. 合并两个有序数组
  • 【FFmpeg从入门到精通】第三章-FFmpeg转封装
  • 从句详细解析
  • day 20
  • U-Boot 启动过程详解
  • 案例驱动的 IT 团队管理:创新与突破之路:第六章 组织进化:从案例沉淀到管理体系-6.1 案例库建设方法论-6.1.2案例分级与标签体系
  • 零基础上手Python数据分析 (18):Matplotlib 基础绘图 - 让数据“开口说话”
  • Cril 截取字段-生成hostname
  • 08-DevOps-向Harbor上传自定义镜像
  • 北斗短报文终端与5G融合:构建空天地海一体化通信新生态
  • XCZU27DR‑2FFVE1156I Xilinx Zynq UltraScale+ RFSoC
  • QT采用cmake编译时文件解析
  • IsaacSim Asserts 配置
  • Warcraft Logs [Classic] [WCL] Usage Wizard <HTOC>
  • matlab读取CMEMS海洋温度数据并调整图片的比例
  • Linux基础IO(九)之软链接
  • 东航推出“上博号”班机,上博设立“东航特展厅”
  • “月光女神”莎拉·布莱曼来上海,再现好莱坞浮华幻梦
  • 火山总裁谭待:很多Agent的能力还停留在类似自动驾驶的L1阶段
  • 江西南昌:千年银杏树倒伏,全力抢救进行时​
  • 肯尼亚总统鲁托将访华
  • 这颗“超级地球”真有生命?剑桥团队在系外行星K2-18b发现气体证据