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

茂名网站开发公司推荐/百度知道在线问答

茂名网站开发公司推荐,百度知道在线问答,永远网站建设,域名解析手机网站建设队列 前言一、队列的结构1.实现思路2.代码结构 二、队列的实现1.初始化和销毁2.判空和获取队列大小3.入队列和出队列4.获取队头和队尾元素5.测试 总结每文推荐 前言 队列是一种特殊的线性表,特殊之处在于它只允许在表的前端(front)进行删除操…

队列

  • 前言
  • 一、队列的结构
    • 1.实现思路
    • 2.代码结构
  • 二、队列的实现
    • 1.初始化和销毁
    • 2.判空和获取队列大小
    • 3.入队列和出队列
    • 4.获取队头和队尾元素
    • 5.测试
  • 总结
  • 每文推荐


前言

队列是一种特殊的线性表,特殊之处在于它只允许在表的前端(front)进行删除操作,而在表的后端(rear)进行插入操作,和栈一样,队列是一种操作受限制的线性表。进行插入操作的端称为队尾,进行删除操作的端称为队头。队列中没有元素时,称为空队列。


一、队列的结构

1.实现思路

队列的结构特点最核心的就是先进先出四个字,和栈类似,我们在实现队列这个数据结构时首先需要考虑的就是使用顺序表来实现还是使用链表来实现,而考虑的主要因素就是该结构是否可以满足或者说是否可以更方便地实现队列的核心特点先进先出。如果没有看过顺序表和链表的实现的,可以先看一下我之前的文章。
顺序表的实现
单向链表的实现
双向链表的实现
这里我们简单地分析一下,如果使用顺序表,那么实现队列就会变得比较麻烦,因为顺序表的尾插尾删效率确实很高,但它的头插头删效率就很一般了,因为顺序表的头插头删都需要我们对顺序表里面的元素进行前移或后移,这是一个时间复杂度为O(N) 的操作,效率是非常一般的,而我们如果使用顺序表来实现队列的话,我们的入队列即是尾插还是很不错,但是出队列即是头删的效率就非常一般了,所以我们在实现队列的时候不推荐使用顺序表。
而如果使用链表,链表的优势就体现出来了,因为链表对于头插头删或者尾插尾删来说效率是非常高的,只需要申请新结点后进行链接操作即可,所以我们推荐使用链表来实现队列。我们在队列的结构中需要用两个变量来分别记录队头(头结点)和队尾(尾结点)的位置以及一个变量来记录当前队列的大小,当然,如果使用双向循环链表的话甚至不用单独记录队头和队尾,不过相应地如果使用双向链表的话进行链接操作时会变得更复杂。而队列的先进先出也就是链表的尾插头删,效率非常高。


2.代码结构

// 链式结构:表示队列 
typedef int QDataType;typedef struct QListNode
{struct QListNode* _next;QDataType _data;
}QNode;// 队列的结构 
typedef struct Queue
{QNode* _front;QNode* _rear;int size;
}Queue;

在本篇文章中,我们就使用单链表来实现一个队列。在C语言中,我们先用一个结构体定义一个链表的结点,在这里即是这个struct QListNode的结构体并将其typedef重命名为QNode,之后我们再用一个结构体来定义一个队列,在这里即是这个struct Queue的结构体并将其typedef重命名为Queue,便于后面书写的简便性。在这个队列的结构中,我们需要定义两个QNode类型的指针来分别记录队列的队头位置和队尾位置,然后再定义一个整形类型的变量来记录当前队列的大小。同时为了方便我们以后更改队列的存储数据类型,我们可以在这里将类型进行typedef,即typedef int QDataType,将int重命名为QDataType,这样以后我们只用在这里更改类型即可更改队列的存储的数据类型


二、队列的实现

1.初始化和销毁

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

初始化队列的函数,我们传入一个Queue类型的指针,然后将其内部完成初始化操作。即将队头和队尾位置赋值为空,然后将队列大小赋值为0

// 销毁队列 
void QueueDestroy(Queue* q)
{assert(q);QNode* cur = q->_front;while (cur){QNode* del = cur;cur = cur->_next;free(del);del = NULL;}q->_front = NULL;q->_rear = NULL;q->size = 0;
}

