C++11 数据结构5 队列的概念,队列的顺序存储,实现,测试

一,队列的概念

队列是一种特殊的受限制的线性表。  

队列(queue)是只允许在一端进行插入操作,而在另一端进行删除操作的线性表。

队列是一种先进先出的t(First In First Out)的线性表,简称FIFO。允许插入的一端为队尾,允许删除的一端为队头。队列不允许在中间部位进行操作!假设队列是q=(a1,a2,……,an),那么a1就是队头元素,而an是队尾元素。这样我们就可以删除时,总是从a1开始,而插入时,总是在队列最后。这也比较符合我们通常生活中的习惯,排在第一个的优先出列,最后来的当然排在队伍最后。如下图:

二,队列的顺序存储

那么如果用数组来模拟队列,情况说明如下,我们这里采用 尾部插入,头部删除的case进行处理

三,  队列顺序存储的代码实现

#ifndef __005SEQQUEUE_H__#define __005SEQQUEUE_H__//这两个是要给 所有人公开的
typedef void SeqQueueNode;
typedef void SeqQueue;//对外提供的方法//初始化队列,要动态的创建SeqQueue,根据user设定的大小创建
//int stacksize ,表示user 要创建队列的大小
//创建失败返回NULL
SeqQueue* createSeqQueue(int queuesize);//入队列 ,给队列的头部插入一个元素,插入点是在数组的尾部
//参数queue 表示要插入的栈
//参数 seqQueueNode 表示要插入的 节点
//成功 返回 1
//失败 返回<0
int push_SeqQueue(SeqQueue* queue, SeqQueueNode * seqQueueNode);//出队列 将队列的头部的第一个元素删除,删除点是在数组的头部
//参数stack 表示要删除第一个元素的栈
//成功 返回 1
//失败 返回<0
//说明,最开始的时候,让删除栈顶元素,返回int,但是这个设计是不合理的。
//因为假设上层是Teacher,这个Teacher里的元素有 char *,char**,且这两个空间也是malloc的,那么上层需要释放这两个malloc出来的元素。
//这意味着我们需要将 pop_SeqStack中的元素返回上去,上层才有机会释放,底层怎么知道上层搞的是个啥存的?因此一定要给上层,让上层去释放。//出队列 将队列的头部的第一个元素删除,删除点是在数组的头部
//参数seqqueue 表示要删除第一个元素的队列
//成功 返回 删除的第一个元素
//失败 返回 NULL
SeqQueueNode* pop_SeqQueue(SeqQueue* seqqueue);//返回队列元素,将队列头部的第一个元素返回
//失败返回NULL
//成功返回节点
SeqQueueNode* top_SeqQueue(SeqQueue* seqqueue);//返回队列大小
//成功 返回 队列的大小
//失败 返回<0
int size_SeqQueue(SeqQueue* seqqueue);//返回user对队列分配的大小
//成功 返回 队列的大小
//失败 返回<0 
int capacity_SeqQueue(SeqQueue* seqqueue);//判断队列是否为空
//成功 返回1 表示队列为空 
//成功 返回0 表示队列不为空
//失败 返回-1 表示该函数执行的时候有问题
int isEmpty_SeqQueue(SeqQueue* seqqueue);//销毁队列
//成功 返回1 表示成功销毁队列 
//失败 返回-1 表示该函数执行的时候有问题
int Destory_SeqQueue(SeqQueue* seqqueue);#endif

