数据结构之队列(源代码➕图解➕习题)
前言
在学过栈之后,会了解到栈的底层是根据顺序表或者链表来构建的,那么我们今天要学习的队列是否也是基于顺序表和链表呢?那我们直接进入正题吧!
1. 队列的概念(图解)
还是跟上节一样,依旧用图解的方式让大家更好的理解概念。
1.1 队列的组成:
队列:队列指的是图中黑色边框及其内部的空间
队头:出元素的一边叫队头
队尾:入元素的一边叫队尾
队内元素:蓝色正方形
1.2 队列的进出规则:先进先出
队列的进出规则跟栈不一样,栈是先进后出,而队列是先进先出。
队列只能从队头出,队尾入,所以这就造就了队列的先进先出,先从队尾入的元素,先从队头出。
2. 队列的架构
2.1 队列为顺序表构成(舍弃方案)
队列的入队列相当于尾插(头插),队列的出队列相当于头删(尾删)
我们知道顺序表的尾插尾删是非常快的,很方便。但是头插头删却需要挪动数据,覆盖,十分麻烦。无论是我们入队列和出队列,我们都必然会涉及到头的挪动。这样大大增加了我们时间复杂度,所以我们队列不推荐使用顺序表构建。
2.2 队列为链表构成(文末源代码)
我们是选择什么样的链表呢?单向链表还是双向链表,是否带头,是否成环?不要着急,我们先来看单链表是否简单可行。
2.2.1 队列为单链表构成
如图,我们选择链表的头部作为了队头,链表的尾部作为了队尾,那么出队列就是头删,入队列就是尾插。
1. 入队列:
入队列就是链表的尾插,先找到链表的尾,再跟新节点连接就可以了。但是当我们队列中没有元素的时候,就需要改变一下链表头指针指向的位置,让他指向第一个节点,这里我们是改变指针,需要用到二级指针,但是我们今天不用二级指针,使用一个新的方法来解决。
2. 出队列
出队列相当于链表的头删,看图就可以了。
我们会发现其实单链表已经可以几乎很好的解决队列这个数据结构了,那我们就没有必要去创造什么带头啊,循环啊,双向啊这些结构。所以接下来就让源代码登场吧!
3. 队列由单链表构成(源代码)
3.1 队列的定义
这里跟以往不同的点是 这里我们重新定义了一个结构体,包含了队列的头节点和尾结点,我们这么定义的目的是可以更改头节点和尾节点。
//如果你要更改队列元素的数据类型,在这里更改一次就OK了,int变成其他数据类型
typedef int QDataType;
//这里我们正常定义队列的节点,因为是链表构成的,和链表节点一样
typedef struct QueueNode
{struct QueueNode* next;QDataType data;
}QNode;
//这里我们重新定义了一个结构体,包含了队列的头节点和尾结点,我们这么定义的目的是可以更改头节点和尾节点
typedef struct Queue
{QNode* head;QNode* tail;int size;
}Que;
3.2 队列的初始化
//初始化
void QueueInit(Que* pq)
{assert(pq);pq->head = pq->tail = NULL;pq->size = 0;
}
3.3 队列的销毁
void QueueDestroy(Que* pq)
{assert(pq);QNode* cur = pq->head;while (cur){QNode* next = cur->next;free(cur);cur = next;}pq->head = pq->tail = NULL;pq->size = 0;
}
3.4 入队列
//入队列
void QueuePush(Que* pq, QDataType x)
{assert(pq);QNode* newnode = (QNode*)malloc(sizeof(QNode));if (newnode == NULL){perror("malloc fail");exit(-1);}newnode->data = x;newnode->next = NULL;if (pq->tail == NULL){pq->head = pq->tail = newnode;}else{pq->tail->next = newnode;pq->tail = newnode;}pq->size++;
}
3.5 出队列
//出队列
void QueuePop(Que* pq)
{assert(pq);assert(!QueueEmpty(pq));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;}pq->size--;
}
3.6 取队头元素
//取队头元素
QDataType QueueFront(Que* pq)
{assert(pq);assert(!QueueEmpty(pq));return pq->head->data;
}
3.7 取队尾元素
//取队尾元素
QDataType QueueBack(Que* pq)
{assert(pq);assert(!QueueEmpty(pq));return pq->tail->data;
}
3.8 判断队列是否为空
bool QueueEmpty(Que* pq)
{assert(pq);return pq->head == NULL;
}
3.9 求队列长度
//队列的长度
int QueueSize(Que* pq)
{assert(pq);return pq->size;
}
4. 习题
4.1 下列关于队列的叙述错误的是( )
A.队列可以使用链表实现
B.队列是一种“先入先出”的数据结构
C.数据出队列时一定只影响尾指针
D.数据入队列时一定从尾部插入
答案:C
解析:出队操作,一定会影响头指针,如果出队之后,队列为空,会影响尾指针。
4.2 用无头单链表存储队列,其头指针指向队头结点,尾指针指向队尾结点,则在进行出队操作时()
A.仅修改队头指针
B.队头、队尾指针都要修改
C.队头、队尾指针都可能要修改
D.仅修改队尾指针
答案:C
解析:出队操作,一定会修改头指针,如果出队之后,队列为空,需要修改尾指针。
4.3 以下不是队列的基本运算的是( )
A.从队尾插入一个新元素
B.从队列中删除队尾元素
C.判断一个队列是否为空
D.读取队头元素的值
答案:B
解析:队列只能从队头删除元素。
4.4 下面关于栈和队列的说法中错误的是( )(多选)
A.队列和栈通常都使用链表实现
B.队列和栈都只能从两端插入、删除数据
C.队列和栈都不支持随机访问和随机插入
D.队列是“先入先出”,栈是“先入后出”
答案:AB
解析:
A错误:栈是尾部插入和删除,一般使用顺序表实现,队列是头部删除尾部插入,一般使用链表实现
B错误:栈是后进先出,尾部插入和删除,并不是两端;队列是先进先出,尾部插入头部删除。
4.5 下列关于顺序结构实现循环队列的说法,正确的是( )
A.循环队列的长度通常都不固定
B.直接用队头和队尾在同一个位置可以判断循环队列是否为满
C.通过设置计数的方式可以判断队列空或者满
D.循环队列是一种非线性数据结构
答案:C
解析:顺序结构实现循环队列是通过数组下标的循环来实现的
A错误:循环队列的长度都是固定的
B错误:队头和队尾在同一个位置时 队列可能是空的,也可能是满的,因此无法判断
C正确:设置计数即添加一个字段来记录队列中有效元素的个数,如果队列中有效元素个数等于空间总大小时队列满,如果队列中有效元素个数为0时队列空
D错误:循环队列也是队列的一种,是一种特殊的线性数据结构
好啦,我们关于队列的实现已经结束了,谢谢大家!
相关文章:

数据结构之队列(源代码➕图解➕习题)
前言 在学过栈之后,会了解到栈的底层是根据顺序表或者链表来构建的,那么我们今天要学习的队列是否也是基于顺序表和链表呢?那我们直接进入正题吧! 1. 队列的概念(图解) 还是跟上节一样,依旧用图…...

社区迭代|ETLCloud社区新增“论坛”啦!
ETLCloud社区是谷云科技RestCloud旗下面向开发工程师、集成研发人员等技术人员提供全方位交流和学习的开放式平台,也是ETLCloud在产品生态赋能上的一大亮点,旨在能够帮助更多的用户更快捷高效的掌握技能,也为企业提供集成人才培养赋能&#x…...

ohos的代码同步以及添加自己的代码
首先我们需要获取到官方的repo工具,命令如下curl -s https://gitee.com/oschina/repo/raw/fork_flow/repo-py3 > ./repo,这里我们就拿到repo工具了,这个repo可以放任意地方,也可以放 /usr/local/bin/repo下,这样可以…...

Python的Pandas库(二)进阶使用
Python开发实用教程 DataFrame的运算 DataFrame重载了运算符,支持许多的运算 算术运算 运算方法运算说明df.add(other)对应元素的加,如果是标量,就每个元素加上标量df.radd(other)等效于otherdfdf.sub(other)对应元素相减,如果…...

如何才能从程序员到架构师?
1 引言 小团队一般 10 人左右,其中常常是技术最牛的人做架构师(或TL)。所以,架构师在广大码农中的占比大概平均不到 10%。而架构师也可以分为初级、中级、高级三档,江湖上真正高水平的软件架构师就更少了。 所以&…...

