队列:数据结构中的排队之道

news2024/12/24 0:03:45

在这里插入图片描述
本篇博客会讲解队列这种数据结构,并使用C语言实现。

概况

什么是队列呢?队列是一种先进先出的数据结构,即First In First Out,简称FIFO。队列有2端,分别是队头和队尾,规定只能在队尾插入数据(入队列),在队头删除数据(出队列)。比如:下图中,左边是队尾,右边是队头。
在这里插入图片描述
入队列:1
在这里插入图片描述
入队列:2
在这里插入图片描述
入队列:3
在这里插入图片描述
再依次入队列:[4 5 6]
在这里插入图片描述
出队列(会删除1)
在这里插入图片描述
出队列(会删除2)
在这里插入图片描述
出队列(会删除3)
在这里插入图片描述

结构的定义

要实现队列,如果使用数组,效率太低,因为头插、头删的时间复杂度是O(N)。所以建议用链表实现队列,并且建议使用带头+单向+不循环链表实现,入队列时尾插,出队列时头删。原因是:

  1. 单链表可以节省一些指针,结构更简单,但不影响效率。
  2. 带哨兵位的头结点,第一次插入数据,可以统一处理。
  3. 不使用循环链表,因为没必要。

结点的定义如下:

typedef int QDataType;
typedef struct QListNode
{
	struct QListNode* next;
	QDataType data;
}QNode;

为了省去尾插时找尾结点的过程,我们需要同时维护头结点和尾结点。同时,为了统计结点个数方便,需要记录有效数据的个数,这样就不用每次都遍历链表计数了。

// 队列的结构
typedef struct Queue
{
	QNode* front; // 队头
	QNode* tail;  // 队尾
	int size;     // 有效数据个数
}Queue;

申请结点

申请结点的函数声明如下:

QNode* BuyQueueNode(QDataType data);

申请一个结点,初始化其数据域和指针域。

QNode* BuyQueueNode(QDataType data)
{
	QNode* newnode = (QNode*)malloc(sizeof(QNode));
	if (newnode == NULL)
	{
		perror("malloc fail");
		return NULL;
	}
	newnode->data = data;
	newnode->next = NULL;

	return newnode;
}

初始化

初始化队列的函数声明如下:

void QueueInit(Queue* pq);

开辟一个哨兵位的头结点,并更新头尾指针。

void QueueInit(Queue* pq)
{
	assert(pq);

	// 定义哨兵位
	QNode* head = BuyQueueNode(0);

	pq->front = head;
	pq->tail = head;
	pq->size = 0;
}

入队列

入队列的函数声明如下:

void QueuePush(Queue* pq, QDataType data);

由于有哨兵位的头结点,不需要分类讨论,在尾结点后面直接插入即可。入队列只会影响尾结点,不会影响头结点。

void QueuePush(Queue* pq, QDataType data)
{
	assert(pq);

	// 创建新结点
	QNode* newnode = BuyQueueNode(data);

	// 链接在尾部
	pq->tail->next = newnode;
	pq->tail = newnode;

	pq->size++;
}

出队列

出队列的函数声明如下:

void QueuePop(Queue* pq);

这里需要分类讨论:

  1. 队列为空,不能删除。
  2. 队列中除去哨兵位的头结点之外只有1个结点,删除后需要把尾结点重置为哨兵位。
  3. 其他情况,正常尾删即可。
void QueuePop(Queue* pq)
{
	assert(pq);
	// 判断非空
	assert(!QueueEmpty(pq));

	if (pq->size == 1)
	{
		// 删除数据
		free(pq->tail);
		pq->front->next = NULL;
		pq->tail = pq->front;
	}
	else
	{
		// 至少2个数据
		QNode* first = pq->front->next;
		QNode* second = first->next;
		// 删除数据
		free(first);
		first = NULL;
		// 链接
		pq->front->next = second;
	}

	pq->size--;
}

取队头、队尾数据

函数声明如下:

QDataType QueueFront(Queue* pq);
QDataType QueueBack(Queue* pq);

直接取对应的数据即可,注意要检查队列非空。