#include "005seqqueue.h"
#include "stdlib.h"
#include "stdio.h"
#include "string.h"//栈的内部结构,不用写在.h文件中,一会要移动位置
typedef struct SeqQueue {//队列中的数组,存储的是数据的指针,假设我们的数据是Teacher,那么arr[0] 中的数据就应该是&Tea1,//也就是说,这是一个数组,数组的每一个成员里面都存放的是指针。//本质上是一个  void * arr[], 也可以看成是 int * arr[],因为实际上放的就是 Teacher的指针 SeqQueueNode **data;int m_QueueSize;//队列的实际大小int m_QueueCapacity;//队列的总大小,也就是user给定的大小
}TSeqQueue;//对外提供的方法//初始化队列,要动态的创建SeqQueue,根据user设定的大小创建
//int stacksize ,表示user 要创建队列的大小
//创建失败返回NULL
SeqQueue* createSeqQueue(int queuesize) {TSeqQueue* ss = NULL;ss = (TSeqQueue*)malloc(sizeof(TSeqQueue));if (ss == NULL) {printf("createSeqQueue func error\n");return ss;}memset(ss, 0, sizeof(TSeqQueue));ss->m_QueueSize = 0;ss->m_QueueCapacity = queuesize;ss->data = (SeqQueueNode**)malloc(sizeof(SeqQueueNode *) * queuesize);if (ss->data == NULL) {printf("createSeqQueue func error ss->data == NULL \n");return NULL;}memset(ss->data, 0, sizeof(ss->data));return ss;
}//入队列 ,给队列的头部插入一个元素,插入点是在数组的尾部
//参数queue 表示要插入的栈
//参数 seqQueueNode 表示要插入的 节点
//成功 返回 1
//失败 返回<0
int push_SeqQueue(SeqQueue* queue, SeqQueueNode * seqQueueNode) {int ret = 1;if (queue == NULL) {ret = -1;printf("push_SeqQueue func error because stack==NULL ret=-1 and return\n");return ret;}if (seqQueueNode == NULL) {ret = -2;printf("push_SeqQueue func error because seqQueueNode==NULL ret=-2 and return\n");return ret;}TSeqQueue* st = (TSeqQueue*)queue;if (st->m_QueueCapacity == st->m_QueueSize) {ret = -3;printf("push_SeqQueue func error because st->m_StackCapccity == st->m_StackSize ret = -3 and return st->m_StackSize = %d, st->m_StackCapccity = %d\n",st->m_QueueSize,st->m_QueueCapacity);return ret;}//前面检查都完毕了,到这里就真的可以插入了,实行的是尾插法st->data[st->m_QueueSize] = seqQueueNode;st->m_QueueSize++;return ret;
}//出队列 将队列的头部的第一个元素删除,删除点是在数组的头部
//参数stack 表示要删除第一个元素的栈
//成功 返回 1
//失败 返回<0
//说明,最开始的时候,让删除栈顶元素,返回int,但是这个设计是不合理的。
//因为假设上层是Teacher,这个Teacher里的元素有 char *,char**,且这两个空间也是malloc的,那么上层需要释放这两个malloc出来的元素。
//这意味着我们需要将 pop_SeqStack中的元素返回上去,上层才有机会释放,底层怎么知道上层搞的是个啥存的?因此一定要给上层,让上层去释放。//出队列 将队列的头部的第一个元素删除,删除点是在数组的头部
//参数seqqueue 表示要删除第一个元素的队列
//成功 返回 删除的第一个元素
//失败 返回 NULL
SeqQueueNode* pop_SeqQueue(SeqQueue* seqqueue) {SeqQueueNode* ret = NULL;if (seqqueue == NULL) {ret = NULL;printf("pop_SeqQueue func error because stack==NULL and return\n");return ret;}TSeqQueue * tq = (TSeqQueue *)seqqueue;if (tq->m_QueueSize == 0) {ret = NULL;printf("pop_SeqQueue func error because tq->m_QueueSize == 0 and return\n");return ret;}//执行到这里,说明可以删除ret = tq->data[0];//这里有移动的操作。因为删除的是 数组的第一个元素for (int i = 0; i < tq->m_QueueSize; ++i) {tq->data[i] = tq->data[i + 1];}tq->m_QueueSize--;return ret;
}//返回队列元素,将队列头部的第一个元素返回
//失败返回NULL
//成功返回节点
SeqQueueNode* top_SeqQueue(SeqQueue* seqqueue) {SeqQueueNode* ret = NULL;if (seqqueue == NULL) {ret = NULL;printf("top_SeqQueue func error because stack==NULL and return\n");return ret;}TSeqQueue * tq = (TSeqQueue *)seqqueue;if (tq->m_QueueSize == 0) {ret = NULL;printf("top_SeqQueue func error because tq->m_QueueSize == 0 and return\n");return ret;}//执行到这里,说明队列是有元素的ret = tq->data[0];return ret;
}//返回队列大小
//成功 返回 队列的大小
//失败 返回<0
int size_SeqQueue(SeqQueue* seqqueue){int ret = 0;if (seqqueue == NULL) {ret = -1;printf("size_SeqQueue func error because stack==NULL and return\n");return ret;}TSeqQueue * tq = (TSeqQueue *)seqqueue;return tq->m_QueueSize;}//返回user对队列分配的大小
//成功 返回 队列的大小
//失败 返回<0 
int capacity_SeqQueue(SeqQueue* seqqueue) {int ret = 0;if (seqqueue == NULL) {ret = -1;printf("capacity_SeqQueue func error because stack==NULL and return\n");return ret;}TSeqQueue * tq = (TSeqQueue *)seqqueue;return tq->m_QueueCapacity;
}//判断队列是否为空
//成功 返回1 表示队列为空 
//成功 返回0 表示队列不为空
//失败 返回-1 表示该函数执行的时候有问题
int isEmpty_SeqQueue(SeqQueue* seqqueue) {int ret = 0;if (seqqueue == NULL) {ret = -1;printf("isEmpty_SeqQueue func error because stack==NULL and return\n");return ret;}TSeqQueue * tq = (TSeqQueue *)seqqueue;if (tq->m_QueueSize ==0) {ret = 1;}else {ret = 0;}return ret;
}//销毁队列
//成功 返回1 表示成功销毁队列 
//失败 返回-1 表示该函数执行的时候有问题
int Destory_SeqQueue(SeqQueue* seqqueue) {int ret = 1;if (seqqueue == NULL) {ret = -1;printf("isEmpty_SeqQueue func error because stack==NULL and return\n");return ret;}TSeqQueue * tq = (TSeqQueue *)seqqueue;if (tq->data!=NULL) {free(tq->data);}tq->data = NULL;free(tq);seqqueue = NULL;return ret;}

