数据结构之——队列详解

目录

前言:

一、什么是队列

二、队列的实现

        2.1 队列结构

        2.2 队列初始化

        2.3 队列销毁

        2.4 入队列

        2.5 出队列

        2.6 获取队列头部元素 

        2.7  获取队列尾部元素 

        2.8 获取队列中有效元素个数 

        2.9 检测队列是否为空

三、 代码总览

        Queue.h

        test.c

四、例题


前言:

        我们前面已经学习了栈,今天我们来学习队列,队列和栈一样,相对来说比较简单,随后,会为大家准备OJ练习题,敬请期待!

一、什么是队列

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

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

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

        这里简单给大家解释一下:

        大家肯定都排过队(别说没有,我不信),大家在排好队先前前进时,是不是先站到队伍里的先走。队列的原理何其类似。因为,你可以猜一猜它为什么叫队列。可用下面图片帮助大家理解。 

         明白了,基础知识,那就一起来实现一下队列吧。

二、队列的实现

        2.1 队列结构

                和栈一样,我们队列的结构该如何设计呢?

                队列一共有两种结构,分为:顺序结构链式结构

  • 队列的顺序结构

入队,不需要移动任何元素,时间复杂度为O(1)

出队,所有元素需要往前移动,时间复杂度为O(N)

  • 队列的链式结构

首先我们定义两个指针,队头指针指向第一个节点,队尾指针指向尾节点

入队(尾插),时间复杂度为O(1)

出队(头删),时间复杂度为O(1)

 

                这里,我们将采取链式结构,如若对顺序结构感兴趣可结合之前的栈进行实现。

                我们要采用链式难道要用二级指针吗?一级已经够麻烦了,使用二级会更晕。所以,为了避免这种轻快,我们可采取结构体,如下代码:

typedef int QDataType;
// 链式结构:表示队列
typedef struct QListNode
{struct QListNode* next;QDataType data;
}QNode;// 队列的结构 
typedef struct Queue
{QNode* phead;QNode* ptatil;int size;
}Queue;

                这样即可避免二级指针。

        2.2 队列初始化

// 初始化队列 
void QueueInit(Queue* q)
{assert(q);q->phead = q->ptatil = NULL;q->size = 0;
}

                初始化只用将头和尾置为空即可。队列还未建立,所以,先不管。

        2.3 队列销毁

// 销毁队列 
void QueueDestroy(Queue* q)
{assert(q);QNode* cur = q->phead;while (cur){QNode* next = cur->next;free(cur);cur = next;}q->phead = q->ptatil = NULL;q->size = 0;
}

                销毁时我们要释放的是指针所指向开辟空间,而不是指针本身。所以,使用一个while循来释放。

        2.4 入队列

// 队尾入队列 
void QueuePush(Queue* q, QDataType data)
{assert(q);QNode* newnode = (QNode*)malloc(sizeof(QNode));if (newnode == NULL){perror("malloc fail");return;}newnode->next = NULL;newnode->data = data;if (q->phead == NULL)//这里使用头节点,尾节点判断均可{q->phead = q->ptatil = newnode;}else{q->ptatil->next = newnode;//记住这里是尾节点,不是头节点!!!q->ptatil = newnode;}q->size++;
}

                入队列时,我们要为其开辟一块空间也就是QNode,这就是队列的元素。要分为两种情况讨论,队列为空和队列不为空。

        2.5 出队列

// 队头出队列 
void QueuePop(Queue* q)
{assert(q);assert(q->size != 0);if (q->phead->next == NULL){q->phead = q->ptatil = NULL;}else{QNode* next = q->phead->next;free(q->phead);q->phead = next;}q->size--;
}

                要注意:分两种情况进行讨论。

        2.6 获取队列头部元素 

// 获取队列头部元素 
QDataType QueueFront(Queue* q)
{assert(q);assert(q->phead);return q->phead->data;
}

                这里,直接用头指针返回值即可。

        2.7  获取队列尾部元素 

// 获取队列队尾元素 
QDataType QueueBack(Queue* q)
{assert(q);assert(q->ptatil);return q->ptatil->data;
}

                和上面一样,运用指针获取值即可。

        2.8 获取队列中有效元素个数 

