DS线性表之队列的讲解和实现(5)

news2024/10/24 3:25:35

文章目录

  • 前言
  • 一、队列的概念及结构
  • 二、队列的实现
    • 队列节点和队列
    • 初始化
    • 销毁
    • 判断是否为空
    • 入队列
    • 出队列
    • 获取队头队尾数据
    • 获取队列元素个数
  • 三、实际使用效果
  • 总结


前言

  队列实现源代码
  队列是我们遇到的第二个实用数据结构,栈和队列地位等同


一、队列的概念及结构

  队列是指只允许在一端进行插入数据操作,在另一端进行删除数据操作的特殊线性表。队列具有先进先出 FIFO(First In First Out) 这一点跟栈的先进后出是相反的

队列的核心操作有两个:

  • 入队列:即尾插,进行插入操作的一端称为队尾
  • 出队列:即头删,进行删除操作的一端称为对头

在这里插入图片描述

队列可以考虑顺序表和链表来实现,但是因为队列是一种一端插入一端删除的数据结构,所以最好的实现方式是头删尾插效率高的方式

  1. 顺序表实现:尾插和尾删效率较高,但是头插和头删效率低,因此不太适合
  2. 单链表实现:头删尾插效率较高,链表头删,链表尾插
  3. 双向链表实现:头插头删尾插尾删效率都较高,可以实现队列

照这么看,似乎双向链表是最完美的答案

但是实际上,我们是采用第二种单链表来实现队列,你可能会差异,单链表要遍历一遍才能到达尾节点,而双向链表可以在常量操作内访问到尾节点,为什么我们还会采用单链表来实现队列呢?

答案是我们定义一个队列节点结构体的前提下,在定义一个队列的结构体,里面放着两个队列节点指针front、tail,这样双向链表这里就显得过于复杂,且多开辟了一个头节点,浪费了一点空间,也是不太适合的一种体现

二、队列的实现

  好,掌握了以上知识后,我们来立刻实现!

队列节点和队列

就像前文说的,我们定义两个结构体来实现队列
大致有点像下图:
在这里插入图片描述

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

typedef struct Queue
{
    QNode* head;
    QNode* tail;

	// 根据需要甚至还可以定义一个大小变量
	// int size;
}Queue;

初始化

首先我们肯定要先验空,确保我们确确实实实例化了一个队列结构体q,此时q内部的两个指针,我们需要先置空

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

    pq->head = pq->tail = NULL;
}

销毁

动态开辟的内存,需要手动释放,且由于是链表,所以需要一个一个循环释放
因此思路就是通过一个指针变量cur,一直销毁直到指向为空
在这里插入图片描述

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

    QNode* cur = pq->head;
    while (cur != NULL){
        QNode* next = cur->next;
        free(cur);
        cur = next;
    }
    pq->head = pq->tail = NULL; // 头尾节点指针所指向的内容已被回收,因此不置空将成为野指针
}

判断是否为空

我们看初始化函数就知道,当队列为空的时候,头节点指针为空指针(其实尾节点指针也是~),我们可以通过这个来判断

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

    return pq->head == NULL;
}

入队列

入队就是尾插
在这里插入图片描述
但是我们要分两种情况,一种是队列有数据,另外一种是队列没有数据的时候,这时候头尾节点指针都指向这个新开辟的节点;如果队列已经有数据了,这时候尾节点指针发生变化

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

    QNode* newNode = (QNode*)malloc(sizeof(QNode));
    if (newNode == NULL){
        printf("malloc fail\n");
        exit(-1);
    }

    newNode->data = val;
    newNode->next = NULL;

    if (pq->tail == NULL){ // 如果无数据,用pq->head来判断也行
        pq->head = pq->tail = newNode;
    }
    else {
        pq->tail->next = newNode;
        pq->tail = newNode; // 此时newNode就是新的尾节点
    }
}

出队列

出队就是头删
在这里插入图片描述

void QueuePop(Queue* pq)
{
    assert(pq);
    assert(pq->head);

    if (pq->head->next == NULL) // 只有一个节点的时候
    {
        free(pq->head);
        pq->head = pq->tail = NULL;
    }
    else { // 当有多个节点的时候
        QNode* next = pq->head->next;
        free(pq->head);
        pq->head = next;
    }
}

获取队头队尾数据

对于队列,我们是有权限来访问队头队尾两个元素,就像栈也有权限访问栈顶元素一样(但是栈底不行!)

