【数据结构】栈(Stack)和队列(Queue)

文章目录

    • 一、栈的概念及结构
    • 二、栈的特点
    • 三、栈的实现
      • 1.初始化栈
      • 2.判断栈空
      • 3.入栈
      • 4.出栈
      • 5.取栈顶元素
      • 6.栈的元素个数
      • 7.销毁
  • 队列
    • 一、队列的概念及结构
    • 二、队列的特点
    • 三、队列的实现
      • 1.初始化
      • 2.入队
      • 3.出队
      • 4.判断队空
      • 5.取队头元素
      • 6.取队尾元素
  • 总结

一、栈的概念及结构

(Stack): 一种特殊的线性表,只允许在栈顶进行插入和删除元素操作。栈中的数据元素遵守后进先出LIFO (Last In First Out)的原则。

在这里插入图片描述

栈顶:允许进行插入、删除操作的一端称为栈的栈顶(top),也称为表尾。
栈底:固定不动的一端,称为栈底(bottom),也称为表头。
进栈:栈的插入操作叫做进栈/压栈/入栈,入数据在栈顶。
出栈:栈的删除操作叫做出栈/弹栈,出数据也在栈顶。

也分为顺序栈链栈(类比顺序表和链表)采用顺序存储的栈称为顺序栈,用一段物理地址连续的存储单元依次存储数据元素,通常以数组的形式实现;采用链式存储的栈称为链栈。

栈的实现一般可以使用数组或者链表实现,相对而言数组的结构实现更优一些,因为数组尾插尾删的效率更高。

二、栈的特点

1.只能在栈顶进行插入和删除元素。
2.遵循后进先出原则,后入栈的元素先出栈,即最后插入的元素最先删除。
3.只能访问栈顶元素,不能从栈底或者中间访问元素。

三、栈的实现

栈的基本操作有:入栈(Push)、出栈(Pop)、取栈顶元素(Top)和判断栈是否为空(IsEmpty)等。

和顺序表一样,顺序栈采用动态存储的方式,根据需要来动态地申请空间。

队列的定义

#define INIT_SZ 10  //初始空间大小
#define INC_SZ 4	//每次扩容的空间大小
typedef int STDataType;//方便改存储的数据类型,下面以int示例
typedef struct Stack
{
	int* a;
	int top;//栈顶索引
	int capacity;//分配的空间容量
}ST;

1.初始化栈

//初始化
void STInit(ST* ps)
{
	assert(ps);//提高代码健壮性
	ps->a = (STDataType*)malloc(sizeof(STDataType) * INIT_SZ);
	if (NULL == ps->a)
	{
		perror("malloc");
		return;
	}
	ps->capacity = INIT_SZ;
	//ps->top = -1;//top是栈顶元素的位置
	ps->top = 0;//top是栈顶元素的下一个位置
}

注意:栈顶下标top在初始化时,可以选择初始化为-1,表示栈顶元素的位置;也可以选择初始化为0,表示栈顶元素的下一个位置。top初始化的值会导致后面的基本操作写法有一点不同,随机选择一种即可。

2.判断栈空

判空条件与初始化时top的值有关。

//判断栈空
bool STEmpty(ST* ps)
{
	assert(ps);
	return ps->top == 0;//初始化的值
}

3.入栈

//入栈
void STPush(ST* ps, STDataType x)
{
	assert(ps);
	if (ps->top == ps->capacity)//栈内元素个数等于空间容量,需要进行扩容
	{
		STDataType* tmp = (STDataType*)realloc(ps->a, sizeof(STDataType) * (INC_SZ + ps->capacity));
		if (NULL == tmp)
		{
			perror("malloc");
			return;
		}
		ps->a = tmp;
		ps->capacity += INC_SZ;
	}
	//ps->a[++ps->top] = x;//ps->top初始化为-1时的写法
	ps->a[ps->top++] = x;
}

注意:栈顶下标top初始化为-1,表示栈顶元素的位置,每次入栈先++top,到下一个元素的位置,再插入;top如果初始化为0,表示栈顶元素的下一个位置,每次先插入,再++top。

4.出栈

