【C语言】队列的实现(数据结构)

前言:

相信大家在生活中经常排队买东西,今天学习的队列就跟排队买东西一样,先来买的人就买完先走,也就是先进先出。废话不多说,进入咱们今天的学习吧。

目录

前言:

队列的概念

队列的实现

队列的定义

入队列

判空

出队列

队列初始化

获取队头数据

获取队尾数据

获取有效数量

队列销毁

队列详细代码

头文件Queue.h

函数文件Queue.c

测试Text.cjt


队列的概念

想要去实现队列,首先要了解队列的结构和内容。

队列有队头个队尾,出队列只能在队头出(头删),入队列只能在队尾入(尾插)。

队列:只允许在一端进行插入数据操作,在另一端进行删除数据操作的特殊线性表,队列具有先
进先出FIFO(First In First Out)。
入队列:进行插入操作的一端称为队尾。
出队列:进行删除操作的一 端称为队头。

队列的实现

前面我们学习了单链表的基本实现,如果掌握了单链表,那么队列的实现就轻而易举了。

因为队列的本质是先进先出,也就是和头节点删除一样,如果我们利用顺序表的结构来实现队列,删掉一个头节点,后面的数据都要往前移动一位,时间复杂度为O(N),所以我们利用单链表来实现队列,既方便又简洁。

队列的定义

我们既然利用单链表来实现队列,那么一个节点里面就会包含一个指向下一个节点的指针和我们要存放的数据。

typedef int QDataType;
//表示队列节点的定义
typedef struct QListNode
{struct QListNode* next;QDataType val;
}QNode;

这里将int 定义为 QDataType 方便数据类型的更改。

在实现单链表的时候我们只需要了一个头指针,实现队列的时候我们需要加上一个尾指针,这样方便我们找到头尾数据,同时还可以避免遍历找尾,提高的算法的效率。

更重要的是,在的单链表实现中我们的头删,头插都用到了二级指针,考虑到链表为空,只有二级指针才能更好的方便改变指向节点指针的值,但队列我们增加的一个尾指针的话,改变头节点里面的内容就不需要传二级指针了。

//队列的结构
typedef struct Queue
{QNode* head;QNode* tail;int size;
}Queue;

后面我们要计算队列中有效数据的元素个数,所以我们加一个size进去。

入队列

数据插入队列的时候,我们要考虑队列为空的情况,最后要注意size要++!!!

//队尾入队列
void QueuePush(Queue* q, QDataType x)
{assert(q);QNode* newnode = (QNode*)malloc(sizeof(QNode));if (newnode == NULL)//考虑newnode为空的情况{printf("malloc fail!!!");exit(1);}newnode->next = NULL;newnode->val = x;if (QueueEmpty(q))//队列为空{q->head = q->tail = newnode;}else {           //队列不为空q->tail->next = newnode;q->tail = newnode;}q->size++;//插入数据之后不要忘了把size++
}

判空

如果为空则返回非零结果,如果非空则返回0

int QueueEmpty(Queue* q)
{assert(q);return q->size == 0;
}

出队列

这里也要注意,如果只有一个节点的时候,q->head = NULL的同时要保证q->tail也要为空,不然就会出现野指针的情况!

//队头出队列
void QueuePop(Queue* q)
{assert(q);assert(q->head);if (q->head->next == NULL){free(q->head);q->head = q->tail = NULL;}else {QNode* next = q->head->next;free(q->head);q->head = next;}q->size--;
}

一定要写assert(q->head);这样就保证下面的q->head->next没有问题,这样写是为了防止空指针被解引用!

队列初始化

void QueueInit(Queue* q)
{assert(q);q->head = q->tail = NULL;q->size = 0;
}

获取队头数据

QDataType QueueFront(Queue* q)
{assert(q);assert(q->head);return q->head->val;
}

获取队尾数据

QDataType QueueBack(Queue* q)
{assert(q);assert(q->tail);return q->tail->val;
}