QDataType QueueFront(Queue* pq)
{
	assert(pq);
	// 判断非空
	assert(!QueueEmpty(pq));

	return pq->front->next->data;
}

QDataType QueueBack(Queue* pq)
{
	assert(pq);
	// 判断非空
	assert(!QueueEmpty(pq));

	return pq->tail->data;
}

统计有效数据个数

统计有效数据个数的函数声明如下:

int QueueSize(Queue* pq);

由于我们维护size,用来记录有效数据个数,这个函数的实现就非常方便。

int QueueSize(Queue* pq)
{
	assert(pq);

	return pq->size;
}

判空

判断队列是否为空的函数声明如下:

bool QueueEmpty(Queue* pq);

当size为0时,队列为空。

bool QueueEmpty(Queue* pq)
{
	assert(pq);

	return pq->size == 0;
}

销毁

销毁队列的函数声明如下:

void QueueDestroy(Queue* pq);

遍历链表,销毁结点,最后销毁哨兵位。

void QueueDestroy(Queue* pq)
{
	assert(pq);

	QNode* del = pq->front;
	while (del)
	{
		QNode* next = del->next;
		free(del);
		del = next;
	}

	pq->front = NULL;
	pq->tail = NULL;
	pq->size = 0;
}

总结

使用单向带头不循环链表实现队列,满足“先进先出”的特性。

感谢大家的阅读!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/560304.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

华为OD机试真题 Java 实现【单核CPU任务调度】【2023Q2 200分】

一、题目描述 现在有一个CPU和一些任务需要处理,已提前获知每个任务的任务D、优先级、所需执行时间和到达时间。 CPU同时只能运行一个任务,请编写一个任务调度程序,采用“可抢占优先权调度”调度算法进行任务调度,规则如 下&…

嵌入式Android系统启动基本分析

目录 第一:Android系统架构图: 第二:Android 系统启动流程如下: 第三:Android 层级分析 第四:案例分析 第五:Android 权限问题 上一篇我们讲了 Linux 系统的启动流程,本文讲解一…

QTableWidget样式设置

QTableWidget的样式分为几个部分: 分别是: 外框:QTableWidget 表头:QHeaderView 表头字段:QHeaderView::section 表格:QTableWidget::item 选中的表格:QTableWidget::item::selected 水平滚动条…

课时七—进程同步(一)

1、同步与互斥的基本概念 1)临界资源 (1)临界资源:是一次仅允许一个进程使用的共享资源。各进程采取互斥的方式,实现共享的资源称作临界资源。属于临界资源的硬件有,打印机,磁带机等;软件有消息…

javase个人小结

一、数据类型 二、运算符(需要注意的) /:如果是int类型,那么会保留整数,舍去余数 列如:10/3 3 优先级:拿不准就加括号,括号优先级最高 三、类和对象 什么是封装,继承…

连接器信号完整性仿真教程 三

本文将讲解CST边界(Boundary)、背景(Background)的概念及背景材料与边件设置。边界与背景是CST仿真电磁的基础,有必要了解它,并掌握其设置方法与步骤。并以两个实例演示了具体设置的操作。 一 背景、边界与…

深度学习—目标检测标注数据集

深度学习之目标检测 PASCAL数据集 PASCAL VOC挑战赛(The PASCAL Visual Object Classes)是一个世界级的计算机视觉挑战赛,PASCAL全称:Pattern Analysis,Statical Modeling and Computational Learning,是…

磐维数据库应用案例荣获2022年度杭州商用密码应用优秀案例二等奖

2023年5月8日上午,在2023西湖论剑数字安全大会商用密码应用论坛上发布了2022年度杭州商用密码应用优秀案例,其中由中国移动通信集团浙江有限公司和中移动信息技术有限公司联合申报的 《基于磐维数据库的CRM营销系统商用密码应用案例》荣获二等奖。 20…

Linux下gdb基础命令演示,及命令汇总图

提示:本文主要介绍了什么是gdb,以及gdb指令及其具体使用案例 ————故不积跬步,无以至千里;不积小流,无以成江海。 文章目录 一、gdb模式下命令一览。1.1基本命令:1.2 断点命令:1.3 数据命令…

实时频谱分析-2.3实时频谱分析