//出栈
void STPop(ST* ps)
{
	assert(ps);
	assert(!STEmpty(ps));//栈非空才能出栈
	ps->top--;
}

注意:删除的空间不能free掉,因为动态开辟的空间不能局部释放。

5.取栈顶元素

//返回栈顶元素
STDataType STTop(ST* ps)
{
	assert(ps);
	assert(!STEmpty(ps));//要保证栈非空才能取栈顶元素
	//return ps->a[ps->top];//top初始化为-1时的写法
	return ps->a[ps->top - 1];
}

这里也会受到前面top初始化值的影响。

6.栈的元素个数

//栈的元素个数
int STSize(ST* ps)
{
	assert(ps);
	//return ps->top+1;//top初始化为-1时的写法
	return ps->top;
}

7.销毁

//销毁
void STDestroy(ST* ps)
{
	assert(ps);
	ps->a = NULL;
	free(ps->a);
	ps->top = 0 = ps->capacity = 0;
}

队列

一、队列的概念及结构

队列:只允许在一端进行插入数据操作,在另一端进行删除数据操作的特殊线性表,队列具有先进先出FIFO(First In First Out)的特点。
在这里插入图片描述就像人们排队一样,讲究先来后到,先排队的人享受完服务,先离开。

队头:进行删除操作的一端。
队尾:进行插入操作的一端。
入队列:队列的插入操作,入数据在队尾。
出队列:队列的删除操作,出数据在队头。

队列也可以用数组和链表的结构实现,使用链表的结构实现更优一些,因为如果使用数组的结构,出队列是数组头删,效率会比较低。

队列也分为非循环队列循环队列,可以用数组或链表实现。下面主要介绍用链表实现的普通的非循环队列。

二、队列的特点

1.只能在队头删除数据,只能在队尾插入数据。
2.遵循先进先出原则,先入队的元素先出队,即先插入的元素先删除。
3.只能访问队头和队尾元素,不能从中间访问元素。

三、队列的实现

队列的基本操作有:入队(Push)、出队(Pop)、判断队列空(IsEmpty)取队头元素(Front)、取队尾元素(Back)等。

队列的定义
队列的链式存储结构是一个带有队头指针和队尾指针的单链表。

typedef int QDataType;//数据类型
//结点
typedef struct QueueNode
{
	QDataType data;
	struct QueueNode* next;
}QNode;
//队列
typedef struct Queue
{
	QNode* head;//队头指针
	QNode* tail;//队尾指针
}Queue;

1.初始化

不带头结点的链式队列的初始化。

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

2.入队

在这里插入图片描述入队相当于链表的尾插,只不过链表没有尾指针,需要从头结点开始遍历到尾结点,而队列可以通过队尾指针直接访问尾结点,效率更高。

void QueuePush(Queue* pq, QDataType x)
{
	assert(pq);
	QNode* newNode = (QNode*)malloc(sizeof(QNode));//申请结点
	if (NULL == newNode)
	{
		perror("malloc");
		return;
	}
	newNode->data = x;
	newNode->next = NULL;
	if (NULL == pq->head)//空队列,第一次入队
	{
		pq->head = pq->tail = newNode;
	}
	else
	{
		pq->tail->next = newNode;//队尾的下个结点指向新结点
		pq->tail = newNode;//更新队尾指针
	}
}

3.出队

在这里插入图片描述出队相当于链表的头删。

void QueuePop(Queue* pq)
{
	assert(pq);
	assert(pq->head);
	QNode* head = pq->head;//保存头结点,释放空间
	pq->head = head->next;//更新队头指针
	free(head);//释放头结点的空间
	head = NULL;//防止野指针
}

注意:删除时要释放结点空间,必须先保存头结点,否则更新队头指针后无法找到该结点从而导致无法释放这块空间。

4.判断队空

队列为空的条件与初始化有关。

bool QueueEmpty(Queue* pq)
{
	assert(pq);
	return pq->head == NULL;//或者return pq->tail == NULL;
}

5.取队头元素

QDataType QueueFront(Queue* pq)
{
	assert(pq);
	assert(!QueueEmpty(pq));//队列非空是前提
	return pq->head->data;
}

6.取队尾元素