销毁队列的函数,类似地,我们传入一个Queue类型的指针,然后遍历链表,依次使用free函数释放每个结点,这里和单向链表的销毁一模一样,最后我们再将队列的队头和队尾位置赋值为空并将队列大小赋值为0完成队列的销毁操作。


2.判空和获取队列大小

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

判断队列是否为空的函数,这个函数非常简单,一句return q->_front == NULL就可以搞定,如果当前队列的队头位置为空,那么该队列就为空队列,这句语句就为真,为真就返回非0结果,反之不为空这句语句即为假,为假就返回0。当然这里判空的语句不一定要用队头位置是否为空来判断,用队尾位置是否为空或者队列的大小是否为0来判断也都是没问题的。

// 获取队列中有效元素个数 
int QueueSize(Queue* q)
{assert(q);return q->size;
}

获取队列中有效元素个数的函数,这个函数非常简单,我们直接返回记录队列大小的size的值即可。


3.入队列和出队列

// 队尾入队列 
void QueuePush(Queue* q, QDataType data)
{assert(q);QNode* pnew = (QNode*)malloc(sizeof(QNode));if (pnew == NULL){perror("malloc");exit(-1);}pnew->_data = data;pnew->_next = NULL;if (q->size == 0){q->_front = pnew;q->_rear = pnew;}else{q->_rear->_next = pnew;q->_rear = pnew;}q->size++;
}

进行入队列操作的函数,这个函数就和链表的尾插函数完全类似。首先我们需要进行申请新结点的操作,我们利用malloc函数在堆上申请一个新结点,然后将入队列的值data赋值给新结点中的_data并将_next指针初始化为空完成申请新结点的操作。之后我们就进行链接操作,这里就和单链表的尾插完全类似。我们首先进行分类讨论看当前链表是否为空,如果当前链表为空的话我们就直接让队头和队尾位置指向新开辟的结点pnew;如果不为空的话,我们就让我们的队尾结点_rear的_next指针指向新结点并将队尾结点_rear更新为新结点。最后我们将队列的大小size加1即可完成入队列的操作。

// 队头出队列 
void QueuePop(Queue* q)
{assert(q);if (QueueEmpty(q)){printf("当前队列为空\n");return;}if (q->_front == q->_rear){free(q->_front);q->_front = NULL;q->_rear = NULL;}else{QNode* del = q->_front;q->_front = del->_next;free(del);del = NULL;}q->size--;
}

进行出队列操作的函数,同理,这个函数和链表的头删函数类似,我们先进行判空操作,保证出队列时队列不能为空,如果不为空我们才进行出队列操作。然后出队列操作我们也进行一个分类讨论,讨论一下当前队列的大小是否为1,即队头q->_front是否等于队尾q->_rear,因为这涉及到我们是否需要更改队尾的位置。如果大小为1,我们就用free函数释放这一个结点,然后将队头和队尾都赋值为空;如果大小不为1,我们就先用一个变量del记录当前的队头位置,然后将队头位置_front指向队头的_next位置并释放del记录的之前的队头位置。最后我们将队列的大小size减1即可完成出队列操作。


4.获取队头和队尾元素

// 获取队列头部元素 
QDataType QueueFront(Queue* q)
{assert(q);if (q->size == 0){printf("无元素\n");return 0;}return q->_front->_data;
}

获取队列头部元素的函数,我们先进行一个判空操作,如果队列为空则提前返回,如果不为空就返回队头位置_front的数据。

// 获取队列队尾元素 
QDataType QueueBack(Queue* q)
{assert(q);if (q->size == 0){printf("无元素\n");return 0;}return q->_rear->_data;
}

获取队列队尾元素的函数,同理,我们也先进行一个判空操作,如果队列为空则提前返回,如果不为空就返回队尾位置_rear的数据。


5.测试

进行测试的main函数,用来测试我们写的队列的逻辑是否存在问题。