实时频谱分析 频谱分析要想归入实时类别中,必须没有间隙地、不确定地处理关心的频宽内包含的所有信息。RSA 必须获得时域波形中包含的全部信息,把信息转换成频域信号。实时完成这一点必须满足多个重要的信号处理要求: 1)提供足够…

【计算思维题】少儿编程 蓝桥杯青少组计算思维真题及详细解析第3套

少儿编程 蓝桥杯青少组计算思维题及详细解析第3套 1、浩浩的左手边是 A、兰兰 B、贝贝 C、青青 D、浩浩 答案:B 考点分析:主要考查小朋友们的观察能力,从给定的图中可以看到:浩浩的左手边是贝贝,所以答案B 2、2 时 30 分,钟面上时针和分针形成的角是什么角 A、钝角…

与vCenter无法通讯时更改虚拟机的网络配置

客户的VCSA由于虚拟机的配置问题导致无法启动,需要通过重新创建VCSA的虚拟机配置的方式来恢复。但是,由于ESXi主机上的所有物理网口都已分配给了分布式网络交换机,在重建虚拟机配置时不能指定标准交换机的端口组来配置网络。而如果将虚拟机的…

找C++程序员工作被卡学历怎么办?我来分享一下实用的方法

当学历低的程序员找C程序员工作时,最担心的问题就是学历卡关。但只有资深的人力资源经理才知道那个行业内的潜规则。对于学历低的程序员来说,这是简直是很难逾越的关卡。 企业招聘程序员时,对学历的要求几乎全是本科及以上学历。这让学历低的…

C++11 列表初始化initializer_list

引子 C11,是继C98后的一次有力更新,引进了很多好用的语法,STL也添加了几个新容器,也解决了很多的问题。本篇博客就学习一下C11列表初始化的新语法和 initializer_list 文章目录 引子一. 列表初始化二. initializer_list结束语 一…

接口测试的流程?怎么设计接口测试用例?两张图给你讲的明明白白

目录 一、简介 二、接口测试的流程 三、为什么要写用例 四、接口用例设计 一、简介 在开始接口测试之前,我们想一下,接口测试的流程是什么?说到这里,有些人就会产生好奇和疑问,心里mmp:接口测试要什么流…

详细的谈谈,软件测试定义、目的及原则。

1.软件测试定义 软件测试就是在产品上线前,对软件需求、设计方案和编码实现的核查。软件测试的定义 软件测试是为了发现错误而执行程序的过程使用人工或自动方式来运行并测试某个系统,以此来检验系统是否满足规定的需求并确定预期结果与实际结果的差异 …

WEB安全:深入反射式dll注入技术

一、前言 dll注入技术是让某个进程主动加载指定的dll的技术。恶意软件为了提高隐蔽性,通常会使用dll注入技术将自身的恶意代码以dll的形式注入高可信进程。 常规的dll注入技术使用LoadLibraryA()函数来使被注入进程加载指定的dll。常规dll注入的方式一个致命的缺陷…

你不会还不知道如何用Python写一个切水果的小游戏吧

目录 引言 一、需要导入的包 二、窗口界面设置 三、随机生成水果位置 四、绘制字体 五、玩家生命的提示 六、游戏开始与结束的画面 七、游戏主循环 引言 水果忍者的玩法很简单,尽可能的切开抛出的水果就行。 今天小五就用python简单的模拟一下…

linux centos 安装zookeeper服务

一、进入官网:Apache ZooKeeper 二、下载安装包 可以使用wget 下载,我这里服务器的原因就不使用了,直接在网页使用http下载,然后通过xftp上传到服务器 下载完成后通过xftp上传到linux服务器 三、解压 tar -zxvf apache-zookeepe…

520中国劲酒携手撒贝宁直播探厂,共同见证健康跑活动启幕

5月20日是“网络情人节”,每年一度的 520,所有人都沉在真爱告白的浓情氛围当中,对于全中国的劲酒爱好者来说,520 却有着不一样的意义,每年 520 劲粉节,中国劲酒以爱之名,号召和鼓励劲粉们培养持之以恒的健康生活方式。      520 当日,总台央视主持人撒贝宁来到了湖北大冶市…