【数据结构】队列的实现
白日去如箭,达者惜今阳。 --朱敦儒
目录
🚁前言:
🏝️一.队列的概念及结构
🌻二.队列各种功能的实现
🍍1.队列的初始化
🏝️2.队列的尾入
🍉3.队列头的元素
🍁4.队列的头出
🍀5.判断是否为空
🚲6.队列尾的元素
🪂7.销毁队列
🌴三.队列的全部代码
🌻1.Queue.h:
🍌2.Queue.c:
🍈3.test.c:
🚁前言:

前几天我们对栈进行了实现,栈是数据先进后出,而今天我们要是实现的队列是完全相反的,队列
是数据先进先出。而在栈中我们使用的顺序表(数组)来实现的。而队列却用单链表来实现是更加合适的。
在队列入数据的时候,相当于是尾插,而队列出数据的时候相当于是头删。
- 队列的顺序结构
入队,不需要移动任何元素,时间复杂度为O(1)。
出队,所有元素需要往前移动,时间复杂度为O(N)。 - 队列的链式结构
首先我们定义两个指针,队头指针指向第一个节点,队尾指针指向尾节点。
入队(尾插),时间复杂度为O(1)。
出队(头删),时间复杂度为O(1)。
结论:所以我们使用单链表来实现队列。
🏝️一.队列的概念及结构
队列:只允许在一端进行插入数据操作,在另一端进行数据操作的特殊线性表,队列具有先进先出FIFO(Frist in First out)。
入队列:进行插入操作的一端称为队尾。
出队列:进行删除操作的一端称为对头。
队列的初始结构:单链表实现
typedef int QDataType;
typedef struct QueueNode
{struct QueueNode* next;//单链表QDataType data;
}QNode;typedef struct Queue
{QNode* head;//队列头QNode* tail;//队列尾
}Queue;
🌻二.队列各种功能的实现
🍍1.队列的初始化
这里我们实现的单链表是无头不循环的单链表。所以我们把队列头和队列尾初始化为空指针。
//初始化
void QueueInit(Queue* ps)
{assert(ps);ps->head = ps->tail = NULL;
}
🏝️2.队列的尾入
对于队列的尾入,我们要分为两种情况:
第一种:第一次尾入数据的时候,队列头和队列尾都是指向的同一个位置,并且都是空,当我们要尾入的时候创建一个新的结点,把新结点赋值给队列的头和队列的尾。
第二种:队列已经有数据了,我们把新的结点链接到尾后面,然后再把新结点赋值为新的结点,也就是更新队列的尾。总结:队列头是一直不变的,队列尾入一个数据就需要把队列尾往后面移动一位。
//队尾入
void QueuePush(Queue* ps,QDataType x)
{assert(ps);QNode* newnode = (QNode*)malloc(sizeof(QNode));//创建一个新的结点if (newnode == NULL){perror("malloc\n");return;}newnode->data = x;newnode->next = NULL;if ( ps->tail == NULL)//第一种情况{ps->head=ps->tail = newnode;//新结点就是队列尾和队列头}else//第二种情况{ps->tail->next = newnode;//队列尾链接新的结点ps->tail = newnode;//更新队列尾}
}
🍉3.队列头的元素
需要知道队列头的元素是非常简单的,只需要返回队列头的元素即可。
//头的元素
QDataType QueueFront(Queue* ps)
{assert(ps);assert(ps->head);return ps->head->data;
}
🍁4.队列的头出
队列的头出也是分为两种情况:
第一种:当队列只有一个结点的时候,直接free掉第一个结点即可,然后把队列头和对列尾赋值尾空即可。
第二种:当队列有两个及两个以上的结点的时候,我们先保存队列头的下一个结点,然后free掉队列头即可。
//对头出
void QueuePop(Queue* ps)
{assert(ps);assert(ps->head);if (ps->head->next == NULL)//当队列只有一个结点时{free(ps->head);ps->head = ps->tail = NULL;}else//当队列有两个或者两个以上的结点时{QNode* next = ps->head->next;//free掉第一个结点时,先保存下一个结点free(ps->head);ps->head = next;}
}
🍀5.判断是否为空
在队列出的时候,我们出一个数据就要判断一下队列是否为空,如果为空,我们就不能出数据了。
我们还是和栈的判断空一样,使用bool值来判断。
//判断是否为空
bool QueueEmpty(Queue* ps)
{assert(ps);return ps->head == NULL;
}
有了上面的代码我们就可以把出队列的数据给打印一下。
很明显这和队列的结构时一致的,即先进先出。
🚲6.队列尾的元素
//尾的元素
QDataType QueueBack(Queue* ps)
{assert(ps);assert(ps->head);return ps->tail->data;
}
🪂7.销毁队列
最后退出程序,我们再把队列给销毁一下。
//销毁队列
void QueueDestroy(Queue* ps)
{assert(ps);QNode* cur = ps->head;while (cur){QNode* next = ps->head->next;free(ps->head);ps->head = next;cur = next;}ps->head = ps->tail == NULL;
}
最后我们再把队列的功能给实现一下:
🌴三.队列的全部代码
🌻1.Queue.h:
#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include<stdbool.h>typedef int QDataType;
typedef struct QueueNode
{struct QueueNode* next;QDataType data;
}QNode;typedef struct Queue
{QNode* head;QNode* tail;
}Queue;//初始化
void QueueInit(Queue* ps);//队尾插
void QueuePush(Queue* ps,QDataType x);//队头出
void QueuePop(Queue* ps);//头的元素
QDataType QueueFront(Queue* ps);//尾的元素
QDataType QueueBack(Queue* ps);//队列的元素个数
int QueueSize(Queue* ps);//判断是否为空
bool QueueEmpty(Queue* ps);//销毁队列
void QueueDestroy(Queue* ps);
🍌2.Queue.c:
#define _CRT_SECURE_NO_WARNINGS 1
#include"Queue.h"//初始化
void QueueInit(Queue* ps)
{assert(ps);ps->head = ps->tail = NULL;
}//队尾入
void QueuePush(Queue* ps,QDataType x)
{assert(ps);QNode* newnode = (QNode*)malloc(sizeof(QNode));if (newnode == NULL){perror("malloc\n");return;}newnode->data = x;newnode->next = NULL;if ( ps->tail == NULL){ps->head=ps->tail = newnode;}else{ps->tail->next = newnode;ps->tail = newnode;}
}//对头出
void QueuePop(Queue* ps)
{assert(ps);assert(ps->head);if (ps->head->next == NULL)//当队列只有一个结点时{free(ps->head);ps->head = ps->tail = NULL;}else//当队列有两个或者两个以上的结点时{QNode* next = ps->head->next;//free掉第一个结点时,先保存下一个结点free(ps->head);ps->head = next;}
}//头的元素
QDataType QueueFront(Queue* ps)
{assert(ps);assert(ps->head);return ps->head->data;
}//尾的元素
QDataType QueueBack(Queue* ps)
{assert(ps);assert(ps->head);return ps->tail->data;
}//队列的元素个数
int QueueSize(Queue* ps)
{int count = 0;QNode* cur = ps->head;while (cur){count++;cur = cur->next;}return count;
}//销毁队列
void QueueDestroy(Queue* ps)
{assert(ps);QNode* cur = ps->head;while (cur){QNode* next = ps->head->next;free(ps->head);ps->head = next;cur = next;}ps->head = ps->tail == NULL;
}//判断是否为空
bool QueueEmpty(Queue* ps)
{assert(ps);return ps->head == NULL;
}
🍈3.test.c:
#define _CRT_SECURE_NO_WARNINGS 1
#include"Queue.h"
int main()
{QNode q;QueueInit(&q);QueuePush(&q, 1);QueuePush(&q, 2);QueuePush(&q, 3);QueuePush(&q, 4);printf("对于队列 1 2 3 4 出的数据为:\n");while (!QueueEmpty(&q)){printf("%d ", QueueFront(&q));QueuePop(&q);}QueuePush(&q, 5);QueuePush(&q, 6);QueuePush(&q, 7);QueuePush(&q, 8);printf("\n");printf("队列的元素为 5 6 7 8\n");printf("队列头的元素为:\n");int first = QueueFront(&q);printf("%d\n", first);printf("队列尾的元素为:\n");int tail = QueueBack(&q);printf("%d\n", tail);printf("队列的元素的个数为:\n");int count = QueueSize(&q);printf("%d\n", count);QueueDestroy(&q);printf("退出程序\n");printf("队列已经被销毁……\n");return 0;
}
相关文章:

