一起学数据结构(6)——栈和队列

news2024/11/17 19:30:04

上篇文章中,对栈的概念及特点进行了解释,并且给出了栈实现的具体代码。本篇文章将给出队列的基本概念及特点。并给出相应的代码。

1. 队列的概念及结构:

在给出队列的概念之前,先给出上篇文章中提到的栈的概念:一种只能在表尾进行插入和删除的线性表。

对于队列,与栈相同的一点是,依然只能在表尾插入数据。但是,队列只允许在表头删除数据。

进行插入操作的一端,称之为队尾。将插入数据的操作称之为入队列。

进行删除数据的一段,称之为对头。将删除数据的操作称之为出队列。

队列整体结构可以有下图反应:
2. 队列的代码实现:

2.1 队列结构的定义:

通过结构体定义下放给的队列结构:

typedef int QDataType;
typedef struct QueueNode
{
	struct QueueNode* next;
	QDataType data;
}QNode;

在后续的操作中,需要通过向所编写的功能函数中传递两个结构体指针phead,tail来分别表示队头、队尾来达到头删、尾插的目的。例如在进行插入时,插入第一个数据时,pheadtail均指向第一个数据。即:

只有插入的元素数量>1时,pheadtail两个指针才会拉开差距。例如:插入3个元素时,大致效果如下:

所以,在后续操作时,需要改变pheadtail两个指针中的内容。在之前关于单链表的文章中一起学数据结构(3)——万字解析:链表的概念及单链表的实现_起床写代码啦!的博客-CSDN博客提到,当一级指针phead,tail作为形式参数时,函数内部对于形式参数的更改,并不会影响这两个指针中实际保存的内容。解决这个问题的方法, 在之前的文章中曾提到过下面几种:
1. 通过传递关于phead,tail二级指针来达到改变着两个指针中存储内容的目的。

2.在书写函数时,最后直接返回形参。并且在外部创建变量来记录函数的返回值。

本文提供第三种方法,即再额外创建一个结构体来存储phead,tail这两个指针。并且将这个结构体的指针作为形参传递到函数中。即:

typedef struct Queue
{
	QNode* phead;
	QNode* tail;
	int size;
}Que;

如果想更改phead中存储的内容,只需要命名一个结构体指针,例如:Que*ps。通过ps-> phead可以达到目的。

对于上面提出的用结构体封装两个指针的方法,也可以看作关于带头结点的双向循环链表文章一起学数据结构(4)——带头结点的双向循环链表_起床写代码啦!的博客-CSDN博客

中哨兵位头结点的作用。

2.2 队列初始化:

将结构体Que中各个结构体成员初始化,代码如下:

void QueueInit(Que* ps)
{
	assert(ps);
	ps->phead = ps->tail = 0;
	ps->size = 0;
}

2.3 向队列中插入元素:

与通过栈顶向栈中插入元素的思路大致相同,首先需要进行扩容。但是因为在实现栈时,是采用顺序实现。而对于本文的队列则采用链式实现。所以,在栈中开辟空间时,是开辟一部分连续空间。当这部分空间被占满时再开辟。对于链式结构,只需要,在每次插入之前,开辟一个单独的结点即可。具体代码如下:
 

void QueuePush(Que* ps, QDataType x)
{
	assert(ps);

	QNode* newnode = (QNode*)malloc(sizeof(QNode));
	if (newnode == NULL)
	{
		perror("malloc");
		exit(-1);
	}

	newnode->next = NULL;
	newnode->data = x;

	if (ps->tail == NULL)
	{
		ps->phead = ps->tail = newnode;
	}
	else
	{
		ps->tail->next = newnode;
		ps->tail = newnode;
	}
	ps->size++;
}

2.3 删除队列中的元素:

在文章的前面提到,队列的特点是尾部插入元素、头部删除元素、先进先出。所以,对于删除队列中的元素,只需要先将phead指向下一个结点。但是需要注意,当队列中只有一个结点时,当free掉该结点时,需要处理phead,tail这两个指针。具体代码如下:
 

void QueuePop(Que* ps)
{
	assert(ps);
	assert(!QueueEmpty(ps));
	if (ps->phead->next == NULL)
	{
		free(ps->phead);
		ps->phead = ps->tail = NULL;
	}
	else
	{
		QNode* next = ps->phead->next;
		free(ps->phead);
		ps->phead = next;
	}
	ps->size--;
}

2.4 取队列的队头、队尾元素:

直接通过指针返回队头、队尾的元素即可,只给出代码,不做多余解释:

QDataType QueueFront(Que* ps)
{
	assert(ps);
	assert(!QueueEmpty(ps));

	return ps->phead->data;
}

QDataType QueueBack(Que* ps)
{
	assert(ps);
	assert(!QueueEmpty(ps));

	return ps->tail->data;
}

2.5 探空:

原理与栈中的探空结构相同,只给出代码,不做多余解释:

bool QueueEmpty(Que* ps)
{
	assert(ps);

	return ps->phead == NULL;
}

2.6 统计长度:

在前面的删除元素、删除元素的功能中,每进行一次变动,都会有size进行相应的变动。所以,统计长度这部分,直接返回size即可。代码如下:

int QueueSize(Que* ps)
{
	assert(ps);


	return ps->size;
}

2.7 删除栈:

与删除单链表原理相同,先创建一个变量cur存储队列的头指针,通过while循环进行删除,对于删除的过程,首先创建一个变量用于存储cur->next,再free(cur),最后让cur存储next中存储的地址。最后将phead,tail,size全部置为NULL或者0即可。代码如下:

void QueueDestory(Que* ps)
{
	assert(ps);

	QNode* cur = ps->phead;
	while (cur)
	{
		QNode* next = cur->next;
		free(cur);
		cur = next;
	}
	ps->phead = ps->tail = NULL;
	ps->size = 0;
}

3. 队列功能测试:

通过下面的测试代码,对队列的功能进行测试:
 

void TestQueue()
{
	Que ps;
	QueueInit(&ps);
	QueuePush(&ps, 1);
	QueuePush(&ps, 2);
	QueuePush(&ps, 3);
	QueuePush(&ps, 4);
	while (!QueueEmpty(&ps))
	{
		printf("%d", QueueFront(&ps));
		QueuePop(&ps);
	}
	QueueDestory(&ps);


}

int main()
{
	TestQueue();
	return 0;
}

结果如下:







 

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

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

相关文章

JVM系列 运行时数据区

系列文章目录 第一章 运行区实验 文章目录 系列文章目录前言一、堆(Heap)1.1、新生代/Young区1.1.1、Eden区1.1.2、Survival区 1.2、年老代(old区) 二、虚拟机栈(Stack)2.1、栈顶缓存技术2.2、溢出2.3、栈…

约瑟夫环(循环列表实现)

约瑟夫(Joseph)问题的一种描述是:编号为1,2,3,…,n的n个人按顺时针方向围坐一圈。每人持有一个密码(正整数)。一开始任选一个正整数作为报数上限值m,从第一个…

vscode c++解决包含头文件红色波浪线问题

