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

单链表实现【队列】

目录

队列的概念及其结构

队列的实现

数组队列

链式队列

队列的常见接口的实现

主函数Test.c

头文件&函数声明Queue.h

头文件

函数声明

函数实现Queue.c

初始化QueueInit

创建节点Createnode 

空间释放QueueDestroy

入队列QueuePush

出队列QueuePop

队头元素QueueFront

队尾元素QueueBack

判断队列是否为空QueueEmpty

队列元素个数QueueSize

链式队列总代码


队列的概念及其结构

队列:只允许在一端进行插入数据操作,在另一端进行删除数据操作的特殊线性表。

队列具有 先进先出 /后进后出 FIFO(First In First Out)

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

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

队列的实现

队列的实现也有两种方式。队列也可以数组和链表的结构实现,使用链表的结构实现更优一些,因为如果使用数组的结构,出队列在数组头上出数据,效率会比较低

数组队列

虽然数组也可以实现【队列】,但是挪动数据的效率真的很低!! 

链式队列

无论是【栈】还是【队列】双向链表都是通吃的。但是我们为了节省资源就是要用【单链表】去实现队列。我们用【单链表】去实现【队列】需要注意:

  • 入队列 == 尾插
  • 出队列 == 头删
  • 需要ptail指针维护队列最后一个元素
  • 需要phead指针维护队列最后一个元素
  • 二级指针&一级指针
  • 带不带哨兵位的头节点都可(哨兵位的头节点最后要释放空间)

应用场景:办理业务排队打号机。因为【队列】是绝对公平的。

队列的常见接口的实现

  • 入队列和出队列的顺序都只有一种!!
  • 传二级指针/传一级指针的情况
  • 怎么去计算队列元素个数❓
  • 怎么用其他方式替代传二级指针❓空间换时间的方式
  • 链表都需要考虑❓链表没有元素❓链表只有一个元素//两种情况即对应指针的判断情况
  • 二级指针 == 头节点 == 返回值 == 结构体包含两个一级指针 

主函数Test.c