【数据结构】队列的实现
白日去如箭,达者惜今阳。 --朱敦儒目录 🚁前言: 🏝️一.队列的概念及结构 🌻二.队列各种功能的实现 🍍1.队列的初始化 🏝️2.队列…...

【数据库】— 无损连接、Chase算法、保持函数依赖
【数据库】— 无损连接、Chase算法 Chase算法Chase算法举例一种简便方法:分解为两个模式时无损连接和函数依赖的一个简单例子 Chase算法 形式化定义: 构造一个 k k k行 n n n列的表格,每行对应一个模式 R i ( 1 ≤ i ≤ k ) Ri (1≤i ≤ k)…...

用英语翻译中文-汉字英文翻译
中文转英语翻译 作为一款高效、准确的中文转英语翻译软件,我们的产品可以帮助全球用户更好地沟通和合作,实现跨文化交流。 在全球化的今天,中英文翻译已经成为商务、学术、娱乐等各个领域不可或缺的一部分。我们的中文转英语翻译软件是为了…...
瑞吉外卖项目——缓存优化
用户数量多,系统访问量大 频繁访问数据库,系统性能下降,用户体验差 环境搭建 maven坐标 在项目的pom.xml文件中导入spring data redis的maven坐标: <dependency><groupId>org.springframework.boot</groupId><arti…...