dvadmin-打包发布-nginx-静态服务器配置-防火墙设置
文章目录 1.下载nginx2.nginx常用命令3.dvadmin打包发布4.防火墙设置 1.下载nginx 也从作者下载的网址下载:https://download.csdn.net/download/m0_67316550/88470098 2.nginx常用命令 注意:一定要在dos窗口启动,不要直接双击nginx.exe&a…...

Win10中Pro/E鼠标滚轮不能缩放该怎么办?
Pro/E安装好后,鼠标滚轮不能缩放模型,该怎么办?问题多发生在win8/win10上,新装了PROE,发现滑动鼠标中键不能放大缩小。 彩虹图纸管理软件_图纸管理系统_图纸文档管理软件系统_彩虹EDM【官网】彩虹EDM图纸管理软件系统…...

腾讯云轻量应用服务器性能如何?值得入手吗?
腾讯云轻量应用服务器性能怎么样?轻量服务器的CPU内存计算性能和同规格的标准型云服务器CVM性能处于同一水准,性能很不错,具有100%CPU性能,并且价格很优惠,值得买。腾讯云百科txybk.com分享腾讯云轻量应用服务器性能测…...

主流大语言模型的技术细节
主流大语言模型的技术原理细节从预训练到微调https://mp.weixin.qq.com/s/P1enjLqH-UWNy7uaIviWRA 比较 LLaMA、ChatGLM、Falcon 等大语言模型的细节:tokenizer、位置编码、Layer Normalization、激活函数等。2. 大语言模型的分布式训练技术:数据并行、…...

面试经典150题——Day22
文章目录 一、题目二、题解 一、题目 6. Zigzag Conversion The string “PAYPALISHIRING” is written in a zigzag pattern on a given number of rows like this: (you may want to display this pattern in a fixed font for better legibility) P A H N A P L S I I G …...

for循环三种跳出循环的方法(retrun、continue、break)
1、continue:指的是跳出当前循环,即不执行continue后的语句,直接进入下次循环。 【continue语句和break语句差不多。不同的是,它不是退出一个循环,而是跳出当前循环,进行下一轮循环】 public static void…...

React中的受控组件(controlled component)和非受控组件(uncontrolled component)
聚沙成塔每天进步一点点 ⭐ 专栏简介 前端入门之旅:探索Web开发的奇妙世界 欢迎来到前端入门之旅!感兴趣的可以订阅本专栏哦!这个专栏是为那些对Web开发感兴趣、刚刚踏入前端领域的朋友们量身打造的。无论你是完全的新手还是有一些基础的开发…...

python 查找波峰和波谷
import numpy as np import matplotlib.pyplot as plt from scipy.signal import find_peaks# 生成示例信号 x np.array([1, 3, 7, 1, 2, 6, 0, 4, 3, 2, 5, 1])# 寻找波峰 peaks, _ find_peaks(x)# 寻找波谷(使用信号的负数形式) valleys, _ find_pe…...

深入理解 Document Load 和 Document Ready 的区别
目录 前言: 一、Document Ready 二、Document Load 三、理解和总结 前言: 在前端开发中,理解页面加载的不同阶段是至关重要的。特别是当我们需要在页面加载到特定阶段时执行某些操作时,我们需要知道应该使用 document ready 还…...

有趣的算法(七) ——快速排序改进算法
有趣的算法(七) ——快速排序改进算法 目录 有趣的算法(七) ——快速排序改进算法 本文章向大家介绍有趣的算法(七) ——快速排序改进算法,主要内容包括其使用实例、应用技巧、基本知识点总结…...

Vue3 + Tsx 集成 ace-editor编辑器
Ace Editor介绍 Ace Editor(全名:Ajax.org Cloud9 Editor)是一个开源的代码编辑器,旨在提供强大的代码编辑功能,通常用于构建基于Web的代码编辑应用程序。它最初由Cloud9 IDE开发,现在由开源社区维护。 主…...

TypeScritpt中的namespace
namesapce 它是在ES模块诞生前,ts自己发明的模块功能,目前已经不推荐使用了,namespace意为命名空间,就是模块化的意思。 1. 基本用法 namespace用来建立一个容器,内部的所有变量和函数只能在容器内部才能使用。 nam…...