QDataType QueueFront(Queue* pq)
{
    assert(pq);
    assert(pq->head);

    return pq->head->data;
}

QDataType QueueBack(Queue* pq)
{
    assert(pq);
    assert(pq->head);

    return pq->tail->data;
}

获取队列元素个数

其实你的队列如果有size变量的话,那这里应该蛮简单,只是我这里提供的没有,那么就是经典的遍历套路

int QueueSize(Queue* pq)
{
	assert(pq);
	
	int size = 0;
	QNode* cur = pq->head;
	while (cur != NULL)
	{
		size++;
		cur = cur->next;
	}
	
	return size;
}

三、实际使用效果

// 各接口一览
void QueueInit(Queue* pq);
void QueueDestroy(Queue* pq);

void QueuePush(Queue* pq, QDataType val);
void QueuePop(Queue* pq);

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

bool isQueueEmpty(Queue* pq);

在这里插入图片描述


总结

  栈和队列,将会贯穿我们后面的学习,所以,请对它们有深刻的认识

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

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

相关文章

SAP学习笔记 - 豆知识13 - Msg 番号 NR751 - Object RF_BELEG R100、番号範囲間隔 49 不存在 FBN1

其实这种就是自动採番的番号没弄。 比如跨年了,那该新年度的番号范围没弄啊,就会出这种错误。 把番号范围给加一下就可以了。 1,现象 比如点 VL02N 出荷传票变更 画面,点 出库确认 就会出如下错误: Object RF_BEL…

双十一有哪些必买的好物清单?分享2024年双十一好用的好物排行榜

随着数字化生活的日益普及,每年的双十一已不仅仅是简单的购物狂欢,在这个充满期待的日子,无数家庭和个人都希望能以最实惠的价格,淘到那些能给日常生活带来便利与乐趣的好物。今天我们将聚焦于那些兼具实用性和创新性的产品&#…

使用飞桨AI Studio平台训练数据,并进行图像识别分析得牡丹花测试

🎼个人主页:【Y小夜】 😎作者简介:一位双非学校的大二学生,编程爱好者, 专注于基础和实战分享,欢迎私信咨询! 🎆入门专栏:🎇【MySQL&#xff0…

zookeeper客户端