从头创建一个新的浏览器,这合理吗?
从头构建一个新浏览器?这如果是不是个天大的“伪需求”,便是一场开发者的噩梦! 要知道,如果没有上百亿的资金和数百名研发工程师的投入,从头开始构建一个新的浏览器引擎,几乎是不可能的。然而SerenityOS系统…...
TypeScript泛型类型和接口
本节课我们来开始了解 TypeScript 中泛型类型的概念和接口使用。 一.泛型类型 1. 前面,我们通过泛型变量的形式来存储调用方的类型从而进行检查; 2. 而泛型也可以作为类型的方式存在,理解这一点,先了解下函数的…...
docker命令
1.运行 docker-compose up 2.查看命令 docker images 3.删掉docker镜像: docker rmi -f [id] docker卸载 1.杀死docker有关的容器: docker kill $(docker ps -a -q) 2.删除所有docker容器:docker rm $(docker ps -a -q) 3.删除所有docker镜像&…...

2023 年 3 月 NFT 月度报告
作者:Danielfootprint.network 数据来源:NFT Monthly Report 三月份的 NFT 市场上出现了两个有趣的趋势。一方面,Polygon 链尽管在二月份有所突破,达到了 NFT 总交易量的 4.2%,但于三月再次跌至 1% 以下,…...

【http】 get方法和Post方法区别;http和https
get方法和Post方法 get方法:通过url传参,回显输入的私密信息,不够私密 Post方法:通过正文传参,不会回显,一般私密性有保证。 一般如果上传的图片,音频比较大,推荐Post方法&#x…...