QDataType QueueBack(Queue* pq)
{
	assert(pq);
	assert(!QueueEmpty(pq));//队列非空是前提
	return pq->tail->data;
}

总结

栈和队列都是一种特殊的线性表。

  • 栈的特点:后进先出,只能在表尾进行插入和删除。
  • 队列的特点:先进先出,只能在表头删除,在表尾插入。

  • 它们都可以用顺序存储和链式存储的方式。

    栈常用顺序存储结构即数组的方式,因为数组的尾插尾删效率高,但可能会存在频繁开辟内存空间和内存空间浪费的问题。而栈的链式存储结构,解决了空间浪费的问题,但每个节点都存放一个指针域,也会存在一定的内存开销,并且在每次申请和释放节点的过程中也存在一定的时间开销。

    队列常用链式存储结构即链表的方式,比链表多定义一个尾指针,解决尾插效率低的问题,并且不存在空间浪费。 而队列的顺序存储结构,由于插入需要挪动数据,效率低下,但循环队列可以解决这个问题,时间复杂度从O(N)变成了O(1),但仍存在内存空间浪费的问题。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

k8s 理论知识基本介绍

目录 一 k8s 理论前言 (一)微服务是什么 1,应用场景 2,API 是什么 (二),微服务 如何做版本迭代 1. Docker镜像构建 2. 版本标记 3. Docker Registry 4. 环境一致性 5. 滚动更新…

26 | 备库为什么会延迟好几个小时?

在官方的 5.6 版本之前,MySQL 只支持单线程复制,由此在主库并发高、TPS 高时就会出现严重的主备延迟问题。 coordinator 就是原来的 sql_thread, 不过现在它不再直接更新数据了,只负责读取中转日志和分发事务。真正更新日志的,变成了 worker 线程。而 work 线程的个数,就是…

今日刷三题(day12):兑换零钱(一)+最长回文子串+编辑距离(一)

题目一:兑换零钱(一) 题目描述: 给定数组coins,coins中所有的值都为正整数且不重复。每个值代表一种面值的货币,每种面值的货币可以使用任意张,再给定一个aim,代表要找的钱数&…

单位圆内的正交向量多项式,第一部分:由Zernike多项式的梯度导出的基组