int main()
{Queue q;QueueInit(&q);QueuePush(&q, 1);QueuePush(&q, 2);QueuePush(&q, 3);QueuePush(&q, 4);printf("%d\n", QueueBack(&q));printf("%d ", QueueFront(&q));QueuePop(&q);printf("%d ", QueueFront(&q));QueuePop(&q);printf("%d ", QueueFront(&q));QueuePop(&q);printf("%d ", QueueFront(&q));QueuePop(&q);printf("\n");QueuePop(&q);printf("\n");printf("%d ", QueueSize(&q));printf("\n");printf("%d\n", QueueFront(&q));printf("%d\n", QueueBack(&q));printf("%d\n", QueueEmpty(&q));QueueDestroy(&q);return 0;
}

总结

本章到这里数据结构队列的实现就已经全部完成了,队列的实现难度其实不是特别大,特别是如果亲自实现过前面的顺序表和链表的话,难度应该会更小。虽然队列看起来简单,但我们不能忽视它的重要性,它的作用包括但不限于任务调度,事件处理,缓存机制,并发控制,算法实现等方面。所以虽然结构基础,但它的意义却是非常之大,值得我们亲自去实现它。

如需源码,可在我的gitee上找到,下面是链接。
队列源码
如对您有所帮助,可以来个三连,感谢大家的支持。


每文推荐

张靓颖–念念不忘
A-Lin–天若有情
梁静茹–慢冷

学技术学累了时可以听歌放松一下。

相关文章:

C语言实现队列

队列 前言一、队列的结构1.实现思路2.代码结构 二、队列的实现1.初始化和销毁2.判空和获取队列大小3.入队列和出队列4.获取队头和队尾元素5.测试 总结每文推荐 前言 队列是一种特殊的线性表,特殊之处在于它只允许在表的前端(front)进行删除操…...

Python使用scrapy创建项目爬虫步骤

一、安装导入 使用包管理器下载 pip install scrapy 二、创建Scrapy项目 首先需要进入你创建项目的目录下,打开cmd窗口或powershell窗口: scrapy startproject 项目名称(英文) 三、了解项目结构 scrapy.cfg # 项目的配置文件…...

长沙某公司.Net高级开发面试题

1.dot net core跟dot net比较有哪些更好的地方? 第一是跨平台,它可以运行在三大操作系统上面,windows, Linux和MAC。 第二是对架构本身安装没有依赖,因为所有的依赖都跟程序本身在一起。 第三是dot net core处理请求…...

物联网系统中声音拾取音频方案_咪头

01 物联网系统中为什么要使用咪头 物联网系统中使用咪头(麦克风或传声器)的原因主要可以归结为以下几个方面: 声音信号的拾取与转换 基本功能:咪头是一种将声音转换为电信号的装置。在物联网系统中,咪头负责捕捉周围…...

【题解】Codeforces Round 975 (Div. 2) A~E