第三章 法的渊源与法的分类
目录 第一节 法的渊源的分类 一、法的渊源释义二、法的渊源种类 第二节 正式法源 一、正式法源的含义二、当代中国的正式法源三、正式法源的一般效力原则 第三节 非正式法源 一、当代中国的非正式法源 第四节 法的分类 一、法的一般分类二、法的特殊分类 第一节 法的渊源的…...
在Ubuntu18.04或者20.04下搭建edk2运行环境
#更新完之后依次执行下面两条命令 1.apt-get update 2.apt-get upgrade 如果执行之后出现源不能更新的问题,到/etc/apt/sources.list.d 下删除对应的ppa源重新更新即可解决 git clone https://github.com/tianocore/edk2.git cd edk2 git submodule update --init 如果git cl…...
多线程编程常用函数用法
一、多线程编程常用函数用法 1、pthread_create 头文件 #include<pthread.h>函数声明 int pthread_create(pthread_t*restrict tidp,const pthread_attr_t *restrict_attr,void*(*start_rtn)(void*),void *restrict arg)函数功能 pthread_create是UNIX环境…...

C++ 标准模板库(Standard Template Library,STL)
✅作者简介:人工智能专业本科在读,喜欢计算机与编程,写博客记录自己的学习历程。 🍎个人主页:小嗷犬的个人主页 🍊个人网站:小嗷犬的技术小站 🥭个人信条:为天地立心&…...
一个寄存器的bit2 bit3位由10修改成11,C示例
方法1: 如果需要将一个寄存器中的 bit2 和 bit3 两个位从 11 修改为 10,可以使用如下的 C 语言代码实现: // 将寄存器的 bit2 和 bit3 位从 11 修改为 10 volatile uint32_t *reg_addr (volatile uint32_t *)0x12345678; // 假设寄存器地址…...
【洛谷】P1631 序列合并
【洛谷】 P1631 序列合并 题目描述 有两个长度为 N N N 的单调不降序列 A , B A,B A,B,在 A , B A,B A,B 中各取一个数相加可以得到 N 2 N^2 N2 个和,求这 N 2 N^2 N2 个和中最小的 N N N 个。 输入格式 第一行一个正整数 N N N; 第二…...
2023年七大最佳勒索软件解密工具
勒索软件是目前最恶毒且增长最快的网络威胁之一。作为一种危险的恶意软件,它会对文件进行加密,并用其进行勒索来换取报酬。 幸运的是,我们可以使用大量的勒索软件解密工具来解锁文件,而无需支付赎金。如果您的网络不幸感染了勒索软…...
prettier 命令行工具来格式化多个文件
prettier 命令行工具来格式化多个文件 你可以使用 prettier 命令行工具来格式化多个文件。以下是一个使用命令行批量格式化文件的示例: 安装 prettier 如果你还没有安装 prettier,你可以使用以下命令安装它: npm install -g prettier 进入…...

我发现了PMP通关密码!这14页纸直接背!
一周就能背完的PMP考试技巧只有14页纸 共分成了4大模块 完全不用担心看不懂 01关键词篇 第1章引论 1.看到“驱动变革”--选项中找“将来状态” 2.看到“依赖关系”--选项中找“项目集管理” 3.看到“价值最大化”--选项中找“项目组合管理” 4.看到“可行性研究”--选项中…...

Medical X-rays Dataset汇总(长期更新)
目录 ChestX-ray8 ChestX-ray14 VinDr-CXR VinDr-PCXR ChestX-ray8 ChestX-ray8 is a medical imaging dataset which comprises 108,948 frontal-view X-ray images of 32,717 (collected from the year of 1992 to 2015) unique patients with the text-mi…...
一文告诉你如何做好一份亚马逊商业计划书的框架
“做亚马逊很赚钱”、“我也来做”、“哎,亏钱了”诸如此类的话听了实在是太多。亚马逊作为跨境电商老大哥,许多卖家还是对它怀抱着很高的期许。但是,事实的残酷的。有人入行赚得盆满钵盈,自然也有人亏得血本无归。 会造成这种两…...