启动单机版的zookeeper 配置Maven环境 (1) IDEA自带maven (2) 更新Maven库镜像地址: ① 拷贝D:\Program Files\JetBrains\IntelliJ IDEA 2018.3.5\plugins\maven\lib\maven3\conf\settings.xml [IntelliJ的安装目录]到 C:/用户/username/.m2 (如果.m2文件不存在&…

JDK17下,使用SHA1算法报Certificates do not conform to algorithm constraints错误

JDK17从17.0.5开始,默认不再允许使用SHA1算法,如果引用的jar包或代码里使用了SHA1算法,会报以下错误。 Caused by: javax.net.ssl.SSLHandshakeException: Certificates do not conform to algorithm constraintsat java.base/sun.security.…

SQL第16课——更新和删除数据

介绍如何利用update和delete语句进一步操作表数据。 16.1 更新数据 使用update语句。两种使用方式: 1. 更新表中的特定行; 2. 更新表中的所有行。 !!!(使用update时不要省略where子句,因为…

vue+ant 弹窗可以拖动

通过自定义指令实现拖拽功能 在main.js里加入drag自定义指令 我自己测试时发现modal不管如何设置宽度,居中等,他的初始的left都为0,如果不设置好,容易出现点击后刚开始移动弹窗会偏移一段距离。 Vue.directive(drag, {bind(el)…

一些硬件知识【20241014】

BUCK电路中SW节点过冲怎么解决,什么原因产生: BUCK电路中电感感值过大会怎样: 所以buck电路中电感感值大小不是越大越好: 在以太网通信中,接口和码元是两个重要概念,它们涉及物理层和数据传输方式的不同方面…

黑马程序员-redis项目实践笔记1

目录 一、 基于Session实现登录 发送验证码 验证用户输入验证码 校验登录状态 Redis代替Session登录 发送验证码修改 验证用户输入验证码 登录拦截器的优化 二、 商铺查询缓存 缓存更新策略 数据库和缓存不一致解决方案 缓存更新策略的最佳实践方案 实现商铺缓…

【1-1】STM32F407学习笔记之中断

一、异常与中断的概念 《Cortex M3与M4权威指南》章节4.5 P104-106 翻译:异常(Exceptions)在编程中是指那些导致程序流程改变的事件。当异常发生时,处理器会暂停当前执行的任务,转而执行一个称为异常处理程序(exception handler)的程序部分。处理完毕后,处理器会恢…

uniapp微信小程序调用百度OCR

uniapp编写微信小程序调用百度OCR 公司有一个识别行驶证需求,调用百度ocr识别 使用了image-tools这个插件,因为百度ocr接口用图片的base64 这里只是简单演示,accesstoken获取接口还是要放在服务器端,不然就暴露了自己的百度项目k…

Cherno游戏引擎笔记(61~72)

---------------一些维护和更改------------- 》》》》 Made Win-GenProjects.bat work from every directory 代码更改: echo off->pushd ..\->pushd %~dp0\..\call vendor\bin\premake\premake5.exe vs2019popdPAUSE 为什么要做这样的更改? …

【C++】STL--stack

1. stack的介绍 stack的文档介绍 后进先出&#xff08;LIFO&#xff09;&#xff1a;Stack容器遵循后进先出的原则&#xff0c;即最后进入栈的元素最先被移出栈。 2.stack的使用 常用的几个接口 代码演示如下 int main() {stack<int> st;st.push(1);st.push(2);st.…

一句话木马的多种变形方式

今天来和大家聊一聊&#xff0c;一句话木马的多种变形方式。 经常有客户的网站碰到被上传小马和大马&#xff0c;这里的“马”是木马的意思&#xff0c;可不是真实的马。 通常&#xff0c;攻击者利用文件上传漏洞&#xff0c;上传一个可执行并且能被解析的脚本文件&#xff0c;…

软件测试之基础的“管理岗”

1、是否需要选择管理岗&#xff1f; 建议&#xff1a;如果个人有机会成为管理岗&#xff0c;那就抓紧了。 原因很简单&#xff0c;我认为市场的行业发展是这个样子的&#xff0c;专业化的技术人员一定是市场缺失的人才&#xff0c;但是相比较而言&#xff0c;管理者会更加被公…

实验室信息系统(LIS)源码,.Net C#语言开发C/S架构,支持DB2,Oracle,MS SQLServer等主流数据库

实验室管理信息系统LIS从属于HIS系统&#xff0c;严格意义上讲&#xff0c;它是HIS系统的一个子系统。众所周知的是&#xff0c;LIS系统的主要功能是将检验仪器传出的检验数据经分析后&#xff0c;生成检验报告&#xff0c;通过网络存储在数据库中&#xff0c;使医生能够方便、…

Adobe Photoshop 2025(PS2025版) v26.0.0.26 中文版新功能特色

Photoshop 2025 是一款图像处理软件&#xff0c;它提供了许多强大的功能和工具&#xff0c;使用户能够对图像进行编辑、调整、修复、合成和设计。 Adobe Photoshop 2025新功能特色 图像编辑&#xff1a;支持各种图像编辑功能&#xff0c;如裁剪、调整色彩、修复照片、添加滤镜…

根据指定键对自定义 JSON 输出

要根据指定键对自定义 JSON 进行输出&#xff0c;通常的做法是&#xff1a; 解析 JSON 数据。按照用户给定的键提取或排序数据。重新构造并输出 JSON 数据。 这里有几个常见的场景&#xff1a; 提取特定键及其值。按特定键排序 JSON 数组。过滤掉不需要的键。 接下来&#…

华为FreeBuds 6i开降噪后底噪声大该如何解决?

华为FreeBuds 6i开了降噪会有沙沙的底噪声&#xff1f;最近看到一些小伙伴说这款耳机降噪效果比较好&#xff0c;但有时候在安静的环境下可以听到沙沙的底噪声&#xff0c;这是怎么回事&#xff1f; 我们先来聊一下降噪的原理&#xff1a;耳机内部的降噪系统通过麦克风采集外界…

智慧园区防护系统——提升园区安全性的关键工具

伴随着城市现代化推进&#xff0c;智慧园区已经成为当代城市基本建设不可或缺的一部分。智慧园区综合服务管理系统软件也被视为园区安全高效的关键工具之一。本文将从智慧园区安全性系统设计、作用、运用等多个方面详细的表述与分析。 一、设计 智慧园区防护系统设计方案应依据…