A. Max Plus Size 分别假设答案为取第偶数位的最大值和取第奇数位的最大值两种情况, 取更优解. 取偶数位的最大值时, 把所有其他都偶数位都取上. 奇数同理. code: int solve(int _) {int n;cin >> n;vector<int>a(n 1);int Maxj 0, Maxo 0;for (int i 1; i …...

如何搞定视频裁剪?新手小白零基础剪辑,分享5个实用工具!

现在是一个短视频盛行的时代&#xff0c;几乎每个人都掌握了视频剪辑技能。 不管是因为工作也好&#xff0c;生活也罢&#xff0c;只要有视频&#xff0c;那么就一定会用到视频剪辑软件。视频裁剪已经难不倒普通人了&#xff0c;借助专业的视频裁剪工具&#xff0c;任何人都可…...

HttpClientHandler 详解及使用

在现代网络编程中&#xff0c;HttpClientHandler 是一个至关重要的组件&#xff0c;它提供了对 HTTP 请求的底层配置和控制。本文将详细介绍 HttpClientHandler 的核心概念、配置选项以及如何在实际应用中使用它。 1. 什么是 HttpClientHandler&#xff1f; HttpClientHandle…...

基于两分支卷积和 Transformer 的轻量级多尺度特征融合超分辨率网络 !

当前的单图像超分辨率&#xff08;SISR&#xff09;算法有两种主要的深度学习模型&#xff0c;一种是基于卷积神经网络&#xff08;CNN&#xff09;的模型&#xff0c;另一种是基于Transformer的模型。前者利用不同卷积核大小的卷积层堆叠来设计模型&#xff0c;使得模型能够更…...

Font Awesome 手势图标

Font Awesome 手势图标 Font Awesome 是一个广泛使用的图标库,它为网页设计师和开发者提供了一系列高质量的图标。这些图标涵盖了从基本的网页元素到复杂的符号和手势,可以轻松地集成到各种网页和应用中。在本文中,我们将重点介绍 Font Awesome 中的手势图标,探讨它们的应…...

基于Hive和Hadoop的哔哩哔哩网站分析系统

本项目是一个基于大数据技术的哔哩哔哩平台分析系统&#xff0c;旨在为用户提供全面的哔哩哔哩视频数据和深入的用户行为分析。系统采用 Hadoop 平台进行大规模数据存储和处理&#xff0c;利用 MapReduce 进行数据分析和处理&#xff0c;通过 Sqoop 实现数据的导入导出&#xf…...

Augular 学习步骤建议

Angular 是一个由 Google 维护的开源 Web 应用框架&#xff0c;用于开发单页面客户端应用程序。以下是学习 Angular 的建议步骤&#xff1a; 1. 了解基础&#xff1a; 熟悉 HTML、CSS 和 JavaScript 的基础知识。 了解 TypeScript&#xff0c;因为 Angular 应用程序主要使用…...

突破自闭症治疗进展报道:改变孩子和家庭的未来

在这个充满挑战与希望的时代&#xff0c;自闭症这一复杂的神经发育障碍&#xff0c;长久以来一直是无数家庭心中的痛。然而&#xff0c;在星贝育园这片充满爱与科学的土地上&#xff0c;一场关于自闭症治疗的深刻变革正在悄然发生&#xff0c;它不仅为孩子们点亮了未来的希望之…...

我想注册一批账号做矩阵,需要每次注册都切换一个ip吗

在注册一批账号以建立矩阵时&#xff0c;切换IP地址是一个重要的考虑因素&#xff0c;尤其是为了避免被平台识别为同一用户或多重账户&#xff0c;从而减少账号被封的风险。以下是一些建议&#xff0c;帮助你有效管理IP地址和账号注册过程&#xff1a; 1. 切换IP地址的必要性 …...

linux系统的常用命令

微服务Linux解析部署使用全流程 Linux安装vim超详细教程 Linux安装JDK及配置环境变量超详细教程 Linux安装tomcat及配置环境变量超详细教程 目录 1、ls&#xff1a;列出目录内容。 2、cd&#xff1a;改变当前目录。 3、pwd&#xff1a;打印当前工作目录的路径 4、mkdir…...

无锡卓瓷X哲讯智能科技,SAP项目正式启动!

在数字化浪潮的推动下&#xff0c;高精密陶瓷行业的领军企业—无锡卓瓷科技有限公司&#xff0c;携手哲讯智能科技有限公司近期启动SAP&BI项目&#xff0c;以打造行业领先的数字化管理平台。这一战略举措标志着无锡卓瓷在数字化转型的道路上迈出了坚实的一步。 无锡卓瓷—…...

Python从入门到精通-基础篇

1.Python的起源 1989年&#xff0c;为了打发圣诞节假期&#xff0c;Gudio van Rossum&#xff08;吉多范罗苏姆&#xff08;龟叔&#xff09;&#xff09;决心开发一个新的解释程序&#xff08;Python雏形&#xff09; 1991年&#xff0c;第一个Python解释器诞生 Python这个…...

系统架构设计师-知识产权与标准化

目录 一、保护范围与对象 二、保护期限 三、知识产权人确定 四、侵权判断 五、标准化 一、保护范围与对象 知识产权是权利人依法就下列课题享有的专有权利&#xff1a; &#xff08;一&#xff09;作品&#xff08;著作&#xff09; &#xff08;二&#xff09;发明、实用…...

Python安装流程(Windows + MAC)

目录 Windows 版 1.下载Python 2.开始安装 3.配置环境变量 4.测试python是否成功安装 MAC版 1.下载Python 2.开始安装 Windows 版 1.下载Python 进入Python官网下载&#xff1a;&#xff08;Python更新频繁&#xff0c;下载最新版即可&#xff0c;安装流程一致&#x…...

在 Qt 项目中使用 spdlog 的全攻略

目录 1. 准备工作&#xff1a;安装 spdlog 方法一&#xff1a;使用 CMake 的 FetchContent&#xff08;推荐&#xff09; 方法二&#xff1a;手动下载并添加到项目中 2. 在 Qt 项目中集成 spdlog a. 初始化 spdlog b. 在 Qt 的各个部分使用 spdlog 3. 基本使用示例 4. …...

vue的el-button防止重复点击

这样效果仅生效在按钮上...

消息中间件 Kafka 快速入门与实战

1、概述 最近感觉上班实在是太无聊&#xff0c;打算给大家分享一下Kafka的使用&#xff0c;本篇文章首先给大家分享三种方式搭建Kafka环境&#xff0c;接着给大家介绍kafka核心的基础概念以及Java API的使用&#xff0c;最后分享一个SpringBoot的集成案例&#xff0c;希望对大…...

【Unity服务】如何使用Unity Version Control

Unity上的线上服务有很多&#xff0c;我们接触到的第一个一般就是Version Control&#xff0c;用于对项目资源的版本管理。 本文介绍如何为项目添加Version Control&#xff0c;并如何使用&#xff0c;以及如何将项目与Version Control断开链接。 其实如果仅仅是对项目资源进…...

C++ --- 静态多态和动态多态

静态多态和动态多态 静态多态动态多态总结 静态多态和动态多态是面向对象编程中多态性的两种主要形式&#xff0c;它们在实现方式、绑定时机以及应用场景上存在一些显著的区别。 静态多态 静态多态&#xff0c;也被称为编译时多态&#xff0c;是指在编译阶段就已经确定了对象调…...

华为vxlan

VXLAN是什么&#xff1f;VXLAN与VLAN之间有何不同&#xff1f; - 华为...

队列及笔试题

队列 先进先出 使用单链表进行队尾插入 队头删除 其中带头结点直接尾插&#xff0c;不带头结点第一次操作要判断一下 但是带头结点需要malloc和free 函数传需要修改的参数方法 1、二级指针 2、带哨兵位的头结点 3、返回值 4、如果有多个值&#xff0c;用结构体封装起来…...

JAVA TCP协议初体验

文章目录 一、需求概述二、设计选择三、代码结构四、代码放送五、本地调试1. 服务端日志2. 客户端日志3. 断线重连日志 六、服务器部署运行1. 源码下载2. 打包镜像3. 运行容器 一、需求概述 最近开发某数据采集系统&#xff0c;系统整体的数据流程图如下&#xff1a; #mermaid…...

sqlserver迁移数据库文件存储位置

业务背景&#xff1a;由于C盘爆满&#xff0c;需要将数据库文件迁移到别处比如D盘 下面以某一个数据库转移为示例&#xff1a;&#xff08;可以用SSMS工具&#xff0c;新建查询配合使用&#xff09; 1.查询数据库文件存储路径 sql语句&#xff1a; -- 查询路径 USE QiangTes…...

配置项取值给静态类用

在 Java 中&#xff0c;如果要从 application.yml 文件中取值并供静态类使用&#xff0c;可以考虑以下几种方法&#xff1a; 一、使用 Spring 的 Environment 类 1. 首先确保你的项目是一个 Spring 项目&#xff0c;并且配置文件被正确加载。 2. 在需要获取配置值的类中注入…...

【vs code(cursor) ssh连不上服务器】但是 Terminal 可以连上,问题解决 ✅

问题描述 通过 vs code 的 ssh 原本方式无法连接&#xff0c;但是通过 Terminal 使用相同的 bash 却可以连接上服务器。 ssh -p 4xx username14.xxx.3 问题解决方法 在 vs code 的 config 里&#xff0c;将该服务器&#xff08;14.xxx.3&#xff09;的相关配置全部清空或注释…...

Go基础学习06-Golang标准库container/list(双向链表)深入讲解;延迟初始化技术;Element;List;Ring

基础介绍 单向链表中的每个节点包含数据和指向下一个节点的指针。其特点是每个节点只知道下一个节点的位置&#xff0c;使得数据只能单向遍历。 示意图如下&#xff1a; 双向链表中的每个节点都包含指向前一个节点和后一个节点的指针。这使得在双向链表中可以从前向后或从后…...