#define _CRT_SECURE_NO_WARNINGS
#define _CRTDBG_MAP_ALLOC
#include "iostream"
#include <stdio.h>
#include <stdlib.h>extern "C" {
#include "005seqqueue.h"
}typedef struct Teacher {int age;char name[128];char *othername;char **stuname; //一个老师下面有5个学生
}Teacher;int main() {_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);//程序退出时检测内存泄漏并显示到“输出”窗口int ret = 0;//初始化队列,要动态的创建SeqStack,根据user设定的大小创建
//int stacksize ,表示user 要创建栈的大小
//创建失败返回NULLSeqQueue* seqqueue = createSeqQueue(1024);if (seqqueue == NULL) {ret = -1;printf("func createSeqQueue error because seqstack = NULL return ret =-1\n");return ret;}ret = isEmpty_SeqQueue(seqqueue);printf("isEmpty_SeqQueue = ret %d\n", ret);ret = size_SeqQueue(seqqueue);printf("size_SeqQueue = ret %d\n", ret);ret = capacity_SeqQueue(seqqueue);printf("capacity_SeqQueue = ret %d\n", ret);Teacher tea1;tea1.age = 20;strcpy(tea1.name, (const char*)"tea1");tea1.othername = (char *)malloc(sizeof(char) * 128);memset(tea1.othername, 0, sizeof(char) * 128);strcpy(tea1.othername, (const char*)"tea1othername");tea1.stuname = (char **)malloc(sizeof(char *) * 5);memset(tea1.stuname, 0, sizeof(char *) * 5);for (size_t i = 0; i < 5; i++){tea1.stuname[i] = (char *)malloc(sizeof(char) * 128);//每个学生名字也有128个字符memset(tea1.stuname[i], 0, sizeof(char) * 128);sprintf(tea1.stuname[i], "tea1stuname%d", i + 1);}Teacher tea2;tea2.age = 22;strcpy(tea2.name, (const char*)"tea2");tea2.othername = (char *)malloc(sizeof(char) * 128);memset(tea2.othername, 0, sizeof(char) * 128);strcpy(tea2.othername, (const char*)"tea2othername");tea2.stuname = (char **)malloc(sizeof(char *) * 5);memset(tea2.stuname, 0, sizeof(char *) * 5);for (size_t i = 0; i < 5; i++){tea2.stuname[i] = (char *)malloc(sizeof(char) * 128);//每个学生名字也有128个字符memset(tea2.stuname[i], 0, sizeof(char) * 128);sprintf(tea2.stuname[i], "tea2stuname%d", i + 1);}Teacher tea3;tea3.age = 33;strcpy(tea3.name, (const char*)"tea3");tea3.othername = (char *)malloc(sizeof(char) * 128);memset(tea3.othername, 0, sizeof(char) * 128);strcpy(tea3.othername, (const char*)"tea3othername");tea3.stuname = (char **)malloc(sizeof(char *) * 5);memset(tea3.stuname, 0, sizeof(char *) * 5);for (size_t i = 0; i < 5; i++){tea3.stuname[i] = (char *)malloc(sizeof(char) * 128);//每个学生名字也有128个字符memset(tea3.stuname[i], 0, sizeof(char) * 128);sprintf(tea3.stuname[i], "tea3stuname%d", i + 1);}ret = push_SeqQueue(seqqueue, &tea1);if (ret < 0) {printf("push_SeqQueue(seqqueue, (SeqStackNode * )&tea1) func error ret =%d \n", ret);return ret;}push_SeqQueue(seqqueue, &tea2);if (ret < 0) {printf("push_SeqQueue(seqqueue, (SeqStackNode * )&tea2) func error ret =%d \n", ret);return ret;}push_SeqQueue(seqqueue, &tea3);if (ret < 0) {printf("push_SeqQueue(seqqueue, (SeqStackNode * )&tea3) func error ret =%d \n", ret);return ret;}printf("-after-\n");ret = isEmpty_SeqQueue(seqqueue);printf("isEmpty_SeqQueue = ret %d\n", ret);ret = size_SeqQueue(seqqueue);printf("size_SeqQueue = ret %d\n", ret);ret = capacity_SeqQueue(seqqueue);printf("capacity_SeqQueue = ret %d\n", ret);while (size_SeqQueue(seqqueue) > 0) {Teacher * temptea = (Teacher *)top_SeqQueue(seqqueue);if (temptea == NULL) {printf("can not get find teacher\n");}printf("temptea->age = %d,temptea->name = %s,temptea->othername=%s\n",temptea->age,temptea->name,temptea->othername);for (size_t j = 0; j < 5; j++){printf("temptea->stuname[%d] = %s,  ",j, temptea->stuname[j]);}Teacher * deltea = (Teacher *)pop_SeqQueue(seqqueue);if (deltea == NULL) {printf("pop_SeqStack seqstack error\n");}if (deltea->othername != NULL) {free(deltea->othername);}if (deltea->stuname != NULL) {for (size_t i = 0; i < 5; i++){if (deltea->stuname[i] != NULL) {free(deltea->stuname[i]);}}free(deltea->stuname);deltea->stuname = NULL;}printf("\n");}printf("sss\n");//销毁栈//成功 返回1 表示成功销毁栈 //失败 返回-1 表示该函数执行的时候有问题ret = Destory_SeqQueue(seqqueue);return 0;}

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

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

