【C语言】实现队列


目录

(一)队列

 (二)头文件

(三) 功能实现

(1)初始化

(2) 销毁队列

(3) 入队

(4)出队 

(5)得到队头的数据 

(6)得到队尾的数据

(7)判断队列是否为空

(8)得到队列内数据个数 


正文开始:

(一)队列

        队列是一种数据结构,其中元素按照先进先出(FIFO)的顺序进行操作。在队列中,新元素被插入到队列的尾部,而删除元素发生在队列的头部。

        队列可以用于处理任务或事件的顺序,例如处理请求、消息传递等。可以将任务或事件放入队列的尾部,并按照它们被放入队列的顺序进行处理。

        队列的常见操作包括入队(向队列尾部添加元素)、出队(从队列头部删除元素)、获取队列头部的元素(但不删除)、判断队列是否为空等。

        队列可以用数组或链表实现。使用数组实现的队列称为顺序队列,使用链表实现的队列称为链式队列。顺序队列的插入和删除操作会涉及元素的移动,而链式队列不需要移动元素,因此插入和删除操作的时间复杂度都是O(1)。

 (二)头文件

         队列可以使用链表实现,也可以使用顺序表实现,但是队列需要频繁的头删,顺序表的头删效率低,由于队列规定了队头出,队尾进,所以顺序表的随机访问功能在队列中用不到;而链表的头删与尾插效率高,适合实现队列,因此本文用链表实现队列。


         什么是SLT?

SLT库 

        STL(Standard Template Library)是C++的标准库,提供了一组通用数据结构和算法的模板,可以方便地用于各种应用程序的开发。

        STL包含了多个模块,其中最重要的被称为容器(Containers)、算法(Algorithms)和迭代器(Iterators)。

        容器模块包括了多种数据结构,如向量(vector)、链表(list)、队列(queue)、栈(stack)、集合(set)、映射(map)等。这些容器提供了不同的数据组织方式和操作,可以根据需要选择合适的容器进行数据存储和访问。

        算法模块包含了多种常用算法,如排序、查找、合并、遍历等。这些算法可以用于各种数据结构上,无需重复实现,只需直接调用相应的算法函数即可。

        迭代器模块提供了一种通用的访问容器元素的方式,通过迭代器可以遍历容器中的元素,并进行读取、修改等操作。迭代器相当于一个指针,可以指向容器中的某个位置,通过迭代器可以直接访问容器中的元素。

 

        本文根据Cpp的STL库来实现队列(Queue)的相关功能:包括队列初始化,销毁,向队列中插入数据(入队),删除数据(出队),得到队列的头数据(front),得到队列的尾数据(tail),判断队列是否为空,得到队列内数据个数等共八项功能接口。

这里不加解释的给出头文件,根据头文件来实现队列的具体功能:

#pragma once#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include<stdbool.h>/*		基于链表实现队列,入数据的为队尾,出数据的为队头*		顺序表实现队列头删效率低*		顺序表的随机访问队列中用不到*		所以选择用链表实现队列
*/
//队列存储数据类型
typedef int QueueDatatype;//队列的一个节点
typedef struct QueueNode
{QueueDatatype data;struct QueueNode* next;
}QNode;//一个队列
typedef struct Queue
{QNode* phead;//指向队列头的指针QNode* ptail;//指向队列尾的指针int size;    //队列内数据个数
}Queue;//初始化队列
void Qinit(Queue* pq);//销毁队列
void QDestroy(Queue* pq);//向队列插入数据
void Qpush(Queue* pq,QueueDatatype x);//删除队列的数据
void Qpop(Queue* pq);//得到front数据
QueueDatatype Qfront(Queue* pq);//得到tail数据
QueueDatatype Qback(Queue* pq);//判断队列是否为空
bool Qempty(Queue* pq);//得到队列内数据个数
int Qsize(Queue* pq);

(三) 功能实现

(1)初始化

队列初始化

        首先函数接收的指针不能是空指针(若是空,无法进行解引用操作),可以通过assert断言实现;

        将队列的头尾指针都置空,表示此时队列内没有任何数据,数据个数(size)置0;


//初始化队列
void Qinit(Queue* pq)
{assert(pq);pq->phead = pq->ptail = NULL;pq->size = 0;
}

(2) 销毁队列

销毁队列

        首先函数接收的指针不能是空指针(若是空,无法进行解引用操作),可以通过assert断言实现;

        创建pcur指针,遍历链表;

        创建next指针,保存下一个节点,防止释放此节点后,无法解引用找到下一个节点;

        最后,分别指向队头与队尾的phead与ptail指针要置空;


//销毁队列
void QDestroy(Queue* pq)
{assert(pq);QNode* pcur = pq->phead;while (pcur){QNode* next = pcur->next;free(pcur);pcur = next;}pq->ptail = pq->phead = NULL;
}

(3) 入队

入队

         首先函数接收的指针不能是空指针(若是空,无法进行解引用操作),可以通过assert断言实现;

        入队时,队列有两种状态:

        若队列为空(此时队头队尾都为空),让头指针和尾指针都指向新节点newnode;

        若队列不为空,执行尾插;

        不要忘记让队列的size++;