这是也要注意要对q->head和q->tail进行断言。

获取有效数量

int QueueSize(Queue* q)
{assert(q);return q->size;
}

队列销毁

void QueueDestroy(Queue* q)
{assert(q);QNode* pcur = q->head;while (pcur){QNode* next = pcur->next;free(q->head);pcur = next;}q->head = q->tail = NULL;q->size = 0;
}

在while循环里面要注意将pcur的下一个节点用新指针保存起来,这样更方便我们去释放空间。

队列详细代码

头文件Queue.h

#include<stdio.h>
#include<stdbool.h>
#include<stdlib.h>
#include<assert.h>typedef int QDataType;
//表示队列节点的定义
typedef struct QListNode
{struct QListNode* next;QDataType val;
}QNode;
//队列的结构
typedef struct Queue
{QNode* head;QNode* tail;int size;
}Queue;//初始化队列
void QueueInit(Queue* q);
//队尾入队列
void QueuePush(Queue* q,QDataType x);
//队头出队列
void QueuePop(Queue* q);
//获取队列头部元素
QDataType QueueFront(Queue* q);
//获取队列尾部元素
QDataType QueueBack(Queue* q);
//获取队列中有效元素个数
int QueueSize(Queue* q);
//检验队列是否为空,如果为空则返回非零结果,如果非空则返回0
int QueueEmpty(Queue* q);
//销毁队列
void QueueDestroy(Queue* q);

函数文件Queue.c

#include"Queue.h"
//初始化队列
void QueueInit(Queue* q)
{assert(q);q->head = q->tail = NULL;q->size = 0;
}
//队尾入队列
void QueuePush(Queue* q, QDataType x)
{assert(q);QNode* newnode = (QNode*)malloc(sizeof(QNode));if (newnode == NULL)//考虑newnode为空的情况{printf("malloc fail!!!");exit(1);}newnode->next = NULL;newnode->val = x;if (QueueEmpty(q))//队列为空{q->head = q->tail = newnode;}else {           //队列不为空q->tail->next = newnode;q->tail = newnode;}q->size++;//插入数据之后不要忘了把size++
}//队头出队列
void QueuePop(Queue* q)
{assert(q);if (q->head->next == NULL){free(q->head);q->head = q->tail = NULL;}else {QNode* next = q->head->next;free(q->head);q->head = next;}q->size--;
}
//获取队列头部元素
QDataType QueueFront(Queue* q)
{assert(q);assert(q->head);return q->head->val;
}
//获取队列尾部元素
QDataType QueueBack(Queue* q)
{assert(q);assert(q->tail);return q->tail->val;
}
//获取队列中有效元素个数
int QueueSize(Queue* q)
{assert(q);return q->size;
}
//检验队列是否为空,如果为空则返回非零结果,如果非空则返回0
int QueueEmpty(Queue* q)
{assert(q);return q->size == 0;
}
//销毁队列
void QueueDestroy(Queue* q)
{assert(q);QNode* pcur = q->head;while (pcur){QNode* next = pcur->next;free(q->head);pcur = next;}q->head = q->tail = NULL;q->size = 0;
}

测试Text.cjt

#include"Stack.h"
#include"Queue.h"
void QueueText()
{Queue q;QueueInit(&q);//传地址过去才能影响结构体里面的值QueuePush(&q, 1);QueuePush(&q, 2);QueuePush(&q, 3);QueuePush(&q, 4);while (!QueueEmpty(&q)){printf("%d", QueueFront(&q));QueuePop(&q);printf("\n");}QueueDestroy(&q);
}
int main()
{QueueText();return 0;
}


今天的分享就到这啦!如果大家有所感悟或者见解多多分享哈。

记得三连哦,有不好的地方欢迎大佬指正!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/51299.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

DDR等长,到底长度差多少叫等长?

