【数据结构】队列
前言:
本节博客是对基础数据结构队列的一种实现思路的分享,有需要借鉴即可。
1.队列的概念
队列:只允许在一端进行插入数据操作,在另一端进行删除数据操作的特殊线性表,队列具有先
进先出FIFO(First In First Out) 入队列:进行插入操作的一端称为队尾 出队列:进行删除操作的一
端称为队头
与此恰好相反的数据结构是栈的概念:详情见博客LINK
2.队列的结构
在写代码之前,我们首先要搞清楚几个问题:
1.队列依托的底层数据结构是什么?为什么?
如果用数组来做队列的话,有个问题,就是需要不停的一个一个的挪动数据。
我们接下来看一下用链表做队列的情况:
所以选择单链表。因为单链表可行且效率较高。
总结一下:用数组实现队列,无论怎么进行布局,都避免不了挪动数据的问题;用链表实现,尾插可以作为队尾(插入数据)头删可以用来出数据。
2.队列的一个整体接口是如何的?
3.为什么在队列的效率考虑我采用了一个结构体来存储指针?(这里指针意思是记录phead的内容与ptail的内容的指针)
原因:如果不用结构体来存储指针的话,那我们每个接口传入都需要传入这两个指针比较麻烦。
3.各种接口的实现
1.初始化与销毁
void QueueInit(Queue* pq)
{assert(pq);pq->phead = pq->ptail = NULL;pq->size = 0;
}void QueueDestroy(Queue* pq)
{assert(pq);QNode* pcur = pq->phead;while (pcur){QNode* next = pcur->next;//记录free(pcur);//销毁pcur = next;//更新}pq->phead = pq->ptail = NULL;pq->size = 0;
}int QueueSize(Queue* pq)
{assert(pq);return pq->size;
}
2.进队列与出队列
这个模块属于队列的重点,因而特地强调一下。
在进队列的情况下,有两种情况,一是没有结点的时候,需要移动phead与ptail两个指针。二是有一个或者多个结点的时候,只需要移动ptail进行尾插即可。
在出队列的情况下,有三种情况,一是没有结点的时候,不能出队列;二是有一个队列的时候,需要对ptai和phead两个指针做改动;三是有多个结点的时候,只需要修改phead进行头删即可。
void QueuePush(Queue* pq, QDataType x)//=尾插
{assert(pq);//申请一块堆空间QNode* newnode = (QNode*)malloc(sizeof(QNode));if(newnode == NULL){perror("malloc fail");exit(1);}//新节点的初始化newnode->val = x;newnode->next = NULL;//如果是没有结点时候需要插入if (pq->phead == NULL){pq->phead = pq->ptail = newnode;}//至少有一个节点时需要插入(尾插)else{pq->ptail->next = newnode;pq->ptail = newnode;}pq->size++;
}void QueuePop(Queue* pq)
{assert(pq);//这里其实有三种不同的情况://1.没有结点,这种是不可以删除的//2.一个结点,那么就需要phead与ptail都需要调整(容易被坑)//3.多个结点,只需要调整phead即可assert(pq->phead != NULL);if (pq->phead == pq->ptail){free(pq->phead);pq->phead = pq->ptail = NULL;}else{QNode* next = pq->phead->next;free(pq->phead);pq->phead = next;}pq->size--;
}
3.取头结点与取尾结点
QDataType QueueFront(Queue* pq)
{assert(pq);//没有数据,不能取出assert(pq->phead != NULL);//有数据return pq->phead->val;
}QDataType QueueBack(Queue* pq)
{assert(pq);//没有数据,不能取出assert(pq->phead != NULL);//有数据return pq->ptail->val;
}bool QueueEmpty(Queue* pq)
{assert(pq);return pq->phead == NULL;
}
4.全部代码一览
#include"Queue.h"void QueueInit(Queue* pq)
{assert(pq);pq->phead = pq->ptail = NULL;pq->size = 0;
}void QueueDestroy(Queue* pq)
{assert(pq);QNode* pcur = pq->phead;while (pcur){QNode* next = pcur->next;//记录free(pcur);//销毁pcur = next;//更新}pq->phead = pq->ptail = NULL;pq->size = 0;
}int QueueSize(Queue* pq)
{assert(pq);return pq->size;
}void QueuePush(Queue* pq, QDataType x)//=尾插
{assert(pq);//申请一块堆空间QNode* newnode = (QNode*)malloc(sizeof(QNode));if(newnode == NULL){perror("malloc fail");exit(1);}//新节点的初始化newnode->val = x;newnode->next = NULL;//如果是没有结点时候需要插入if (pq->phead == NULL){pq->phead = pq->ptail = newnode;}//至少有一个节点时需要插入(尾插)else{pq->ptail->next = newnode;pq->ptail = newnode;}pq->size++;
}void QueuePop(Queue* pq)
{assert(pq);//这里其实有三种不同的情况://1.没有结点,这种是不可以删除的//2.一个结点,那么就需要phead与ptail都需要调整(容易被坑)//3.多个结点,只需要调整phead即可assert(pq->phead != NULL);if (pq->phead == pq->ptail){free(pq->phead);pq->phead = pq->ptail = NULL;}else{QNode* next = pq->phead->next;free(pq->phead);pq->phead = next;}pq->size--;
}QDataType QueueFront(Queue* pq)
{assert(pq);//没有数据,不能取出assert(pq->phead != NULL);//有数据return pq->phead->val;
}QDataType QueueBack(Queue* pq)
{assert(pq);//没有数据,不能取出assert(pq->phead != NULL);//有数据return pq->ptail->val;
}bool QueueEmpty(Queue* pq)
{assert(pq);return pq->phead == NULL;
}
#pragma once
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<stdbool.h>
#include<stdlib.h>
#include<assert.h>//队列结构-底层:单链表实现
typedef int QDataType;
typedef struct QueueNode
{QDataType val;struct QueueNode* next;
}QNode;//两个指针的结构体
typedef struct Queue
{QNode* phead;QNode* ptail;int size;
}Queue;//实现的各种接口:
//初始化与销毁
void QueueInit(Queue* pq);
void QueueDestroy(Queue* pq);
int QueueSize(Queue* pq);
//插入与删除
void QueuePush(Queue* pq, QDataType x);
void QueuePop(Queue* pq);
//取头结点与取尾结点
QDataType QueueFront(Queue* pq);
QDataType QueueBack(Queue* pq);
bool QueueEmpty(Queue* pq);
#include"Queue.h"test1()
{Queue q;QueueInit(&q);QueuePush(&q, 1);QueuePush(&q, 2);QueuePush(&q, 3);QDataType x = QueueFront(&q);printf("%d ", x);QueuePop(&q);x = QueueFront(&q);printf("%d ", x);QueuePop(&q);QueuePush(&q, 4);QueuePush(&q, 5);QueuePush(&q, 6);//取出while (QueueSize(&q) != 0){x = QueueFront(&q);printf("%d ", x);QueuePop(&q);}}int main()
{test1();return 0;
}
完。
相关文章:

【数据结构】队列
前言: 本节博客是对基础数据结构队列的一种实现思路的分享,有需要借鉴即可。 1.队列的概念 队列:只允许在一端进行插入数据操作,在另一端进行删除数据操作的特殊线性表,队列具有先 进先出FIFO(First In First Out) 入…...

学习JAVA的第十三天(基础)
目录 API之Arrays 将数组变成字符串 二分查找法查找元素 拷贝数组 填充数组 排序数组 Lambda表达式 集合的进阶 单列集合 体系结构 Collection API之Arrays 操作数组的工具类 将数组变成字符串 //将数组变成字符串char[] arr {a,b,c,d,e};System.out.println(Arra…...

C++--机器人的运动范围
目录 1. 题目 2. 思路 3. C代码测试 4. 测试结果 1. 题目 地上有一个m行和n列的方格。一个机器人从坐标0,0的格子开始移动,每一次只能向左,右,上,下四个方向移动一格,但是不能进入行坐标和列坐标的数位之和大于k的格…...
深度学习API——keras初学
keras定义相关概念: Keras是一个深度学习API,使用Python语言编写的github开源项目,主要开发者为谷歌工程师。Keras底层可调用不同的机器学习平台,如TensorFlow、Theano或micsoft-CNTK。 作用:keras主要功能是简化机器…...

Web APIs知识点讲解(阶段二)
DOM-事件基础 一.事件 1.事件 目标:能够给 DOM元素添加事件监听 事件:事件是在编程时系统内发生的动作或者发生的事情,比如用户在网页上单击一个按钮 事件监听:就是让程序检测是否有事件产生,一旦有事件触发,就立即调用一个函…...

多平台拼音输入法软件的开发
拼音输入法从上个世纪发展到现在, 已经发展了几十年了, 技术上已经非常成熟了. 换句话说, 就是实际上没多少技术含量, 随便来个人就能手搓一个. 本文介绍一个简单的多平台拼音输入法软件的设计和实现, 支持 GNU/Linux (ibus) 平台 (PC) 和 Android 平台 (手机). 目录 1 中文输…...
Flutter学习7 - Dart 泛型
1、泛型类 //泛型类 class Cache<T> {final Map<String, T> _cache {};void saveData(String key, T value) {_cache[key] value;}//泛型方法T? getData(String key) {return _cache[key];} }void main() {Cache<int> cache1 Cache();const String name…...

Git 基本操作 ⼯作区、暂存区、版本库
创建本地仓库: 创建 Git 本地仓库 要提前说的是,仓库是进行版本控制的⼀个文件目录。我们要想对文件进行版本控制,就必须先创建⼀个仓库出来。 首先touch 一个文件: 初始化仓库: 创建完成后,我们会发现当前…...
利用Vue3的新API(customRef)实现防抖效果
customRef是创建一个自定义的 ref,然后显式声明对其依赖追踪和更新触发的控制方式。因为ref是直接更新的,数据修改会马上更新,而customRef可以认为控制更新的过程,比如可以利用这个api控制 空格输入限制、数据更新速度控制、违规内…...
【Linux】在 Ubuntu 系统下使用 Screen 运行 Python 脚本
在 Ubuntu 系统下使用 Screen 运行 Python 脚本的优点 在 Ubuntu 操作系统中,Screen 是一种非常有用的工具,特别是在需要长时间运行的任务或者需要在后台运行的任务中。结合 Python 脚本,Screen 提供了一种灵活且高效的方式来管理和执行任务…...

jxls——自定义命令设置动态行高
文章目录 前言依赖引入绘制 jxls 批注的 excel 模板测试类编写自定义命令关于自动换行 前言 之前的博客中都简单说了数据的渲染和导出excel文件。包括固定的 表头结构,以及动态 表头和表数据等方式。 本篇博客主要说明自定义命令的方式,控制输出excel文…...

前端面试练习24.3.2-3.3
HTMLCSS部分 一.说一说HTML的语义化 在我看来,它的语义化其实是为了便于机器来看的,当然,程序员在使用语义化标签时也可以使得代码更加易读,对于用户来说,这样有利于构建良好的网页结构,可以在优化用户体…...

优先级队列(Java )
目录 一、 优先级队列1、概念 二、优先级队列的模拟实现1、堆的概念2、堆的存储方式 三、堆的创建1、堆向下调整2、堆的创建3、建堆的时间复杂度 四、堆的插入与删除1、堆的插入2、堆的删除 五、用堆模拟实现优先级队列 一、 优先级队列 1、概念 优先级队列(Priori…...
大宋咨询如何进行汽车门店6S标准现场检查
随着汽车市场的快速发展,汽车门店的现场管理日益受到关注。6S标准现场检查作为一项重要的评估工具,正在被越来越多的汽车厂商和经销商采用。 6S标准现场检查是指对汽车门店的整理、整顿、清洁、清扫、素养和安全六个方面进行规范和优化,旨在…...
仿牛客网项目---点赞模块的实现
本篇文章介绍一下项目中的点赞模块。 点赞模块是一个通过使用Redis实现的功能模块,它提供了点赞操作的处理逻辑和数据存取功能。通过服务类和控制器类的配合,点赞模块实现了用户对实体的点赞、点赞数量的查询、点赞状态的查询等功能。该模块使用了Redis…...

【AI视野·今日CV 计算机视觉论文速览 第300期】Fri, 1 Mar 2024
AI视野今日CS.CV 计算机视觉论文速览 Fri, 1 Mar 2024 Totally 114 papers 👉上期速览✈更多精彩请移步主页 Daily Computer Vision Papers DistriFusion: Distributed Parallel Inference for High-Resolution Diffusion Models Authors Muyang Li, Tianle Cai, J…...

【单片机学习的准备】
文章目录 前言一、找一个视频是二、画图软件三、装keil5 仿真protues总结 前言 提示:这里可以添加本文要记录的大概内容: 项目需要: 提示:以下是本篇文章正文内容,下面案例可供参考 一、找一个视频是 https://www.b…...

力扣hot100:438.找到字符串中所有字母异位词
26个字符,我复制怎么了?26个字符我比较个数怎么了? 顶多时间复杂度*26 本题用固定窗口大小的滑动窗口每次比较包含26个元素的数组次数,最容易写。 动态窗口大小哈希表存数值(双指针差值)难想难写。 一、动态…...

Kali Linux 2024.1
Kali Linux 2024.1刚刚发布,标志着这个备受欢迎的安全重点Linux发行版在今年的首次重大更新。以其先进的渗透测试和安全审计功能而闻名,它是安全专业人员和爱好者的首选工具。 Kali 2024.1 亮点 本次发布由 Linux 内核 6.6 提供支持,突出了…...
springboot启动加载
目录 使用PostConstruct注解 实现InitializingBean接口 实现CommandLineRunner接口 实现ApplicationRunner接口 使用EventListener注解监听ApplicationReadyEvent事件 应用启动完成之前或者之后,我们需要拿数据库中的一些数据加载到本地缓存中。这些数据一般都…...
变量 varablie 声明- Rust 变量 let mut 声明与 C/C++ 变量声明对比分析
一、变量声明设计:let 与 mut 的哲学解析 Rust 采用 let 声明变量并通过 mut 显式标记可变性,这种设计体现了语言的核心哲学。以下是深度解析: 1.1 设计理念剖析 安全优先原则:默认不可变强制开发者明确声明意图 let x 5; …...
反向工程与模型迁移:打造未来商品详情API的可持续创新体系
在电商行业蓬勃发展的当下,商品详情API作为连接电商平台与开发者、商家及用户的关键纽带,其重要性日益凸显。传统商品详情API主要聚焦于商品基本信息(如名称、价格、库存等)的获取与展示,已难以满足市场对个性化、智能…...
基于Uniapp开发HarmonyOS 5.0旅游应用技术实践
一、技术选型背景 1.跨平台优势 Uniapp采用Vue.js框架,支持"一次开发,多端部署",可同步生成HarmonyOS、iOS、Android等多平台应用。 2.鸿蒙特性融合 HarmonyOS 5.0的分布式能力与原子化服务,为旅游应用带来…...
数据链路层的主要功能是什么
数据链路层(OSI模型第2层)的核心功能是在相邻网络节点(如交换机、主机)间提供可靠的数据帧传输服务,主要职责包括: 🔑 核心功能详解: 帧封装与解封装 封装: 将网络层下发…...
拉力测试cuda pytorch 把 4070显卡拉满
import torch import timedef stress_test_gpu(matrix_size16384, duration300):"""对GPU进行压力测试,通过持续的矩阵乘法来最大化GPU利用率参数:matrix_size: 矩阵维度大小,增大可提高计算复杂度duration: 测试持续时间(秒&…...

QT: `long long` 类型转换为 `QString` 2025.6.5
在 Qt 中,将 long long 类型转换为 QString 可以通过以下两种常用方法实现: 方法 1:使用 QString::number() 直接调用 QString 的静态方法 number(),将数值转换为字符串: long long value 1234567890123456789LL; …...
MySQL 8.0 事务全面讲解
以下是一个结合两次回答的 MySQL 8.0 事务全面讲解,涵盖了事务的核心概念、操作示例、失败回滚、隔离级别、事务性 DDL 和 XA 事务等内容,并修正了查看隔离级别的命令。 MySQL 8.0 事务全面讲解 一、事务的核心概念(ACID) 事务是…...

C++ 设计模式 《小明的奶茶加料风波》
👨🎓 模式名称:装饰器模式(Decorator Pattern) 👦 小明最近上线了校园奶茶配送功能,业务火爆,大家都在加料: 有的同学要加波霸 🟤,有的要加椰果…...
适应性Java用于现代 API:REST、GraphQL 和事件驱动
在快速发展的软件开发领域,REST、GraphQL 和事件驱动架构等新的 API 标准对于构建可扩展、高效的系统至关重要。Java 在现代 API 方面以其在企业应用中的稳定性而闻名,不断适应这些现代范式的需求。随着不断发展的生态系统,Java 在现代 API 方…...

【Linux】Linux安装并配置RabbitMQ
目录 1. 安装 Erlang 2. 安装 RabbitMQ 2.1.添加 RabbitMQ 仓库 2.2.安装 RabbitMQ 3.配置 3.1.启动和管理服务 4. 访问管理界面 5.安装问题 6.修改密码 7.修改端口 7.1.找到文件 7.2.修改文件 1. 安装 Erlang 由于 RabbitMQ 是用 Erlang 编写的,需要先安…...