#include"Queue.h"
int main()
{Queue pq;QueueInit(&pq);QueuePush(&pq, 1);QueuePush(&pq, 2);QueuePush(&pq, 3);QueuePush(&pq, 4);QueuePush(&pq, 77);QueuePush(&pq, 7);while (!QueueEmpty(&pq)){printf("队头元素:%d\n", QueueFront(&pq));//printf("队尾元素:%d\n", QueueBack(&pq));QueuePop(&pq);}QueueDestroy(&pq);return 0;
}

头文件&函数声明Queue.h

头文件

#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<stdbool.h>
#include<assert.h>

函数声明

  • 创建节点
typedef int QDataType;
//创建队列节点
typedef struct QueueNode
{QDataType val;struct QueueNode* next;//易错❌QNode*next
}QNode;
  • 创建维护队列的指针
//两个指针维护链表队列
typedef struct Queue
{QNode* phead;QNode* ptail;int size;
}Queue;
  • 初始化
void QueueInit(Queue* pq);
  • 销毁释放空间
void QueueDestroy(Queue* pq);
  • 入队列
void QueuePush(Queue* pq, QDataType x);
  • 出队列
void QueuePop(Queue* pq);
  • 队头元素
QDataType QueueFront(Queue* pq);
  • 队尾元素
QDataType QueueBack(Queue* pq);
  • 判断队列是否为空
bool QueueEmpty(Queue* pq);
  • 队列元素个数
int QueueSzie(Queue* pq);

函数实现Queue.c

初始化QueueInit

#include"Queue.h"
//不需要头节点,初始化
void QueueInit(Queue* pq)
{assert(pq);pq->phead = NULL;pq->ptail = NULL;pq->size = 0;
}

创建节点Createnode 

Queue* Createnode(Queue* pq, QDataType x)
{assert(pq);QNode* newnode = (QNode*)malloc(sizeof(QNode));if (newnode == NULL){perror("fail malloc");return;}newnode->val = x;newnode->next = NULL;return newnode;
}

空间释放QueueDestroy

//空间释放
void QueueDestroy(Queue* pq)
{assert(pq);while (pq->phead){Queue* cur = pq->phead;pq->phead = pq->phead->next;free(cur);cur = NULL;}pq->phead = NULL;pq->ptail = NULL;pq->size = 0;
}

入队列QueuePush

//Push元素
void QueuePush(Queue* pq, QDataType x)
{assert(pq);//创建节点Queue* newnode = Createnode(pq,x);if (pq->phead == NULL){pq->phead = pq->ptail = newnode;}else{pq->ptail->next = newnode;pq->ptail = newnode;}pq->size++;
}

出队列QueuePop

  • 删到空的情况(phead/ptail野指针的情况)
  • 删到只剩一个节点的情况(ptail野指针的情况)
//Pop元素
void QueuePop(Queue* pq)
{assert(pq);assert(pq->size > 0);//为NULL的判断Queue* cur = pq->phead;pq->phead = pq->phead->next;free(cur);cur = NULL;//为一个节点的判断if (pq->phead == NULL){pq->ptail = NULL;}pq->size--;
}

队头元素QueueFront

//队头元素
QDataType QueueFront(Queue* pq)
{assert(pq);assert(pq->size > 0);return pq->phead->val;
}

队尾元素QueueBack

//队尾元素
QDataType QueueBack(Queue* pq)
{assert(pq);assert(pq->size > 0);return pq->ptail->val;
}

判断队列是否为空QueueEmpty

//判断是否为NULL
bool QueueEmpty(Queue* pq)
{assert(pq);return pq->size == 0;
}

队列元素个数QueueSize

//队员元素个数
int QueueSzie(Queue* pq)
{assert(pq);return pq->size;
}

链式队列总代码

//Test.c
#include"Queue.h"
int main()
{Queue pq;QueueInit(&pq);QueuePush(&pq, 1);QueuePush(&pq, 2);QueuePush(&pq, 3);QueuePush(&pq, 4);QueuePush(&pq, 77);QueuePush(&pq, 7);while (!QueueEmpty(&pq)){printf("队头元素:%d\n", QueueFront(&pq));//printf("队尾元素:%d\n", QueueBack(&pq));QueuePop(&pq);}QueueDestroy(&pq);return 0;
}
//Queue.h
#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<stdbool.h>
#include<assert.h>typedef int QDataType;
//创建队列节点
typedef struct QueueNode
{QDataType val;struct QueueNode* next;//易错❌QNode*next
}QNode;
//两个指针维护链表队列
typedef struct Queue
{QNode* phead;QNode* ptail;int size;
}Queue;
//接口的实现
void QueueInit(Queue* pq);//初始化
void QueueDestroy(Queue* pq);//空间释放
void QueuePush(Queue* pq, QDataType x);//放元素到队列尾
void QueuePop(Queue* pq);//出元素到队头
QDataType QueueFront(Queue* pq);//队列头的元素
QDataType QueueBack(Queue* pq);//队列尾的元素
bool QueueEmpty(Queue* pq);//判断队列是否是否为NULL
int QueueSzie(Queue* pq);//队列里面的元素个数
//Queue.c
#include"Queue.h"
//不需要头节点,初始化
void QueueInit(Queue* pq)
{assert(pq);pq->phead = NULL;pq->ptail = NULL;pq->size = 0;
}Queue* Createnode(Queue* pq, QDataType x)
{assert(pq);QNode* newnode = (QNode*)malloc(sizeof(QNode));if (newnode == NULL){perror("fail malloc");return;}newnode->val = x;newnode->next = NULL;return newnode;
}
//Push元素
void QueuePush(Queue* pq, QDataType x)
{assert(pq);//创建节点Queue* newnode = Createnode(pq,x);if (pq->phead == NULL){pq->phead = pq->ptail = newnode;}else{pq->ptail->next = newnode;pq->ptail = newnode;}pq->size++;
}//Pop元素
void QueuePop(Queue* pq)
{assert(pq);assert(pq->size > 0);//为NULL的判断Queue* cur = pq->phead;pq->phead = pq->phead->next;free(cur);cur = NULL;//为一个节点的判断if (pq->phead == NULL){pq->ptail = NULL;}pq->size--;
}//队头元素
QDataType QueueFront(Queue* pq)
{assert(pq);assert(pq->size > 0);return pq->phead->val;
}//队尾元素
QDataType QueueBack(Queue* pq)
{assert(pq);assert(pq->size > 0);return pq->ptail->val;
}//判断是否为NULL
bool QueueEmpty(Queue* pq)
{assert(pq);return pq->size == 0;
}//队员元素个数
int QueueSzie(Queue* pq)
{assert(pq);return pq->size;
}//空间释放
void QueueDestroy(Queue* pq)
{assert(pq);while (pq->phead){Queue* cur = pq->phead;pq->phead = pq->phead->next;free(cur);cur = NULL;}pq->phead = NULL;pq->ptail = NULL;pq->size = 0;
}

✔✔✔✔✔最后,感谢大家的阅读,若有错误和不足,欢迎指正!下篇博文会分享一些【栈和队列的OJ题目】&【循环队列】各位小伙伴乖乖敲代码哦。 

代码---------→【唐棣棣 (TSQXG) - Gitee.com】

联系---------→【邮箱:2784139418@qq.com】

相关文章:

单链表实现【队列】

目录 队列的概念及其结构 队列的实现 数组队列 链式队列 队列的常见接口的实现 主函数Test.c 头文件&函数声明Queue.h 头文件 函数声明 函数实现Queue.c 初始化QueueInit 创建节点Createnode 空间释放QueueDestroy 入队列QueuePush 出队列QueuePop 队头元…...

随机微分方程的MATLAB数值求解

dt0.01; tout200; %总时间为2 xzeros(1,tout); x(1)0.5; %初始位置 mu0.2; sigma1; Wtsqrt(dt)*randn(1,tout); %产生随机序列Wt for t1:tout-1x(t1)x(t)mu*x(t)*dtsigma*x(t)*Wt(t); end t11:10:tout; %对原时间序列进行抽样 xtzeros(1,length(t1)); i1; for tt1xt(i)0.5*exp(…...

ChatGPT 也并非万能,品牌如何搭上 AIGC「快班车」

内容即产品的时代&#xff0c;所见即所得&#xff0c;所得甚至超越所见。 无论是在公域的电商平台、社交媒体&#xff0c;还是品牌私域的官网、社群、小程序&#xff0c;品牌如果想与用户发生连接&#xff0c;内容永远是最前置的第一要素。 01 当内容被消费过&#xff0c;就…...

【JavaSE】不允许你不会使用String类

&#x1f3a5; 个人主页&#xff1a;深鱼~&#x1f525;收录专栏&#xff1a;JavaSE&#x1f304;欢迎 &#x1f44d;点赞✍评论⭐收藏 目录 前言&#xff1a; 一、常用方法 1.1 字符串构造 1.2 String对象的比较 &#xff08;1&#xff09;比较是否引用同一个对象 注意…...

身份证阅读器和社保卡读卡器Harmony鸿蒙系统ArkTS语言SDK开发包

项目需求&#xff0c;用ArkTS新一代开发语言实现了在Harmony鸿蒙系统上面兼容身份证阅读器和社保卡读卡器&#xff0c;调用了DonseeDeviceLib.har这个读卡库。 需要注意的是&#xff0c;鸿蒙系统的app扩展名为.hap&#xff0c;本项目编译输出的应用为&#xff1a;entry-default…...

并发与并行

并发和并行是操作系统中的两个重要概念&#xff0c;它们在定义和处理任务的方式上有一些区别。 并发&#xff08;concurrency&#xff09;是指在一段时间内&#xff0c;有多个程序都处于启动运行到运行完毕之间&#xff0c;但任一时刻点上只有一个程序在处理机上运行。它是一种…...

搭个网页应用,让ChatGPT帮我写SQL

大家好&#xff0c;我是凌览。 开门见山&#xff0c;我搭了一个网页应用名字叫sql-translate。访问链接挂在我的个人博客(https://linglan01.cn/about)导航栏&#xff0c;也可以访问https://www.linglan01.cn/c/sql-translate/直达sql-translate。 它的主要功能有&#xff1a;…...

实时云渲染 助力破解智慧园区痛点困局

智慧园区是运用先进的信息技术&#xff0c;如物联网&#xff08;IoT&#xff09;、大数据、云计算、人工智能、三维可视化等&#xff0c;对园区内的各类设施、资源以及管理进行智能化和数字化升级。其目标是通过科技手段提升园区的运营效率、资源利用率&#xff0c;提供更便捷、…...

计算机组成原理2

1.浮点数 2.IEEE 754 3.存储器的性能指标 4.存储器的层次化结构 主存类似手机运行内存8g &#xff0c;辅存类似手机内存128g.... 辅存必须先通过主存才能被cpu接收&#xff0c;就例如微信打开那个月亮小人界面两三秒就是主存在读取辅存的程序然后被cpu接收运行。 5.主存储…...

Py之PyMuPDF:PyMuPDF的简介、安装、使用方法之详细攻略

Py之PyMuPDF&#xff1a;PyMuPDF的简介、安装、使用方法之详细攻略 目录 PyMuPDF的简介 PyMuPDF的安装 PyMuPDF的使用方法 1、基础用法 PyMuPDF的简介 PyMuPDF是一个高性能的Python库&#xff0c;用于PDF(和其他)文档的数据提取&#xff0c;分析&#xff0c;转换和操作。 …...

2023亚太杯数学建模A题B题C题思路模型代码论文指导

2023亚太地区数学建模A题思路&#xff1a;开赛后第一时间更新&#xff0c;获取见文末 名片 2023亚太地区数学建模B题思路&#xff1a;开赛后第一时间更新&#xff0c;获取见文末 名片 2023亚太地区数学建模C题思路&#xff1a;开赛后第一时间更新&#xff0c;获取见文末 名片…...

【C/PTA】函数专项练习(四)

本文结合PTA专项练习带领读者掌握函数&#xff0c;刷题为主注释为辅&#xff0c;在代码中理解思路&#xff0c;其它不做过多叙述。 目录 6-1 计算A[n]1/(1 A[n-1])6-2 递归实现顺序输出整数6-3 自然数的位数(递归版)6-4 分治法求解金块问题6-5 汉诺塔6-6 重复显示字符(递归版)…...

广西柳州机械异形零部件三维扫描3D抄数全尺寸测绘建模-CASAIM中科广电

一、背景介绍 复杂机械异形零部件具有不规则的形状和复杂的结构&#xff0c;给生产制造带来了很大的检测难度。为了确保零部件的制造质量和精度&#xff0c;需要对零部件进行全面的尺寸检测和分析。 CASAIM三维扫描仪在机械异形零部件全尺寸检测应用可以实现对机械异形零部件…...

(四)C语言之符号常量概述

&#xff08;四&#xff09;C语言之符号常量概述 一、符号常量概述 一、符号常量概述 在程序中使用像300,20等这样的等类似的“幻数”不是一个好的习惯&#xff0c;它们无法向阅读该程序的人提供更多有用的信息&#xff0c;从而使得修改程序变得困难。处理这种幻数的一种方法是…...

springboot -sse -flux 服务器推送消息

先说BUG处理&#xff0c;遇到提示异步问题 Async support must be enabled on a servlet and for all filters involved in async request processing. This is done in Java code using the Servlet API or by adding "<async-supported>true</async-supported&…...

js进阶笔记之原型,原型链

目录 1、原型对象 constructor 属性 对象原型 2、原型链 3、instanceof 4、原型继承 1、原型对象 面向过程就是分析出解决问题所需要的步骤&#xff0c;然后用函数把这些步骤一步一步实现&#xff0c;使用的时候再一个一个的依次调用就可以了。 面向对象是把事务分解成为…...

【DevOps】Git 图文详解(四):Git 使用入门

本系列包含&#xff1a; Git 图文详解&#xff08;一&#xff09;&#xff1a;简介及基础概念Git 图文详解&#xff08;二&#xff09;&#xff1a;Git 安装及配置Git 图文详解&#xff08;三&#xff09;&#xff1a;常用的 Git GUIGit 图文详解&#xff08;四&#xff09;&a…...

Jquery ajax 同步阻塞引起的UI线程阻塞的坑(loading图片显示不出来 )

Jquery ajax 同步阻塞引起的UI线程阻塞的坑&#xff08;loading图片显示不出来&#xff0c;layer.load延迟&#xff09;jax重新获取数据刷新页面功能&#xff0c;因为ajax属于耗时操作&#xff0c;想在获取数据且加载页面时显示加载遮罩层&#xff0c;结果发现了ajax的好多坑。…...

读书笔记——《黑猩猩的政治》

前言 弗朗斯德瓦尔&#xff08;Frans de Waal)的代表作《黑猩猩政治》成书于1982年&#xff0c;是它的首部书籍作品&#xff0c;也是美国国会新任议员的被推荐读物。之前看的他另一部作品的《万智有灵》是2016年的作品&#xff0c;时间跨度居然这么大。《万智有灵》介绍了许多…...

此处不允许使用特性namespace

1.DOCTYPE 后面改成 mapper 2.PUBLIC一行中的Config改为Mapper 3.将下一行config变为小写的mapper <?xml version"1.0" encoding"UTF-8" ?> <!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.or…...

Clawdbot性能调优:提升Qwen3-VL模型响应速度的10个技巧

Clawdbot性能调优&#xff1a;提升Qwen3-VL模型响应速度的10个技巧 1. 引言 如果你正在使用Clawdbot集成Qwen3-VL模型&#xff0c;可能会遇到响应速度不够理想的情况。特别是在处理多模态任务时&#xff0c;模型推理、数据传输和结果返回都需要时间&#xff0c;用户等待时间过…...

如何快速掌握llama-cpp-python:从Python调用到多模态AI应用开发

如何快速掌握llama-cpp-python&#xff1a;从Python调用到多模态AI应用开发 【免费下载链接】llama-cpp-python Python bindings for llama.cpp 项目地址: https://gitcode.com/gh_mirrors/ll/llama-cpp-python 在人工智能快速发展的今天&#xff0c;本地部署大型语言模…...

在苹果设备上开启跨平台冒险:UTM虚拟机的魔法世界

在苹果设备上开启跨平台冒险&#xff1a;UTM虚拟机的魔法世界 【免费下载链接】UTM Virtual machines for iOS and macOS 项目地址: https://gitcode.com/gh_mirrors/ut/UTM 你是否曾幻想过&#xff0c;在iPad上运行Windows系统处理Excel表格&#xff0c;或在MacBook上体…...

游友云-风启之旅-Windrose-模组安装教程

前言&#xff1a; 部分模组只需要服务端安装即可&#xff0c;具体请阅读模组介绍 服务器不建议装太多高倍率&#xff0c;目前bug较多容易崩服 模组可能会影响存档&#xff0c;注意备份&#xff01;&#xff01; 推荐服务器&#xff1a;yy.0play.cn 下载模组&#xff1a; 打…...

从Spring Boot项目里‘偷’图:手把手教你用PlantUML插件,自动生成UML类图

从Spring Boot项目自动生成UML类图的工程实践 在真实的软件开发过程中&#xff0c;UML类图往往被视为文档编制的"必修课"&#xff0c;却鲜少发挥其真正的工程价值。传统的手动绘制方式不仅效率低下&#xff0c;更难以与快速迭代的代码保持同步。本文将颠覆这一现状&a…...

避坑指南:AIP650驱动开发中常见的I2C通信失败问题与调试方法

AIP650驱动开发实战&#xff1a;I2C通信故障排查与深度调试手册 当你在深夜调试AIP650驱动的数码管显示&#xff0c;却发现屏幕一片漆黑或是乱码飞舞时&#xff0c;那种挫败感我深有体会。这不是一篇照本宣科的技术文档&#xff0c;而是凝结了多次项目实战中踩坑经验的调试指南…...

MySQL 查询缓存与执行计划交互机制

MySQL 查询缓存与执行计划交互机制探析 在数据库性能优化中&#xff0c;MySQL的查询缓存与执行计划是两大关键机制。查询缓存通过存储SELECT语句及其结果集&#xff0c;减少重复计算&#xff1b;而执行计划则是优化器生成的查询路径&#xff0c;直接影响查询效率。两者的交互机…...

圆圈中最后剩下的数字-C++

分享一个大牛的人工智能教程。零基础&#xff01;通俗易懂&#xff01;风趣幽默&#xff01;希望你也加入到人工智能的队伍中来&#xff01;请轻击人工智能教程https://www.captainai.net/troubleshooter // 面试题62&#xff1a;圆圈中最后剩下的数字 // 题目&#xff1a;0, 1…...

完整指南:如何使用GEMMA高效完成基因组关联分析

完整指南&#xff1a;如何使用GEMMA高效完成基因组关联分析 【免费下载链接】GEMMA Genome-wide Efficient Mixed Model Association 项目地址: https://gitcode.com/gh_mirrors/gem/GEMMA 如果你正在寻找一款能够快速处理大规模基因组数据&#xff0c;同时校正群体结构…...

解锁NVIDIA Profile Inspector全球影响力:多语言本地化架构深度解析

解锁NVIDIA Profile Inspector全球影响力&#xff1a;多语言本地化架构深度解析 【免费下载链接】nvidiaProfileInspector 项目地址: https://gitcode.com/gh_mirrors/nv/nvidiaProfileInspector 掌握显卡配置工具国际化&#xff0c;让全球玩家享受专业级图形优化体验 …...