MPNet:旋转机械轻量化故障诊断模型详解python代码复现
目录 一、问题背景与挑战 二、MPNet核心架构 2.1 多分支特征融合模块(MBFM) 2.2 残差注意力金字塔模块(RAPM) 2.2.1 空间金字塔注意力(SPA) 2.2.2 金字塔残差块(PRBlock) 2.3 分类器设计 三、关键技术突破 3.1 多尺度特征融合 3.2 轻量化设计策略 3.3 抗噪声…...

基于FPGA的PID算法学习———实现PID比例控制算法
基于FPGA的PID算法学习 前言一、PID算法分析二、PID仿真分析1. PID代码2.PI代码3.P代码4.顶层5.测试文件6.仿真波形 总结 前言 学习内容:参考网站: PID算法控制 PID即:Proportional(比例)、Integral(积分&…...

大话软工笔记—需求分析概述
需求分析,就是要对需求调研收集到的资料信息逐个地进行拆分、研究,从大量的不确定“需求”中确定出哪些需求最终要转换为确定的“功能需求”。 需求分析的作用非常重要,后续设计的依据主要来自于需求分析的成果,包括: 项目的目的…...
ubuntu搭建nfs服务centos挂载访问
在Ubuntu上设置NFS服务器 在Ubuntu上,你可以使用apt包管理器来安装NFS服务器。打开终端并运行: sudo apt update sudo apt install nfs-kernel-server创建共享目录 创建一个目录用于共享,例如/shared: sudo mkdir /shared sud…...

遍历 Map 类型集合的方法汇总
1 方法一 先用方法 keySet() 获取集合中的所有键。再通过 gey(key) 方法用对应键获取值 import java.util.HashMap; import java.util.Set;public class Test {public static void main(String[] args) {HashMap hashMap new HashMap();hashMap.put("语文",99);has…...
蓝桥杯 2024 15届国赛 A组 儿童节快乐
P10576 [蓝桥杯 2024 国 A] 儿童节快乐 题目描述 五彩斑斓的气球在蓝天下悠然飘荡,轻快的音乐在耳边持续回荡,小朋友们手牵着手一同畅快欢笑。在这样一片安乐祥和的氛围下,六一来了。 今天是六一儿童节,小蓝老师为了让大家在节…...
大语言模型如何处理长文本?常用文本分割技术详解
为什么需要文本分割? 引言:为什么需要文本分割?一、基础文本分割方法1. 按段落分割(Paragraph Splitting)2. 按句子分割(Sentence Splitting)二、高级文本分割策略3. 重叠分割(Sliding Window)4. 递归分割(Recursive Splitting)三、生产级工具推荐5. 使用LangChain的…...
工程地质软件市场:发展现状、趋势与策略建议
一、引言 在工程建设领域,准确把握地质条件是确保项目顺利推进和安全运营的关键。工程地质软件作为处理、分析、模拟和展示工程地质数据的重要工具,正发挥着日益重要的作用。它凭借强大的数据处理能力、三维建模功能、空间分析工具和可视化展示手段&…...
Matlab | matlab常用命令总结
常用命令 一、 基础操作与环境二、 矩阵与数组操作(核心)三、 绘图与可视化四、 编程与控制流五、 符号计算 (Symbolic Math Toolbox)六、 文件与数据 I/O七、 常用函数类别重要提示这是一份 MATLAB 常用命令和功能的总结,涵盖了基础操作、矩阵运算、绘图、编程和文件处理等…...
高效线程安全的单例模式:Python 中的懒加载与自定义初始化参数
高效线程安全的单例模式:Python 中的懒加载与自定义初始化参数 在软件开发中,单例模式(Singleton Pattern)是一种常见的设计模式,确保一个类仅有一个实例,并提供一个全局访问点。在多线程环境下,实现单例模式时需要注意线程安全问题,以防止多个线程同时创建实例,导致…...