int QueueSize(Queue* q)
{assert(q);return q->size;
}

        2.9 检测队列是否为空

// 检测队列是否为空,如果为空返回非零结果,如果非空返回0 
bool QueueEmpty(Queue* q)
{assert(q);return q->size == 0;
}

三、 代码总览

        Queue.h

#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<stdbool.h>
#include<assert.h>typedef int QDataType;
// 链式结构:表示队列
typedef struct QListNode
{struct QListNode* next;QDataType data;
}QNode;// 队列的结构 
typedef struct Queue
{QNode* phead;QNode* ptatil;int size;
}Queue;// 初始化队列 
void QueueInit(Queue* q);
// 队尾入队列 
void QueuePush(Queue* q, QDataType data);
// 队头出队列 
void QueuePop(Queue* q);
// 获取队列头部元素 
QDataType QueueFront(Queue* q);
// 获取队列队尾元素 
QDataType QueueBack(Queue* q);
// 获取队列中有效元素个数 
int QueueSize(Queue* q);
// 检测队列是否为空,如果为空返回非零结果,如果非空返回0 
bool QueueEmpty(Queue* q);
// 销毁队列 
void QueueDestroy(Queue* q);

        Queue.c

#include"Queue.h"// 初始化队列 
void QueueInit(Queue* q)
{assert(q);q->phead = q->ptatil = NULL;q->size = 0;
}
// 队尾入队列 
void QueuePush(Queue* q, QDataType data)
{assert(q);QNode* newnode = (QNode*)malloc(sizeof(QNode));if (newnode == NULL){perror("malloc fail");return;}newnode->next = NULL;newnode->data = data;if (q->phead == NULL){q->phead = q->ptatil = newnode;}else{q->ptatil->next = newnode;//记住这里是尾节点,不是头节点!!!q->ptatil = newnode;}q->size++;
}
// 队头出队列 
void QueuePop(Queue* q)
{assert(q);assert(q->size != 0);if (q->phead->next == NULL){q->phead = q->ptatil = NULL;}else{QNode* next = q->phead->next;free(q->phead);q->phead = next;}q->size--;
}
// 获取队列头部元素 
QDataType QueueFront(Queue* q)
{assert(q);assert(q->phead);return q->phead->data;
}
// 获取队列队尾元素 
QDataType QueueBack(Queue* q)
{assert(q);assert(q->ptatil);return q->ptatil->data;
}
// 获取队列中有效元素个数 
int QueueSize(Queue* q)
{assert(q);return q->size;
}
// 检测队列是否为空,如果为空返回非零结果,如果非空返回0 
bool QueueEmpty(Queue* q)
{assert(q);return q->size == 0;
}
// 销毁队列 
void QueueDestroy(Queue* q)
{assert(q);QNode* cur = q->phead;while (cur){QNode* next = cur->next;free(cur);cur = next;}q->phead = q->ptatil = NULL;q->size = 0;
}

        test.c

#include"Queue.h"int main()
{Queue q;QueueInit(&q);QueuePush(&q, 1);QueuePush(&q, 2);QueuePush(&q, 3);QueuePush(&q, 4);while (!QueueEmpty(&q)){printf("%d ", QueueFront(&q));QueuePop(& q);}printf("\n");QueueDestroy(&q);return 0;
}

四、例题

        来一道例题来练一练吧!

        现有队列Q与栈S,初始时Q中的元素依次是 1,2,3,4,5,6(1在队头),S 为空。若仅允许下列3种操作:①出队并输出出队元素;②出队并将出队元素入栈;③出栈并输出出栈元素,则不能得到的输出序列是()。

                       A. 1,2,5,6,4,3                                        B.  2,3,4,5,6,1                                        C. 3,4,5,6,1,2                                         D.  6.5.4.3.2.1

        

        可得:答案为:C。

        如果还有什么问题,可以私信也可在评论区留言!

完! 

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

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

相关文章

树莓派、ubuntu低版本python3安装库

如果遇到树莓派中自带低版本python3&#xff0c;又不想额外去安装python3时&#xff0c;可能会遇到版本过低&#xff0c;无法安装库的情况&#xff0c;以下用我实际情况举例解决方案。 本次遇到的问题是树莓派低版本中&#xff0c;python3为3.7.3&#xff0c;需要安装numpy&am…

Python专题:八、列表(1)

Python的内置数据类型 数据类型&#xff1a;列表 list类型 可以是字符串&#xff0c;浮点数&#xff0c;整数&#xff0c;列表 列表特性 ①集合性的数据类型 ②列表是有序的 ③列表是可更新的 访问列表元素的方式也是[索引]&#xff0c;也是从0开始的&#xff0c;不能超过…

EasyNmon服务器性能监控工具环境搭建

一、安装jdk环境 1、看我这篇博客 https://blog.csdn.net/weixin_54542209/article/details/138704468 二、下载最新easyNmon包 1、下载地址 https://github.com/mzky/easyNmon/releases wget https://github.com/mzky/easyNmon/releases/download/v1.9/easyNmon_AMD64.tar.…

Ansible-inventory和playbook

文章目录 一、inventory 主机清单1、列表表示2、inventory 中的变量3、变量3.1 主机变量3.2 组变量3.3 组嵌套 二、playbook剧本1、playbook的组成2、编写剧本2.1 剧本制作2.2 准备nginx.conf2.3 运行剧本2.4 查看webservers服务器2.5 补充参数 3、剧本定义、引用变量3.1 剧本制…

kdb 调试内核-延迟驱动加载

说明: 系统在启动过程中&#xff0c;一些要调试的驱动在 "进入kdb 之前" 就已经加载了&#xff0c; 那么&#xff0c;我们就需要延迟 "加载驱动" #define XX_module_platform_driver(__platform_driver) \XX_module_driver(__platform_driver, platform_d…

【Java】高效解决 非降序数组合并 两种方法

欢迎浏览高耳机的博客 希望我们彼此都有更好的收获 感谢三连支持&#xff01; oj&#xff1a;https://leetcode.cn/problems/merge-sorted-array/submissions/ 合并两个有序数组是个经典问题&#xff0c;它不仅在算法学习中频繁出现&#xff0c;也在实际开发中经常遇到。合并数…

计算机毕业设计】springbootBBS论坛系统

本系统为用户而设计制作 BBS论坛系统&#xff0c;旨在实现BBS论坛智能化、现代化管理。本BBS论坛自动化系统的开发和研制的最终目的是将BBS论坛的运作模式从手工记录数据转变为网络信息查询管理&#xff0c;从而为现代管理人员的使用提供更多的便利和条件。使BBS论坛系统数字化…

ADS基础介绍篇1

一. ADS简介 常用的射频仿真软件有ADS和AWR&#xff0c;ADS(Advanced Design system)最传统&#xff0c;是Agilent公司于2008年推出的电磁场仿真器&#xff0c;可提供原理图设计和layout版图设计。仿真功能十分强大&#xff0c;可提供从无源到有源&#xff0c;从直流到交流&am…

Docker搭建ctfd平台

安装docker和docker-compose &#xff08;1&#xff09;安装docker&#xff1a; curl -fsSL https://get.docker.com | bash -s docker --mirror Aliyun&#xff08;2&#xff09;安装 Docker Compose&#xff1a; yum install docker-compose安装失败参考下面文章 https:/…

stm32——OLED篇

技术笔记&#xff01; 一、OLED显示屏介绍&#xff08;了解&#xff09; 1. OLED显示屏简介 二、OLED驱动原理&#xff08;熟悉&#xff09; 1. 驱动OLED驱动芯片的步骤 2. SSD1306工作时序 三、OLED驱动芯片简介&#xff08;掌握&#xff09; 1. 常用SSD1306指令 2. …

初识sql注入--手工注入

目录 可能使用的sql函数 入侵网站方式 1、文件上传漏洞 2、rce 3、sql注入 SQL注入 什么是sql注入 进行SQL注入 实验环境 开始实验&#xff08;使用information_shema数据库&#xff09; 1、进入靶场 2、报列数 下面来解释一下为什么要照上面SQL语句写 url编码 单…

模拟无线音频传输实验

zkhengyang进数字音频系统研究开发交流答疑群(课题组) 一个单管调频无线话筒模块一台调频收音机&#xff0c;全部自己动手制作调试&#xff0c;无线话筒模块可以接话筒mic&#xff0c;人讲话&#xff0c;收音机接受到语音信号&#xff0c; 或者直接输入模拟音频音乐信号&#…

使用SPI驱动串行LCD的驱动实现(STM32F4)

目录 概述 1. 硬件介绍 1.1 ST7796-LCD 1.2 MCU IO与LCD PIN对应关系 2 功能实现 2.1 使用STM32Cube配置Project 2.2 STM32Cube生成工程 3 代码实现 3.1 SPI接口实现 3.2 LCD驱动程序实现 3.3 测试程序实现 4 测试 源代码下载地址&#xff1a; https://gitee.com/mf…

Vue中进行粘贴板粘贴数据(图片、文字等)

在页面中如果需要进行粘贴数据&#xff0c;那么就要读取系统粘贴板clipboard&#xff0c;通过此Api来进行粘贴板数据的操作。 目录: 一.封装相关函数1.示例代码&#xff1a;2.代码解释&#xff1a; 二.页面中进行粘贴1.代码示例&#xff1a;2.代码解释&#xff1a; 三.运行结果…

系统分析师论文——论软件需求分析方法和工具的选用

现已临近2024年软考&#xff0c;周围一些报名参加系统分析师考试的“小伙伴”还未准备论文&#xff0c;我分享早年写的一些内容&#xff08;包括参加继续教育准备的论文&#xff09;&#xff0c;仅供大家结合最新考纲要求酌情参考&#xff0c;希望予人玫瑰&#xff0c;手有余香…

软件测试之 性能测试 性能测试基础指标 Loadrunner、Jmeter等工具

你好,我是Qiuner. 为记录自己编程学习过程和帮助别人少走弯路而写博客 这是我的 github gitee 如果本篇文章帮到了你 不妨点个赞吧~ 我会很高兴的 &#x1f604; (^ ~ ^) 想看更多 那就点个关注吧 我会尽力带来有趣的内容 本文档基于 https://www.bilibili.com/video/BV1wC4y1Y…

原创未发表!24年新算法SBOA优化TVFEMD实现分解+四种熵值+频谱图+参数变化图+相关系数图!

声明&#xff1a;文章是从本人公众号中复制而来&#xff0c;因此&#xff0c;想最新最快了解各类智能优化算法及其改进的朋友&#xff0c;可关注我的公众号&#xff1a;强盛机器学习&#xff0c;不定期会有很多免费代码分享~ 目录 数据介绍 优化流程 创新点 使用TVFEMD的创…

【全面介绍下Spring】

&#x1f308;个人主页: 程序员不想敲代码啊 &#x1f3c6;CSDN优质创作者&#xff0c;CSDN实力新星&#xff0c;CSDN博客专家 &#x1f44d;点赞⭐评论⭐收藏 &#x1f91d;希望本文对您有所裨益&#xff0c;如有不足之处&#xff0c;欢迎在评论区提出指正&#xff0c;让我们共…

Excel 分组汇总后删除明细

有 Excel 数据如下所示&#xff1a; IDCriteria1Criteria2Criteria3Criteria4101210271239312381236123171826182918239182120182147 需要按 ID 分组汇总其余列&#xff0c;结果如下&#xff1a; IDCriteria1Criteria2Criteria3Criteria410121027123932561826939267 解法及简…

3D Web轻量化引擎HOOPS Communicator如何处理DWG文件中的图纸?

在当今工程设计和建筑领域&#xff0c;数字化技术已经成为不可或缺的一部分。HOOPS Communicator作为一种强大的三维数据可视化工具&#xff0c;被广泛应用于处理各种CAD文件&#xff0c;其中包括AutoCAD的DWG格式。在这篇文章中&#xff0c;我们将探讨HOOPS Communicator是如何…