相关文章

请编写函数fun,其功能是:将所有大于1小于整数m的非素数存入xx所指数组中,非素数的个数通过k传回。

本文收录于专栏:算法之翼 https://blog.csdn.net/weixin_52908342/category_10943144.html 订阅后本专栏全部文章可见。 本文含有题目的题干、解题思路、解题思路、解题代码、代码解析。本文分别包含C语言、C++、Java、Python四种语言的解法完整代码和详细的解析。 题干 请编…

NDK 基础(五)—— C++ 高级特性2

1、左值右值 在 C 中&#xff0c;左值&#xff08;lvalue&#xff09;和右值&#xff08;rvalue&#xff09;是用于描述表达式的术语&#xff0c;它们与赋值操作和内存中对象的生命周期有关。 **左值&#xff08;lvalue&#xff09;**是指可以出现在赋值操作符左侧的表达式&a…

商店数据(九)

目录 65.店铺入驻字段表 66.店铺分类表 67.店铺配置表 68.店铺快递公司关联表 69.店铺资料附加表 70.店铺入驻流程表 71.店铺运费模板表 72.消息类型表 65.店铺入驻字段表 CREATE TABLE wst_bases (id int(11) NOT NULL AUTO_INCREMENT COMMENT 自增id,flowld int(11)…

如何安全进行速卖通自养号测评操作?

对于新加入的卖家而言&#xff0c;进行销量测评显得尤为关键。速卖通平台上的新店往往难以获得活动的扶持&#xff0c;且初始流量相当有限。因此&#xff0c;开店的首要任务便是积极展开测评工作&#xff0c;努力积累初始的评论和销售记录。测评的益处颇为显著&#xff0c;它不…

SpringBoot项目启动,传参有哪些方式?

SpringBoot项目启动&#xff0c;传参有哪些方式&#xff1f; 1.Spring级别的参数 直接在启动 Spring Boot 应用的命令行中使用 -- 后跟参数名和值的方式来传递参数。 记住&#xff1a;一般是对于Spring Boot应用特有的配置参数&#xff0c;确保它们遵循Spring Boot的配置属性命…

【视频打架行为数据集】打斗场景视频数据集简要介绍

一、UBI-Fight&#xff08;异常事件检测数据集&#xff09; 介绍 UBI-Fights 数据集是一个独特的全新大型数据集&#xff0c;涉及特定的异常检测并仍然在打斗场景中提供广泛的多样性&#xff0c;该数据集包含 80 小时的视频&#xff0c;在帧级别进行了完全注释。由 1000 个视…

# 从浅入深 学习 SpringCloud 微服务架构(五)Consul(2)

从浅入深 学习 SpringCloud 微服务架构&#xff08;五&#xff09;Consul&#xff08;2&#xff09; 段子手168 一、consul 集群&#xff1a;consul 集群的基础知识 1、启动 sonsul 服务命令&#xff1a; 以开发者模式快速启动&#xff1a; consul agent -dev -client0.0.0…

13.JAVAEE之HTTP协议

HTTP 最新的版本应该是 HTTP/3.0 目前大规模使用的版本 HTTP/1.1 使用 HTTP 协议的场景 1.浏览器打开网站 (基本上) 2.手机 APP 访问对应的服务器 (大概率) 学习 HTTP 协议, 重点学习 HTTP 的报文格式 前面的 TCP/IP/UDP 和这些不同, HTTP 的报文格式,要分两个部分来看待.请求…

移动端日志采集与分析最佳实践

前言 做为一名移动端开发者&#xff0c;深刻体会日志采集对工程师来说具有重要意义&#xff0c;遇到问题除了 debug 调试就是看日志了&#xff0c;通过看日志可以帮助我们了解应用程序运行状况、优化用户体验、保障数据安全依据&#xff0c;本文将介绍日志采集的重要性、移动端…

高级防爬还得是公众号

平时一天也就1K的流量&#xff0c;最近流量暴涨&#xff0c;已经用自研的WAF防火墙阻挡了很多恶意攻击和爬虫&#xff0c;已经过滤掉很多低级攻击和爬取了。 多出的流量&#xff0c;也仅仅多了一个导航 dh.yu7s.com 用户&#xff0c;多时没有用的机器人爬虫&#xff0c;不封掉浪…

EXCEL表格中的数字,为什么每次打开会自动变成日期?

一、典型现象 在工作中&#xff0c;有时会发现公司里的报表&#xff0c;经过多人多次的重复的使用和修改后&#xff0c;会出现这种情况&#xff1a; 1.在表格里按照需要输入数字&#xff0c;保存工作簿。 2.然而&#xff0c;再次打开工作簿&#xff0c;里面的数字变成日期&a…

c#学习入门2

十、运算符 1&#xff09;算术运算符是用于数值类型变量计算的运算符&#xff0c;它返回的结果是数值 1.赋值符号 2.算数运算符 加 减- 乘* 除/ 取余% 3.算数运算符的优先级 4.算术运算符的复合运算 5.算术运算符的自增减 2&#xff09;字符串拼接 1.字符串拼接方式1 注意&…

自定义View-旋转变色圆角三角形的绘制

本文字数&#xff1a;3151字 预计阅读时间&#xff1a;20分钟 在现代设计中&#xff0c;动效图在APP的UI界面中所起到的作用无疑是显著的。相比于静态的界面&#xff0c;动效更符合人类的自然认知体系&#xff0c;它有效地降低了用户的认知负载&#xff0c;UI动效俨然已经成为了…

错误代码126:加载d3dcompiler_43.dll失败,分享多种解决方法

在正常使用电脑的过程中&#xff0c;当我尝试启动并运行一款心仪的游戏时&#xff0c;系统却突然弹出一个令人困扰的错误提示“错误代码126:加载d3dcompiler_43.dll失败”&#xff0c;它会导致游戏无法正常运行。为了解决这个问题&#xff0c;我经过多次尝试和总结&#xff0c;…

VMware ESXi虚拟机备份的方法和步骤

关于虚拟机备份 VMware ESXi 是 VMware vSphere 企业虚拟化套件的核心组件。在版本4.1之前&#xff0c;它一直被称为ESX。ESXi是一种裸机管理程序&#xff0c;直接安装在物理服务器上&#xff0c;它提供对底层资源的直接访问和控制&#xff0c;允许您在单个物理主机上创建和运…

网鼎杯-2018-unfinish解题方法

BUUCTF在线评测这里可以解题无需搭建 进入这题后我们会得到这样一个界面 这里我们会发现登录不进去也没有注册界面以及源码&#xff0c;这里我们需要获取它其他的一些界面找注入机会&#xff0c;这里有两种方式找其他界面&#xff0c;一种是猜这里是登录界面那么必定就会有注册…

网络安全新挑战:通用人工智能(AGI)等级保护指南

通用人工智能&#xff08;AGI&#xff09;的发展现状及趋势 随着2023年大语言模型应用的划时代突破&#xff0c;以ChatGPT为杰出代表的此类技术犹如一股洪流&#xff0c;彻底颠覆了人类与机器智能交互的疆界&#xff0c;引领通用人工智能&#xff08;AGI&#xff09;步入一个崭…

[SWPUCTF-2022-新生赛]ez_sql

title:[SWPUCTF 2022 新生赛]ez_sql 审题 根据提示&#xff0c;POST传参 得到假的flag 判断类型 字符型注入 判断列数 发现空格和’or’被过滤 重新构造 nss-1/**/oorrder/**/by/**/4#发现为3个字段 采用联合注入union 爆库 发现union被过滤&#xff0c;双写union绕过 发…

【小迪安全2023】第58天:服务攻防-应用协议设备KibanaZabbix远控向日葵VNCTV

&#x1f36c; 博主介绍&#x1f468;‍&#x1f393; 博主介绍&#xff1a;大家好&#xff0c;我是 hacker-routing &#xff0c;很高兴认识大家~ ✨主攻领域&#xff1a;【渗透领域】【应急响应】 【Java、PHP】 【VulnHub靶场复现】【面试分析】 &#x1f389;点赞➕评论➕收…

腾讯云邮件推送如何设置?群发邮件的技巧?

腾讯云邮件推送功能有哪些&#xff1f;怎么有效使用邮件推送&#xff1f; 腾讯云邮件推送以其稳定、高效的特点&#xff0c;受到了众多企业的青睐。那么&#xff0c;腾讯云邮件推送如何设置呢&#xff1f;又有哪些群发邮件的技巧呢&#xff1f;下面AokSend就来详细探讨一下。 …