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

news2024/11/16 3:19:03

一,队列的概念

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

队列(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 要创建栈的大小
//创建失败返回NULL
	SeqQueue* 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.coloradmin.cn/o/1612397.html

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

相关文章

数据库管理-第171期 Oracle是用这种方式确保读一致的(20240418)

数据库管理171期 2024-04-18 数据库管理-第171期 Oracle是用这种方式确保读一致的&#xff08;20240418&#xff09;1 基本概念2 用处3 注意事项总结 数据库管理-第171期 Oracle是用这种方式确保读一致的&#xff08;20240418&#xff09; 作者&#xff1a;胖头鱼的鱼缸&#x…

Redis系列之哨兵Sentinel集群搭建

在上一篇博客&#xff0c;我们已经知道怎么搭建一个redis主从复制集群&#xff0c;但是主从集群如果出现服务器宕机的情况&#xff0c;是不会自动选举master的&#xff0c;所以需要搭建更加高可用的集群模式&#xff0c;哨兵模式&#xff0c;哨兵集群会自动监控&#xff0c;如果…

深度学习发展中的继承和创新

深度学习是一步一步发展而来的&#xff0c;新的成就也是在原有的基础上&#xff0c;逐步取得突破&#xff0c;有一些东西是一点一点变化&#xff0c;突破发展而来的&#xff0c;也就是每一次小的突破和每一次小的突破累积起来&#xff0c;构成一个明显的进步。我们可以通过观察…

python 文件 成绩分析2

‘’’ 文件score.txt中存储了学生的考试信息,内容如下 小明,98,96 小刚,90,94 小红,90,94 小王,98,96 小刘,80,90 小赵,90,96 第二列是数学成绩&#xff0c;第三列是语文成绩 请写程序分析&#xff1a; 哪些同学语文成绩是相同的?哪些同学数学成绩是相同的?哪些同学语文和数…

C语言—字符指针,指针数组和数组指针详解

字符指针 在指针的类型中我们知道有一种指针类型为字符指针 char* ; int main() {char ch w;char *pc &ch;*pc w;return 0; }还有一种使用方式如下&#xff1a; int main() {const char* pstr "hello world.";//这里是把一个字符串放到pstr指针变量里了吗…

WebSocket 快速入门 - springboo聊天功能

目录 一、概述 1、HTTP&#xff08;超文本传输协议&#xff09; 2、轮询和长轮询 3、WebSocket 二、WebSocket快速使用 1、基于Java注解实现WebSocket服务器端 2、JS前端测试 三、WebSocket进阶使用 1、如何获取当前用户信息 2、 后端聊天功能实现 一、概述 HTTP…

Linux安装Docker完整教程及配置阿里云镜像源

官网文档地址 安装方法 1、查看服务器内核版本 Docker要求CentOS系统的内核版本高于3.10 uname -r #通过 uname -r 命令查看你当前的内核版本2、首先卸载已安装的Docker&#xff08;如果有&#xff09; 2.1 确保yum包更新到最新 yum update2.2 清除原有的docker&#xff0c…

生物特征识别的六大技术研究

生物特征识别技术是结合了计算机科学与光学、声学、生物传感器以及生物统计学原理&#xff0c;通过利用人体固有的生理特征&#xff08;如指纹、人脸、虹膜、掌纹、指静脉等&#xff09;和行为特征&#xff08;如笔迹、声音、步态等&#xff09;&#xff0c;来进行个人身份的鉴…

layui--table里使用switch

1. 项目需求 在layui.table上面渲染后的列表上面加一个switch开关&#xff0c;监听switch开关的动作&#xff0c;实现本列数据的状态切换&#xff01; 实现效果如下&#xff1a; 2. 实现方式 下面介绍的思路都是利用table的templet模板实现的&#xff0c;不同的在于模板代码…

F-logic DataCube3 SQL注入漏洞复现(CVE-2024-31750)

0x01 产品简介 F-logic DataCube3是一款用于光伏发电系统的紧凑型终端测量系统。 0x02 漏洞概述 F-logic DataCube3 /admin/pr_monitor/getting_index_data.php 接口处存在SQL注入漏洞,未经身份验证的攻击者可通过该漏洞获取数据库敏感信息,深入利用可控制整个web服务器。 …

JavaEE 初阶篇-深入了解 File 文件操作(实现文件搜索、非空文件夹删除)

&#x1f525;博客主页&#xff1a; 【小扳_-CSDN博客】 ❤感谢大家点赞&#x1f44d;收藏⭐评论✍ 文章目录 1.0 File 文件概述 2.0 创建 File 类对象的方法 2.1 判断文件类型、获取文件信息的方法 2.2 创建文件、删除文件的方法 2.3 遍历文件夹的方法 3.0 文件搜索与删除 3.1…

虚拟机中的打印机,无法打印内容,打印的是白纸或英文和数字,打印不了中文

原因&#xff1a;打印机驱动设置不正确 解决方案&#xff1a; 打开打印机属性 -> 高级 -> 新驱动程序 下一页 -> Windows 更新 耐心等待&#xff0c;时间较长。 选择和打印机型号匹配的驱动&#xff0c;我选择的是&#xff1a; 虽然虚拟机和主机使用的驱动不…

《机器学习by周志华》学习笔记-线性模型-02

1、对数几率回归 1.1、背景 上一节我们考虑了线性模型的回归学习,但是想要做分类任务就需要用到上文中的广义线性模型。 当联系函数连续且充分光滑,考虑单调可微函数,令: 1.2、概念 找一个单调可谓函数,将分类任务的真实标记与线性回归模型的预测值联系起来,也叫做「…

关系型数据库的相关概念

表、记录、字段 表 一个实体集相当于一个表记录 一个实体相当于一个记录&#xff0c;在表中表表现为一行数据字段 一个字段相当于数据库表中的列 表的关联关系 一对一(一对一的表可以合并成一张表)一对多多对多 必须创建第三张表&#xff0c;该表通常称为联接表&#xff0c…

个人电脑信息安全注意事项

个人电脑信息安全注意事项 一、密码安全&#xff1a; 设置复杂且独特的密码&#xff0c;避免使用容易猜测或常见的密码。 定期更换密码&#xff0c;特别是在重要账户或应用上。 不要在多个账户上重复使用相同的密码。 使用密码管理工具来安全地存储和访问密码。 二、软件安…

Axure琐碎细节

文章目录 琐碎细节注释预览编写原型图的时候可以把颜色改为灰色标尺竖直文字左对齐Axure中的文字怎么添加元件层级问题如何找到各种各样的形状&#xff0c;比如三角形了 五角星了 十字架了给按钮设置简单的交互动作通过锁来等比例缩放 琐碎细节 注释 有时候我们需要给我们的元…

探索通过GPT和云平台搭建网安实战培训环境

项目背景 网络安全是一个不断演变的领域&#xff0c;面临着日益复杂的挑战和不断扩大的威胁。数字化时代&#xff0c;随着勒索攻击、数据窃取、网络钓鱼等频频出现&#xff0c;网络攻击的威胁指数和影响范围进一步增加&#xff0c;如何防范网络攻击&#xff0c;确保数据安全&a…

ssh免秘钥登录与时钟同步

ssh免秘钥登录及数据拷贝 ssh免秘钥登录及数据拷贝环境生成秘钥拷贝公钥到到远程服务器通过ssh-copy-id命令拷贝公钥到远程服务器通过手动拷贝公钥到远程服务器 非root用户远程拷贝公钥 设置编码方式临时设置编码永久设置方法一永久设置方法二 设置时钟同步使用 ntpdate 命令使…

yabai,openssh 竟然把 Windows 搞蓝屏了

在虚拟化技术日益普及的今天&#xff0c;Oracle VirtualBox 提供了一个功能强大的平台&#xff0c;允许用户在单一物理机上运行多个操作系统。 本文将指导你如何使用 Oracle VirtualBox 安装 Oracle Linux 9.3。 1. Oracle VirtualBox 7.0 介绍 Oracle VirtualBox 7.0 是一款由…

Compose 布局

文章目录 Compose 布局ColumnColumn属性使用 RowRow属性使用 BoxBox属性使用 ConstraintLayoutLazyColumnLazyColumn属性使用使用多类型使用粘性标题回到顶部 LazyRowLazyRow属性使用 LazyVerticalGridLazyVerticalGrid属性使用 Compose 布局 Column Compose中的”垂直线性布…