安装c/c插件后,按ctrlshiftp, 点击打开了c_cpp_properties.json文件,对其中的IncludePath进行编辑,示例如下: "includePath": ["${workspaceFolder}/**","${workspaceFolder}/include/**&q…

FastChat

Fast Chat是一个用于训练/部署和评估基于大型语言模型的聊天机器人的开发平台。其核心功能包括: 最先进模型的权重/训练代码和评估代码(例如Vicuna/FastChat-T5)基于分布式多模型的服务系统,具有Web界面和与OpenAI兼容的RESTful API。 安装 pip instal…

Dajngo01_Django框架基础与环境搭建

Dajngo01_Django框架基础与环境搭建 在正式开始学习Django之前,我们先简单了解一下Web应用程序的本质: 接收并解析HTTP请求,获取具体的请求信息处理本次HTTP请求,即完成本次请求的业务逻辑处理构造并返回处理结果——HTTP响应 那么…

Redis 数据一致性方案的分析与研究

点击下方关注我,然后右上角点击...“设为星标”,就能第一时间收到更新推送啦~~~ 一般的业务场景都是读多写少的,当客户端的请求太多,对数据库的压力越来越大,引入缓存来降低数据库的压力是必然选择,目前业内…

【移动开发】最新uniapp开发的多端影视APP+后端对接的苹果CMS源码(可打包多端app)

介绍: 分享一款uniapp开发的多端影视APP源码,后端对接的是苹果10CMS。 这个APP有缓存、投屏、回放记录、收藏等功能,非常完善。 会员中心也使用苹果cms的数据。 可以打包到多个端的代码。 本APP前端用的UI框架是特漂亮的colorUI&#xff0…

当我们谈外包,我们在谈什么?

大家好,我是苍何,周末发小来找我玩耍,聊到了他当初在华为外包的经历,感触挺大的,给大家做下分享。 小 Z 大学专科材料专业毕业,毕业后报名了 IT 培训班,学习了一年,之后面试去了华为…

关于安卓grovvy开发(一)bugly混淆自动上报

背景 打包,mapping,上传,这些是不是都困扰了开发很多。苦于复制粘贴?反正我是。于是,有了这个 最终效果 最终的效果,就是点击项目的打包gradle,复制mapping文件且进行bugly混淆的自动上报。 …

基于单片机超声波测距语音播放

一、系统方案 本设计采用52单片机作为主控器,HC-SR04测距,液晶1602显示,按键设置报警阀值,语音报警。 二、硬件设计 原理图如下: 三、单片机软件设计 1、首先是系统初始化 uint dist; // 保存超声波模块测量到的结果…

基于SSM的网上医院预约挂号系统

末尾获取源码 开发语言:Java Java开发工具:JDK1.8 后端框架:SSM 前端:采用JSP技术开发 数据库:MySQL5.7和Navicat管理工具结合 服务器:Tomcat8.5 开发软件:IDEA / Eclipse 是否Maven项目&#x…

Linux 部分IO函数

open、close函数 标准C库IO函数的说明文档在 man 3 open Linux系统IO函数说明文档在man 2 open open()函数打开文件 && errno 例子:目录下没有a.txt那么运行的时候会报错 open创建新文件 本来没有 create.txt 运行完有了 ll可看文…

【LeetCode-中等题】209. 长度最小的子数组

文章目录 题目方法一:滑动窗口:方法二: 题目 方法一:滑动窗口: 参考图解动画:长度最小的子数组 class Solution { //方法一:滑动窗口public int minSubArrayLen(int target, int[] nums) {int n nums.l…

解决jsp/html界面跳转servlet出现404错误的方法

解决jsp/html界面跳转servlet出现404错误的方法 最近在学习黑马项目过程中遇到的问题 问题一: 检查页面的跳转路径和名称拼写是否正确 问题二: tomcat发布项目时所使用的路径名称与项目不同 在idea右上角点击如图圈住的按钮 在deployment中更改出现…

【SpringCloud微服务项目学习-mall4cloud项目(1)】——环境部署,构建与运行

环境部署,构建与运行 mall4cloud项目介绍源码地址 开发环境搭建pom搭建项目运行前端运行 mall4cloud项目介绍 mall4j商城系统 首先介绍一下mall4j,是一个基于spring boot、spring oauth2.0、mybatis、redis的轻量级、前后端分离、防范xss攻击、拥有分布…

Redis的基本概念与基础用法(1)

在节假日前12306的访问量就会急剧增加,在这种海量用户高并发的情况下就容易出现网站崩溃的情况,造成网站奔溃的罪魁祸首就是关系型数据库,因为关系型数据库有: 性能瓶颈:磁盘IO性能低下扩展瓶颈:数据关系复…

【三维重建】Ubuntu18.04安装COLMAP

Ubuntu18.04安装COLMAP 文章目录 Ubuntu18.04安装COLMAP前言安装COLMAP:安装CUDA, cuDNN安装依赖项安装Ceres优化库安装glog(可选)配置并编译COLMAP运行COLMAP 总结 前言 COLMAP是一种通用的运动结构(SfM)和多视图立体(MVS)管道,具有图形和命令行界面。…

RBTree(红黑树)模拟实现(插入)

目录 红黑树的性质 红黑树的模拟插入 叔叔存在且为红色 叔叔不存在 旋转情况​​​​​​​ 叔叔存在且为黑色 总结 插入实现 节点 插入逻辑 左单旋 右单旋 红黑树是一颗平衡搜索二叉树,但是红黑树并不像 AVL 树一样是高度平衡二叉树,任意一…

正在吞食世界的Python!

谁能想到,30年后,一条蟒蛇因为人工智能而席卷了全世界!这一切,都源于1989年的那个圣诞节。 一个名叫Guido van Rossum程序员在荷兰的阿姆斯特丹呆着,无所事事的圣诞假期有点无聊。为了打发时间,他开发了一…

前端中的事件委托

前端小知识 事 件 委 托 作者:李俊才 (jcLee95):https://blog.csdn.net/qq_28550263 邮箱 :291148484163.com 本文地址:https://blog.csdn.net/qq_28550263/article/details/132819265 【介绍】&#xff1…