DDR4看这一篇就够了 - 知乎 (zhihu.com) 【全网首发】DDR4 PCB设计规范&设计要点PCB资源PCB联盟网 - Powered by Discuz! (pcbbar.com) 终于看到较为权威的DDR4等长要求了: !!!! 依据这个要求&#xff0c;H616项目的等长线不合格&#xff1a;

Vue的指令语法、双向绑定、el和data的另一种写法、MVVM模型

目录 1. 指令语法1.1 双向绑定 2. el和data的另一种写法3. MVVM模型 1. 指令语法 用于解析标签&#xff08;包括&#xff1a;标签属性、标签体内容、绑定事件…&#xff09;。Vue中有很多的指令&#xff0c;且形式都是&#xff1a;v-xxxx&#xff0c;此处我们只是拿v-bind举个…

C++第二十八弹---进一步理解模板:特化和分离编译

✨个人主页&#xff1a; 熬夜学编程的小林 &#x1f497;系列专栏&#xff1a; 【C语言详解】 【数据结构详解】【C详解】 目录 1. 非类型模板参数 2. 模板的特化 2.1 概念 2.2 函数模板特化 2.3 类模板特化 2.3.1 全特化 2.3.2 偏特化 2.3.3 类模板特化应用示例 3. …

前端学习7——自学习梳理

​​​​​​jQuery 教程 | 菜鸟教程jQuery 教程 jQuery 是一个 JavaScript 库。 jQuery 极大地简化了 JavaScript 编程。 jQuery 很容易学习。 本章节的每一篇都包含了在线实例 通过本站的在线编辑器&#xff0c;你可以在线运行修改后的代码&#xff0c;并查看运行结果。 实例…

Redis的事务_乐观锁与悲观锁

目录 一 Redis事务-介绍 二 事务的基本操作 三 Redis事务-乐观锁与悲观锁 四 Redis事务-特性 一 Redis事务-介绍 Redis事务可以一次执行多个命令&#xff0c;本质是一组命令的集合&#xff0c;一个事务中的所有命令都会序列化&#xff0c;按顺序的串行化执行&#xff0c;而…

【开源库学习】libodb库学习(十二)

13 数据库架构演变 当我们添加新的持久类或更改现有的持久类时&#xff0c;例如&#xff0c;通过添加或删除数据成员&#xff0c;存储新对象模型所需的数据库模式也会发生变化。同时&#xff0c;我们可能有包含现有数据的现有数据库。如果应用程序的新版本不需要处理旧数据库&a…

使用 XRDP 远程linux主机

一、简介 XRDP是一个开源的远程桌面协议&#xff08;Remote Desktop Protocol,RDP&#xff09;服务器&#xff0c;采用的是标准的RDP。 官网地址&#xff1a;https://www.xrdp.org/ github地址&#xff1a; https://github.com/neutrinolabs/xrdp/releases XRDP也是C/S架构&…

Springboot 整合Elasticsearch

1 java操作ES方式 1.1 操作ES 9300端口(TCP) 但开发中不在9300进行操作 ES集群节点通信使用的也是9300端口如果通过9300操作ES&#xff0c;需要与ES建立长连接 可通过引入spring-data-elasticsearch:transport-api.jar不在9300操作原因&#xff1a;1.springboot版本不同&…

springboot电影院线上购票系统-计算机毕业设计源码68220

目录 摘要 1 绪论 1.1 选题背景与意义 1.2国内外研究现状 1.3论文结构与章节安排 2系统分析 2.1.1 技术可行性分析 2.1.2 经济可行性分析 2.1.3 法律可行性分析 2.2 系统流程分析 2.2.1 添加信息流程 2.2.2 修改信息流程 2.2.3 删除信息流程 2.3 系统功能分析 2.…

起薪4万的AI产品经理自述:一个算法模型是怎么训练出来的?