//向队列插入数据
void Qpush(Queue* pq, QueueDatatype x)
{assert(pq);//获取新节点QNode* newnode = (QNode*)malloc(sizeof(QNode));if (newnode == NULL){perror("malloc fail!");return;}newnode->data = x;newnode->next = NULL;//队列为空,此时队头队尾都为空if (pq->phead == NULL){assert(pq->ptail == NULL);//防止一个为NULL一个不为NULL的情况pq->phead = pq->ptail = newnode;}else//队列不为空,尾插{pq->ptail->next = newnode;pq->ptail = newnode;}//队列节点数加一pq->size++;
}

(4)出队 

出队

          首先函数接收的指针不能是空指针(若是空,无法进行解引用操作),可以通过assert断言实现;

        判断队列不为空,通过assert断言实现;

        执行头删,创建next指针保存phead的next节点,freephead后,通过next找到新的头节点;

        不要忘记队列的size--;


//删除队头的数据
void Qpop(Queue* pq)
{assert(pq);assert(!Qempty(pq));QNode* next = pq->phead->next;free(pq->phead);pq->phead = next;pq->size--;
}

        

(5)得到队头的数据 

        首先函数接收的指针不能是空指针(若是空,无法进行解引用操作),可以通过assert断言实现;

        直接返回即可;


//得到front数据
QueueDatatype Qfront(Queue* pq)
{assert(pq);return pq->phead->data;
}

 

(6)得到队尾的数据

 

        首先函数接收的指针不能是空指针(若是空,无法进行解引用操作),可以通过assert断言实现;

        直接返回即可;


//得到tail数据
QueueDatatype Qback(Queue* pq)
{assert(pq);return pq->ptail->data;
}

 

(7)判断队列是否为空

         返回判断表达式的结果;(若队列为空,返回真(1),否则返回假(0))

 

/判断队列是否为空
bool Qempty(Queue* pq)
{//队列为空,返回真;非空,返回假return pq->size == 0;
}

 

(8)得到队列内数据个数 

         直接返回队列的size即可;


//得到队列内数据个数
int Qsize(Queue* pq)
{return pq->size;
}


完 ~

未经作者同意禁止转载

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

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

相关文章

spring boot 使用AOP实现是否已登录检测

前后端分离的开发中&#xff0c;用户http请求应用服务的接口时, 如果要求检测该用户是否已登录。可以实现的方法有多种&#xff0c; 本示例是通过aop 的方式实现&#xff0c;简单有效。 约定&#xff1a;前端http的post 请求 export async function request(url,data) {const …

leetcode77组合 剪枝条件详细解释

题目&#xff1a;77. 组合 - 力扣&#xff08;LeetCode&#xff09; 题解&#xff1a;力扣&#xff08;LeetCode&#xff09;官网 - 全球极客挚爱的技术成长平台 思路来自代码随想录&#xff1a; 带你学透回溯算法-组合问题&#xff08;对应力扣题目&#xff1a;77.组合&…

TCP/IP五层各层协议详解

TCP/IP协议栈是网络通信的基础&#xff0c;它由五层协议组成&#xff0c;分别是物理层、数据链路层、网络层、传输层和应用层。以下是对各层协议的详细解释&#xff1a; 1. 物理层&#xff08;Physical Layer&#xff09;&#xff1a;该层负责传输比特流&#xff0c;主要定义传…

centos7系列:出现ZooKeeper JMX enabled by default这种错误的解决方法

出现ZooKeeper JMX enabled by default这种错误的解决方法 前言一 问题描述二 解决方法2.1 可能的原因分析2.2 小编的问题解决方法First&#xff1a;检查/etc/profile里面zookeeper的环境变量配置Second&#xff1a;检查 zookeeper/conf/zoo.cfg里面的dataDir的路径 总结 前言 …

Nginx七层负载均衡之动静分离

思路: servera:负载均衡服务器 serverb:静态服务器 serverc:动态服务器 serverd:默认服务器 servera(192.168.233.132): # 安装 Nginx 服务器 yum install nginx -y#关闭防火墙和selinux systemctl stop firewalld setenforce 0# 切换到 Nginx 配置文…

【Linux内核】从0开始入门Linux Kernel源码

&#x1f308; 博客个人主页&#xff1a;Chris在Coding &#x1f3a5; 本文所属专栏&#xff1a;[Linux内核] ❤️ 前置学习专栏&#xff1a;[Linux学习]从0到1 ⏰ 我们仍在旅途 ​ 目录 …

Python内置函数04——enumerate

文章目录 概述语法实例展示 概述 在Python中&#xff0c;enumerate()是一个很常用的内置函数。它的作用是将一个可迭代对象&#xff08;如列表、元组、字符串等&#xff09;组合为一个索引序列和元素序列的枚举对象。 语法 enumerate(iterable, start0) 其中&#xff0c;ite…

Midjourney绘图欣赏系列(五)

