初阶数据结构(六)队列的介绍与实现

news2024/10/7 10:14:40

💓博主csdn个人主页:小小unicorn💓
⏩专栏分类:C++

🚚代码仓库:小小unicorn的学习足迹🚚
🌹🌹🌹关注我带你学习编程知识

  • 队列的介绍
    • 队列的概念:
    • 队列的结构:
  • 队列的实现
    • 创建队列
    • 初始化队列
    • 销毁队列
    • 队尾入队列
    • 对头出队列
    • 获取队列头部元素
    • 获取队列尾部元素
    • 检测队列是否为空
    • 获取队列中有效元素个数
  • 总结:

队列的介绍

队列的概念:

队列:只允许在一端进行插入数据操作,在另一端进行删除数据操作的特殊线性表。队列遵守先进先出FIFO(First In First Out)的原则。

入队列:队列的插入操作叫做入队列,进行插入操作的一端称为队尾。

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

队列的结构:

在这里插入图片描述

队列的实现

队列也可以数组和链表的结构实现,使用链表的结构实现更优一些,因为如果使用数组的结构,出队列在数组头上出数据,效率会比较低。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

创建队列

首先我们需要创建一个结点类型,类型包含了该结点的数据指向下一结点的指针。

typedef int QDataType;

typedef struct QListNode
{
	struct QListNode* next;               //指针域
	QDataType data;                       //数据域
}QListNode;

其次队列与普通链表又有所不同,普通链表只需要知道链表的头指针,而队列的信息包括了队头和队尾,所以我们需要再创建一个结构体用于存放队列的队头和队尾。

typedef struct Queue
{
	QListNode* head;//队头
	QListNode* tail;//队尾
}Queue;

初始化队列

我们需要一个初始化函数,对刚创建的队列进行初始化

//初始化队列
void QueueInit(Queue* pq)
{
	assert(pq);
	//起始时队列为空
	pq->head = NULL;
	pq->tail = NULL;
}

销毁队列

因为队列中的每一个结点所占用的内存空间都是动态开辟的,当我们使用完队列后需要及时释放队列中的每一个结点。

//销毁队列
void QueueDestroy(Queue* pq)
{
	assert(pq);

	QListNode* cur = pq->head;//接收队头
	//遍历链表,逐个释放结点
	while (cur)
	{
		QListNode* next = cur->next;
		free(cur);
		cur = next;
	}
	pq->head = NULL;//队头置空
	pq->tail = NULL;//队尾置空
}

队尾入队列

入队列,也就是说申请一个新结点并将其链接到队尾,然后改变队尾的指针指向

需要注意的是:若队列中原本无数据,那么我们只需让队头和队尾均指向这个新申请的结点即可。

//队尾入队列
void QueuePush(Queue* pq, QDataType x)
{
	assert(pq);

	QListNode* newnode = (QListNode*)malloc(sizeof(QListNode));//申请新结点
	if (newnode == NULL)
	{
		printf("malloc fail\n");
		exit(-1);
	}
	newnode->data = x;                                        //新结点赋值
	newnode->next = NULL;                                     //新结点指针域置空
	if (pq->head == NULL)                                     //队列中原本无结点
	{
		pq->head = pq->tail = newnode;                         //队头、队尾直接指向新结点
	}
	else                                                       //队列中原本有结点
	{
		pq->tail->next = newnode;                              //最后一个结点指向新结点
		pq->tail = newnode;                                    //改变队尾指针指向
	}
}


对头出队列

出队列,也就是释放队头指针指向的结点并改变队头指针的指向

若队列中只有一个结点,那么直接将该结点释放,然后将队头和队尾置空即可。

//队头出队列
void QueuePop(Queue* pq)
{
	assert(pq);
	assert(!QueueEmpty(pq));                            //检测队列是否为空

	if (pq->head->next == NULL)                         //队列中只有一个结点
	{
		free(pq->head);
		pq->head = NULL;
		pq->tail = NULL;
	}
	else//队列中有多个结点
	{
		QListNode* next = pq->head->next;
		free(pq->head);
		pq->head = next;                                 //改变队头指针指向
	}
}

获取队列头部元素

获取队列头部元素,就是返回队头指针指向的数据。

//获取队列头部元素
QDataType QueueFront(Queue* pq)
{
	assert(pq);
	assert(!QueueEmpty(pq));                        //检测队列是否为空

	return pq->head->data;                          //返回队头指针指向的数据
}

获取队列尾部元素

获取队列尾部元素,也就是返回队尾指针指向的数据。

//获取队列尾部元素
QDataType QueueBack(Queue* pq)
{
	assert(pq);
	assert(!QueueEmpty(pq));                  //检测队列是否为空

	return pq->tail->data;                    //返回队尾指针指向的数据
}