起薪4万的AI产品经理自述&#xff1a;一个算法模型是怎么训练出来的&#xff1f; 这篇文章&#xff0c;我们继续来讲模型构建的其他 3 个环节&#xff1a;模型训练、模型验证和模型融合。 模型训练 模型训练是通过不断训练、验证和调优&#xff0c;让模型达到最优的一个过程。…

【人工智能】穿越科技迷雾:解锁人工智能、机器学习与深度学习的奥秘之旅

文章目录 前言一、人工智能1. 人工智能概述a.人工智能、机器学习和深度学习b.人工智能发展必备三要素c.小案例 2.人工智能发展历程a.人工智能的起源b.发展历程 3.人工智能的主要分支 二、机器学习1.机器学习工作流程a.什么是机器学习b.机器学习工作流程c.特征工程 2.机器学习算…

基于GEC6818开发板+Linux+Qt设计的智能养老院出入管理系统

一、前言 1.1 项目介绍 【1】项目功能介绍 随着我国老龄化进程的加快,养老问题日益突出,如何有效保障老年人的生活质量与安全成为社会关注的重点。智能化、信息化技术的发展为解决这一问题提供了新的思路和手段。基于Linux系统的智能养老院出入管理系统应运而生,为了实现…

Thinkphp仿华为商城源码/红色风格电脑手机数码商城系统网站源码

Thinkphp仿华为商城&#xff0c;主要实现了商品首页展示、用户意见、商品分类列表、商品搜索、商品详细展示、购物车、订单生成、在线付款、以及个人中心完善个人资料、用户修改收货地址、余额查询、消费查询、订单管理、商品评价、热销商品和最近商品浏览&#xff1b; 后台是…

大模型的架构演进史——为什么Decoder-Only成为最终的胜利者

文章目录 大模型的架构encoder onlydecoder nolyencoder-decoder为什么现在decoder-only为主流 大模型的架构 encoder only 使用encoder-only的模型主要的思路是通过编码器&#xff0c;将大量文本、时序数据等资料进行编码、压缩&#xff0c;达到进一步抽象理解输入数据的能力…

【JavaScript】函数的动态传参

Javacript&#xff08;简称“JS”&#xff09;是一种具有函数优先的轻量级&#xff0c;解释型或即时编译型的编程语言。虽然它是作为开发Web页面的脚本语言而出名&#xff0c;但是它也被用到了很多非浏览器环境中&#xff0c;JavaScript基于原型编程、多范式的动态脚本语言&…

Python接口自动化测试框架(实战篇)-- 数据库操作MySQL

文章目录 一、前言二、数据库什么是数据验证为什么需要操作数据库做数据验证?现在回到怎样做数据验证的问题上来 三、[PyMSQL](https://pypi.org/project/pymssql/)pymysql如何操作数据库实际应用 四、总结 一、前言 说起数据库的操作&#xff0c;咱们应该保持一颗敬畏的心&a…

Ubuntu安装terminator教程

Terminator 是一个高级的终端仿真器,专为 Linux 和 Unix 系统设计。它的主要特点是提供了丰富的多窗口和多标签功能,使用户能够在一个窗口中管理多个终端会话。这对于系统管理员、开发人员以及需要同时运行多个命令行任务的用户来说,极为方便。 一、安装 1、更新包 sudo a…

vue项目启动报错 vue与vue-template-compiler版本不一致

出现错误 Vue packages version mismatch: vue2.6.12 (/Users/work_ws/project/my/astar-education/astar-education-ui/node_modules/vue/dist/vue.runtime.common.js)vue-template-compiler2.6.13 (/Users/work_ws/project/my/astar-education/astar-education-ui/node_mod…

图中的最短环

2608. 图中的最短环 现有一个含 n 个顶点的 双向 图&#xff0c;每个顶点按从 0 到 n - 1 标记。图中的边由二维整数数组 edges 表示&#xff0c;其中 edges[i] [ui, vi] 表示顶点 ui 和 vi 之间存在一条边。每对顶点最多通过一条边连接&#xff0c;并且不存在与自身相连的顶…