clear all; close all; clc; %% I1=double(imread(E:\zhenlmailcom-E8E745\华为家庭存\image\imgs\right\0.bmp)); I2=double(imread(E:\zhenlmailcom-E8E745\华为家庭存储\.法\image\imgs\right\1.bmp)); I3=double(imread(E:\zhenlmailcom-E8E745\华为家庭存储\.p\image\imgs…

学习torchmd分子动力学模拟

TorchMD打算提供一种简单易用的API,用于使用PyTorch进行分子动力学。这使研究人员能够更快地进行力场开发研究,并以PyTorch的简单性和强大性将神经网络潜力无缝集成到动力学中。 TorchMD使用与经典MD代码(如ACEMD)一致的化学单位&…

实在Agent智能体:引领智能自动化新纪元

在数字化转型的浪潮中,实在智能科技有限公司凭借其前沿技术,推出了实在Agent智能体——一款革命性的超自动化智能体。它不仅代表了人工智能技术的新高度,更预示着未来工作方式的变革。 什么是实在Agent智能体? 实在Agent智能体是…

《Fundamentals of Power Electronics》——状态空间平均法

文献中出现了许多交流变换器建模技术,包括电流注入法、电路平均法和状态空间平均法。尽管给定方法的支持者可能更喜欢用特定形式表示最终结果,但几乎所有方法的最终结果都是等效的。所有人都会赞同,平均和小信号线性化是PWM变换器建模的关键步…

云动态摘要 2024-05-06

给您带来云厂商的最新动态,最新产品资讯和最新优惠更新。 最新优惠与活动 [免费试用]即刻畅享自研SaaS产品 腾讯云 2024-04-25 涵盖办公协同、营销拓客、上云安全保障、数据分析处理等多场景 云服务器ECS试用产品续用 阿里云 2024-04-14 云服务器ECS试用产品续用…

用得助全媒体呼叫中心,让AI落到实处帮品牌做营销

怎么让人工智能落到实处的帮助到我们?我们今天来讲讲中关村科金得助全媒体呼叫中心是怎么让AI帮品牌。 这次聊的案例是知名的护肤品牌,该品牌在中国功能性护肤品市场占有率达到20.5%,这么高的市场占有率客户的咨询量也是非常庞大的&#xff0…

MAC M1 配置 Git SSH

背景 换了新笔记本,本地想要克隆github 上的项目需要配置ssh 公钥到自己的github账户中,否则使用ssh 地址克隆会报错,如下。 gitgithub.com: Permission denied (publickey). fatal: Could not read from remote repository.操作 1. 生成s…

探索大型语言模型(LLM)的世界

​ 引言 大型语言模型(LLM)作为人工智能领域的前沿技术,正在重塑我们与机器的交流方式,在医疗、金融、技术等多个行业领域中发挥着重要作用。本文将从技术角度深入分析LLM的工作原理,探讨其在不同领域的应用&#xff0…

安卓使用Fiddler抓包 2024

简介 最近试了一下安卓使用fiddler 抓包,发现https包基本都会丢失。原因是Anandroid 7版本针对ssl安全性做了加强,不认可用户的证书。我们要做的就是把fiddler导出的证书进过处理后放置到系统证书目录下面,这样才能抓包https请求。 这里使用…

【Anaconda】升级Anaconda Navigator提示JSONDecoderError,删除.condarc文件后搞定

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言一、报错:JSONDecoderError二、错误原因三、解决问题总结 前言 提示:这里可以添加本文要记录的大概内容: 时间长未升级Ana…

AI 绘画神器 Fooocus 本地部署指南:简介、硬件要求、部署步骤、界面介绍

本文收录于《AI绘画从入门到精通》专栏,专栏总目录:点这里,订阅后可阅读专栏内所有文章。 大家好,我是水滴~~ 随着人工智能技术的飞速发展,AI 绘画逐渐成为创意领域的新宠。Fooocus 作为一款免费开源的 AI 绘画工具&am…

窜货溯源采买的目的

当品牌遇到窜货时,不管是线上还是线下渠道,快速的治理方法,就是找到窜货源头,对源头进行打击,这里面有一步很关键的操作便是买货,将货品买回后做溯源,通过产品本身或者外包装上的条码&#xff0…

【Java orm 框架比较】十 新增hammer_sql_db 框架对比

迁移到(https://gitee.com/wujiawei1207537021/spring-orm-integration-compare) orm框架使用性能比较 比较mybatis-plus、lazy、sqltoy、mybatis-flex、easy-query、mybatis-mp、jpa、dbvisitor、beetlsql、dream_orm、wood、hammer_sql_db 操作数据 …

[uniapp 地图组件] 小坑:translateMarker的回调函数,会调用2次

大概率是因为旋转和移动是两个动画,动画结束后都会分别调用此函数 即使你配置了 【不旋转】它还是会调用两次, 所以此处应该是官方的bug

未来娱乐新地标?气膜球幕影院的多维体验—轻空间

在中国,一座独特的娱乐场所正在崭露头角:气膜球幕影院。这个融合了气膜建筑与激光投影技术的创新场所,不仅令人惊叹,更带来了前所未有的科幻娱乐体验。让我们一起探索这个未来的娱乐空间,感受其中的多维魅力。 现场演出…

Linux(openEuler、CentOS8)企业内网DHCP服务器搭建(固定Mac获取指定IP)

----本实验环境为openEuler系统<以server方式安装>&#xff08;CentOS8基本一致&#xff0c;可参考本文&#xff09;---- 目录 一、知识点二、实验&#xff08;一&#xff09;为服务器配置网卡和IP&#xff08;二&#xff09;为服务器安装DHCP服务软件&#xff08;三&a…

DenseCLIP论文讲解

文章目录 简介方法总体框架 &#xff08;Language-Guided Dense Prediction&#xff09;上下文感知提示 &#xff08;Context-Aware Prompting&#xff09;应用实例 论文&#xff1a;DenseCLIP: Language-Guided Dense Prediction with Context-Aware Prompting 代码&#xff1…