检测队列是否为空

检测队列是否为空,也就是判断队头指针指向的内容是否为空。

//检测队列是否为空
bool QueueEmpty(Queue* pq)
{
	assert(pq);

	return pq->head == NULL;
}

获取队列中有效元素个数

队列中有效元素个数,也就是队列中的结点个数

我们只需遍历一下队列,统计队列中的结点数并返回即可。

//获取队列中有效元素个数
int QueueSize(Queue* pq)
{
	assert(pq);

	QListNode* cur = pq->head;                       //接收队头
	int count = 0;                                   //记录结点个数
	while (cur)                                      //遍历队列
	{
		count++;
		cur = cur->next;
	}
	return count;                                    //返回队列中的结点数
}


总结:

初阶数据结构(五)(六)讲的是栈和队列,它们都是特殊的线性表,只不过对插入和删除操作做了限制。

(stack)是限定仅在表尾进行插入和删除操作的线性表。

对列(queue)是只允许在一端进行插入操作,而在另一端进行删除操作的线
性表。

它们均可以用线性表的顺序存储结构来实现,但都存在着顺序存储的一些弊端。因此它们各自有各自的技巧来解决这个问题。

对于栈来说,如果是两个相同数据类型的栈,则可以用数组的两端作栈底的方法来让两个栈共享数据,这就可以最大化地利用数组的空间。

对于队列来说,为了避免数组插入和删除时需要移动数据,于是就引入了循环队列,使得队头和队尾可以在数组中循环变化。解决了移动数据的时间损耗,使得本来插入和删除是O(n)的时间复杂度变成了O(1)。

它们也都可以通过链式存储结构来实现,实现原则上与线性表基本相同,如下图所示。

文章到这里就要告一段落了,有更好的思路或问题的,欢迎留言评论区。

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

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

相关文章

webassembly003 ggml ADAM (暂记)

Adam优化器的工作方式是通过不断更新一阶矩估计和二阶矩估计来自适应地调整学习率,并利用动量法来加速训练过程。这种方式可以在不同的参数更新方向和尺度上进行自适应调整,从而更有效地优化模型。 https://arxiv.org/pdf/1412.6980.pdf 参数 这些参数…

SCI论文创新思路

SCI论文创新思路 一、 创新的分类1、算法创新2、架构创新3、迁移创新4、思想创新5、方法创新6、组合创新 二、组合创新的必要性三、组合创新的流程四、组合创新举例1、组合创新公式2、生活中的例子3、关于CV的例子4、魔改的方法 一、 创新的分类 1、算法创新 比如提出CNN、LS…

django-发送邮件

一、业务场景 业务警告 邮箱验证 密码找回 二、邮件相关协议 1.SMYTP(简答邮件传输协议 25端口) 属于“推送”协议 负责发送 2.IMAP(交互式邮件访问协议,应用层协议,143端口) 用于从本地邮件客户端…

华为云Stack的学习(三)