LeetCode75——Day17
文章目录 一、题目二、题解 一、题目 1493. Longest Subarray of 1’s After Deleting One Element Given a binary array nums, you should delete one element from it. Return the size of the longest non-empty subarray containing only 1’s in the resulting array.…...

Spring中Bean的作用域
目录 一、什么是Bean的作用域 二、Scope注解 三、Bean的6种作用域 3.1 singleton单例模式 3.2 prototype 原型模式 3.3 request 3.4 session 3.5 application 3.6 websocket 一、什么是Bean的作用域 在之前学习的过程中,我们把作用域定义为:限定程序中变…...

什么是命令行参数解析和选项处理?
在C语言中,命令行参数解析和选项处理是一项关键的编程技术,它使程序能够从命令行接受参数和选项,以在运行时进行不同的配置和控制。这对于命令行工具、应用程序和脚本编写非常重要,因为它允许用户以不同的方式自定义程序的行为。本…...

网络协议--TFTP:简单文件传送协议
15.1 引言 TFTP(Trivial File Transfer Protocol)即简单文件传送协议,最初打算用于引导无盘系统(通常是工作站或X终端)。和将在第27章介绍的使用TCP的文件传送协议(FTP)不同,为了保持简单和短小࿰…...

MongoDB 的集群架构与设计
一、前言 MongoDB 有三种集群架构模式,分别为主从复制(Master-Slaver)、副本集(Replica Set)和分片(Sharding)模式。 Master-Slaver 是一种主从复制的模式,目前已经不推荐使用。Re…...

volatile 系列之实现原理
我们通过volatile解决了由于编译器的指令重排序导致的可见性问题,这意味着volatile 底层用到了内存屏障,下面我们从它的部分源码中找一下内存屏障相关的痕迹。 通过javap-V VolatileExample.class打印VolatileExample类的字节指令如下。 public static …...

【黑马程序员】mysql进阶篇笔记
2023年10月26日17:50:43 58.01. 进阶-课程介绍(Av765670802,P58) 59.02. 进阶-存储引擎-MySQL体系结构(Av765670802,P59) 60.03. 进阶-存储引擎-简介(Av765670802,P60) 61.04. 进阶-存储引擎-InnoDB介绍(Av765670802,P61) 62.05. 进阶-存储引擎-MyISAM和Memory(Av765670802…...

A - Block Sequence
思路: (1)对于每一个位置,有三种选择,一是选择删除,二是选择当排头清洗,三是被前面的排头清洗; (2)注意到总是要求将最后一位数清洗完,即前面信…...

0031【Edabit ★☆☆☆☆☆】【使用箭头函数】Using Arrow Functions
0031【Edabit ★☆☆☆☆☆】【使用箭头函数】Using Arrow Functions data_structures language_fundamentals Instructions Create a function that returns the given argument, but by using an arrow function. An arrow function is constructed like so: arrowFunc(/*p…...

C#,数值计算——分类与推理,基座向量机(SVM,Support Vector Machines)的计算方法与源程序
把 Support Vector Machines 翻译成 支持向量机 是书呆子翻译。基座向量机 不好吗。 1 文本格式 using System; namespace Legalsoft.Truffer { /// <summary> /// Support Vector Machines /// </summary> public class Svm { priv…...

面试总结之消息中间件
RabbitMQ的消息如何实现路由 RabbitMQ是一个基于AMQP协议实现的分布式消息中间件,AMQP具体的工作机制是生产者将消息发送到RabbitMQ Broker上的Exchange交换机上,Exchange交换机将收到的消息根据路由规则发给绑定的队列(Queue)&am…...

Java零基础入门-逻辑运算符
前言 Java是一种广泛应用的编程语言,在在这里插入代码片软件开发中有着重要的地位。本文将介绍Java中的逻辑运算符及其在程序设计中的应用,希望能够帮助零基础的读者更好地入门学习Java。 摘要 本文将介绍Java中的三种逻辑运算符:与运算符…...

图的应用3.0-----拓扑排序
目录 前言 AOE网 1.相关概念 2.AOE网特征 拓扑排序 1.基本概念 2.方法步骤 3.拓扑排序的应用 拓扑排序代码实现 1.邻接矩阵的代码 2.邻接表代码 前言 今天我们学习图的应用----拓扑排序,说到排序,你们是不是会想到冒泡排序,插入排序…...