Midjourney介绍 Midjourney 是生成式人工智能的一个很好的例子&#xff0c;它根据文本提示创建图像。它与 Dall-E 和 Stable Diffusion 一起成为最流行的 AI 艺术创作工具之一。与竞争对手不同&#xff0c;Midjourney 是自筹资金且闭源的&#xff0c;因此确切了解其幕后内容尚不…

OSS业务存储适配器模式

流程 当我们配置了阿里云&#xff0c;腾讯云&#xff0c;minio等多个云存储厂商的业务代码时&#xff0c;如果我们要修改具体使用哪一种厂商的云存储&#xff0c;那么我们的controller层和service层就会需要改变业务代码&#xff1b;此时我们可以使用适配器模式来进行松耦合—…

WebSocket 详细教程

WebSocket 是一种网络通信协议&#xff0c;它实现了客户端与服务器之间的全双工通信。与传统的 HTTP 协议不同&#xff0c;WebSocket 允许服务器主动向客户端发送消息&#xff0c;这对于实时应用&#xff08;如在线聊天、股票交易、游戏等&#xff09;来说非常重要。 1. 工作原…

Leetcode 11-15题

盛最多雨水的容器 数组的第 i i i个数字表示这个位置隔板的高度&#xff0c;选择哪两块板子可以装最多的水&#xff0c;返回可以存储的最大水量。 有一种双指针的贪心策略&#xff1a;如果左边的指针所在的挡板低&#xff0c;就将左边的指针右移&#xff0c;否则将右边的指针左…

MATLAB知识点:nchoosek函数(★★★☆☆)用来计算组合数,也能返回从向量v中抽取k个元素的所有组合

讲解视频&#xff1a;可以在bilibili搜索《MATLAB教程新手入门篇——数学建模清风主讲》。​ MATLAB教程新手入门篇&#xff08;数学建模清风主讲&#xff0c;适合零基础同学观看&#xff09;_哔哩哔哩_bilibili 节选自第3章&#xff1a;课后习题讲解中拓展的函数 在讲解第三…

算法训练营day28(补), 贪心算法2

//122. 买卖股票的最佳时机 II func maxProfit(prices []int) int { result : 0 //利润总和 for i : 1; i < len(prices); i { if prices[i]-prices[i-1] > 0 { result result (prices[i] - prices[i-1]) } } return result } //55. 跳跃游戏 func canJump(nums []…

模型 4E(交换、体验、随处、传教)理论

系列文章 分享 模型&#xff0c;了解更多&#x1f449; 模型_总纲目录。重在提升认知。聚焦体验营销。 1 模型 4E(交换、体验、随处、传教)理论的应用 1.1 4E 理论在软件产品营销中的应用 某软件公司利用 4E 理论提升软件产品的市场占有率。具体如下&#xff1a; Exchange&a…

人工智能学习与实训笔记(四):神经网络之NLP基础—词向量

人工智能专栏文章汇总&#xff1a;人工智能学习专栏文章汇总-CSDN博客 本篇目录 四、自然语言处理 4.1 词向量 (Word Embedding) 4.1.1 词向量的生成过程 4.1.2 word2vec介绍 4.1.3 word2vec&#xff1a;skip-gram算法的实现 4.2 句向量 - 情感分析 4.2.1 LSTM (Long S…

C语言之日历问题

一、代码展示 #include<stdio.h> int leapyear(int year)//判断是不是闰年函数 {if (year % 4 0 && year % 100 ! 0 || year % 400 0)return 1;elsereturn 0; } int days(int year, int month, int* day)//判断一个月有几天 {if (month ! 2)return day[month…

7.JS里表达式,if条件判断,三元运算符,switch语句,断点调试

表达式和语句的区别 表达式就是可以被求值的代码比如什么a 1 语句就是一段可以执行的代码比如什么if else 直接给B站的黑马程序员的老师引流一波总结的真好 分支语句 就是基本上所有的语言都会有的if else 语句就是满足不同的条件执行不同的代码&#xff0c;让计算机有条件…

【Java程序员面试专栏 Java领域】Java虚拟机 核心面试指引

关于Java 虚拟机部分的核心知识进行一网打尽,主要包括Java虚拟机的内存分区,执行流程等,通过一篇文章串联面试重点,并且帮助加强日常基础知识的理解,全局思维导图如下所示 JVM 程序执行流程 包括Java程序的完整执行流程,以及Javac编译,JIT即时编译 Java程序的完整执…

C++抽象类、纯虚函数和接口

在C中&#xff0c;抽象类是一种特殊的类&#xff0c;旨在作为其他类的基类使用。它定义了一组接口&#xff0c;派生类应该实现这些接口。 抽象类的主要特征 至少包含一个纯虚函数&#xff0c;不能被直接实例化&#xff0c;为派生类提供基础结构 纯虚函数&#xff08;Pure Vi…

会声会影2024新功能及剪辑视频步骤教程

会声会影2024的新功能主要包括&#xff1a; 全新的标题动态与特效&#xff1a;用户可以为文字标题指定进入、中场和退出的不同动态效果&#xff0c;比如闪现进入、中场弹跳和淡出退出等&#xff0c;让文字标题更具动感。此外&#xff0c;还新增了多个标题特效&#xff0c;包括…