四、华为云Stack公共组件 1.华为云Stack公共负载均衡方案介绍 1.1 LVS原理 LVS是四层负载均衡,建立在OSI模型的传输层之上,所以效率非常高。 LVS有两种转发模式: NAT模式的转发主要通过修改IP地址(位于OSI模型的第三层网络层&…

可直接运营的零工零活招聘流量主小程序开发演示

在互联网高速发展的今天,诞生了很多互联网招聘平台,极大的方便了企业与求职者之间的对接。而在招聘市场,零工灵活招聘求职也是不可忽视的一个重要组成部分。基于帮助招聘企业快速获得优质员工和求职者快速寻找合适企业,我们在招聘…

echarts画一个简单的饼图 中间是空的 环有两种颜色一种是底色 一种是百分比的颜色

//dom打印出来大概是什么样子下方有个图可以作为参考 ecInit(correctRate, processAnalysisVO.correctRate, (100-processAnalysisVO.correctRate));//如效果图//饼图 function ecInit(dom, correctRate, errorRate) {var dom dom; //就是你要放入的盒子元素var myChart ech…

KCC@北京|开源到底带给了我们什么?

KCC,全称 KAIYUANSHE City Community(中文:开源社城市社区)是由开源社发起,旨在让开源社区在每个城市落地生根的地域性开源组织。 自2023年2月份发起以来,我们已经在南京、上海、深圳、北京、硅谷、新加坡、…

postgresql类型转换函数

postgresql类型转换函数 简介CAST 函数to_date 函数to_timestamp 函数to_char 函数to_number 函数隐式类型转换 简介 类型转换函数用于将数据从一种类型转换为另一种类型。 CAST 函数 CAST ( expr AS data_type )函数用于将 expr 转换为 data_type 数据类型;Post…

macOS上开源免费的新闻阅读器SABnzbd

SABnzbd Mac版是一款运行在Mac平台上的开源新闻阅读器,这款阅读器界面简约、功效简单强大,使用SABnzbd时可以帮助使用Python语言编写,让用户使用usenet新闻组更便利,是你阅读新闻的好帮手! SABnzbd具有以下主要特点&a…

Wolfram Mathematica 13 for Mac 数学计算工具

Wolfram Mathematica for Mac是一款功能强大、划时代的科学计算软件。它结合了数字和符号计算引擎、图形系统、编程语言、文本系统以及与其他应用程序的高级连接,在许多功能方面处于世界领先地位,截至2009年,它是使用最广泛的数学软件之一。人…

小小的消火栓 蕴藏着“大智慧”

2023年8月22日14时24分,天津消防救援总队指挥中心接到报警:天津市南开区万兴街道南京路新天地大厦外墙起火。接警后,总队立即调派23个消防站及南开、和平支队全勤指挥部,共计284名消防救援人员、62辆消防车赶赴现场。总队全勤指挥…

4G的机器上申请8G的内存,是否可以成功?

前言 4G的机器上申请8G的内存,是否可以成功?这个问题没有办法,是没有办法进行回答,这个问题要考虑三个前置条件: 操作系统是 32 位的,还是 64 位的?申请完 8G 内存后会不会被使用?…

用canvas做柱状图

<!DOCTYPE HTML> <html><head lang"en"><meta charset"UTF-8"><title>Canvans绘制统计图</title><style>body {text-align: center;}canvas {background: #ddd;}</style> </head><body><h…

为什么磁盘被写保护怎么解除?这篇文章告诉你

磁盘被写保护是指磁盘无法写入或修改数据&#xff0c;这可能会使您的计算机或存储设备无法正常工作。当发现磁盘被写保护时&#xff0c;我们应该怎么做呢&#xff1f;磁盘被写保护怎么解除&#xff1f;这篇文章将带大家了解一下磁盘被写保护的原因和对应的解除方法吧。 ▌为什…

mac使用VsCode远程连接服务器总是自动断开并要求输入密码的解决办法

在mac中使用vscode远程连接服务器&#xff0c;时常会出现自动断开并要求重新输入服务器密码的问题&#xff0c;接下来让我们来解决它&#xff1a; 1、首先&#xff0c;在本地创建公钥&#xff1a; ssh-keygen 这条命令执行之后&#xff0c;出现提示直接回车即可&#xff1b;直…

C语言练习题Day2

今天继续分享C语言刷题练习 一、选择题 1、以下程序段的输出结果是&#xff08; &#xff09; #include<stdio.h> int main() { char s[] "\\123456\123456\t"; printf("%d\n", strlen(s)); return 0; }A: 12 B: 13 C: 16 D: 以上都不对 这题考的…

monorepo更新组件报错,提示“无法加载文件 C:\Program Files\nodejs\pnpm.ps1,因为在此系统上禁止运行脚本”

解决方法&#xff1a; 第一步&#xff1a;管理员身份运行 window.powershell&#xff0c; win x打开powerShell命令框&#xff0c;进入到对应项目路径。 第二步&#xff1a;执行&#xff1a;get-ExecutionPolicy&#xff0c;显示Restricted&#xff0c;表示状态是禁止的; 第…

Win11 电脑的 Win + E 快捷键失效

报的错误信息如下&#xff1a; 该文件没有与之关联的应用来执行该操作。请安装应用&#xff0c;若已经安装应用&#xff0c;请在”默认应用设置"页面中创建关联。 报错原因&#xff1a;系统注册表被改写了导致的出错 解决办法&#xff1a; 1、首先&#xff0c;按键盘上的…

k3s在线快速安装部署

中文文档&#xff1a;快速入门指南 | K3s 一、k3s父节点安装 设置主机唯一名称 hostnamectl set-hostname 192.168.56.105 开放k3s所需端口 6443 51820 和 51821 在线安装主节点 curl -sfL https://rancher-mirror.rancher.cn/k3s/k3s-install.sh | INSTALL_K3S_MIRRORcn…

36. 国庆期间每个品类的商品的收藏量和购买量

文章目录 题目需求思路一实现一题目来源 题目需求 从订单明细表&#xff08;order_detail&#xff09;和收藏信息表&#xff08;favor_info&#xff09;统计2021国庆期间&#xff0c;每个商品总收藏量和购买量。 期望结果如下&#xff08;截取部分&#xff09;&#xff1a; …