栈和队列【详解】

news2025/3/10 15:19:04

目录

一、栈

1.栈的定义 

2.栈的初始化 

3.入栈 

4.出栈

 5.获取栈顶元素

6.获取栈元素的个数

 7.判断栈是否为空

8.销毁栈

二、队列

1.队列的定义

2.入队

 3.出队

4.获取队头元素

5.获取队尾元素

6.判断队列是否为空

 7.获取队列的元素个数

8.销毁队列


前言:

栈和队列也是一种常见的线性表

一、栈

1.栈的定义 

 栈:仅限在一端进行插入和删除元素操作。数据插入删除的一端称为栈顶,而另一端称为栈底

压栈:数据的插入操作。出栈:数据的删除操作。

栈中的数据遵循后进先出(Last In First Out,简称LIFO)的原则。

如图:

栈的存储定义 :

这里采用的是顺序栈,以动态数组的形式进行存放栈的元素,当栈满时,可以动态的增加栈的容量。

定义一个指针负责指向动态数组,用top来表示栈底,还有就是栈的容量capacity。

代码:

typedef int STDataType;

typedef struct StackNode 
{
	STDataType* a;
	int top; //栈底
	int capacity;  //栈的容量
}Stack;

2.栈的初始化 

当栈的存储定义完成后,就开始对栈进行初始化。

代码:

//初始化栈
/*这里采用动态数组来进行模拟栈*/
void InitStack(Stack* ps) 
{
	assert(ps);
	ps->a = NULL;
	ps->capacity = 0;
	ps->top = 0;  //指向栈顶的下一个元素
}

注意:这里定义的top 是指当top == 0 时 指向栈顶的下一个元素,当然top也可以是-1。这里采用的是top = 0。

3.入栈 

当元素入栈时,我们需要先考虑一下栈的容量的问题,例如:栈满或者初次使用栈的情况。

代码: 

//入栈
void PushStack(Stack* ps, STDataType x) 
{
	assert(ps);
	//入栈前先检查一下栈的容量
	if (ps->capacity == ps->top)
	{
		int newcapacity = ps->capacity == 0 ? 4 : 2 * ps->capacity;
		//使用realloc直接为动态数组分配空间
		STDataType* tmp = (STDataType*)realloc(ps->a,newcapacity*sizeof(STDataType));
		if (tmp == NULL) 
		{
			perror("PushStack->realloc");//出错时提示
			return;
		}
		else 
		{
			ps->a = tmp;
			ps->capacity = newcapacity;
		}
	}

	//数据压栈
	ps->a[ps->top] = x;
	ps->top++;	//同时指向下个一个栈顶元素
}
  • 这里当初次入栈时,使用realloc进行动态分配空间,初次使用realloc 时,说明ps->a == NULL,那么这里就相当于malloc进行分配空间。
  • 栈满时,不是初次入栈就让原来的栈的容量增加二倍 (2 * ps->capacity)。
  • 栈没有满时,就直接入栈,同时top指向下一个栈顶元素。

 这里多说一下,如果对于realloc不是很理解,可以转到  realloc详细解析

注意:还有就是作者刚学realloc时,总是忘记对realloc使用sizeof(),直接给出元素个数,却忘记给出其元素的大小了。 所以不要忘记sizeof()

4.出栈

出栈需要注意的就是:当栈空了,就不能进行出栈了,这里采用断言assert来避免

代码:

//出栈
void PopStack(Stack* ps) 
{
	assert(ps);
	assert(ps->top > 0);
	ps->top--;    //栈顶减一即可
}

 5.获取栈顶元素

这里也要注意栈为空的情况

 代码:

//获取栈顶元素
STDataType TopStack(Stack* ps) 
{
	assert(ps);
	assert(ps->top > 0);
	return ps->a[ps->top - 1];
}

如图:

6.获取栈元素的个数

因为top是从0开始的,下标:0 到 top-1,就相当于有top个元素。

 代码:

//获取栈元素的个数
int SizeStack(Stack* ps) 
{
	assert(ps);
	return ps->top;
}

 7.判断栈是否为空

这里采用bool 返回类型,如果为空就返回的是true ,不为空就返回false。

//判断栈是否为空,空返回true,非空返回false
bool EmptyStack(Stack* ps) 
{
	assert(ps);
	return ps->top == 0;
}

8.销毁栈

为避免内存泄漏,我们应该养成及时释放内存的好习惯。

  代码:

//销毁栈
void DestroyStack(Stack* ps) 
{
	assert(ps);
	free(ps->a);   //释放指向的动态数组
	ps->a = NULL;
	ps->capacity = 0;
	ps->top = 0;
}

二、队列

1.队列的定义

队列:只允许一端进行插入元素(队尾),另一端机进行删除元素(队头)的线性表。 

进队:数据的插入操作  出队:数据的删除操作

队列中的数据遵循先进先出(First In First Out,简称FIFO)的原则。

如图:

队列的存储定义: 这里是通过单链表的形式来进行模拟队列。同时定义两个指针来进行控制,一个指向队头,另一个指向队尾。这样就可以避免再从头开始遍历链表来找尾了。

代码:

typedef int QDataType;

//通过单链表来模拟队列
typedef struct QueueNode 
{
	QDataType val;
	struct QueueNode* next; //记录下一个结点的地址
}QueueNode;

typedef struct Queue 
{
	QueueNode* phead;	//指向队头的指针
	QueueNode* tail;	//指向队尾的指针
	int size;	//同时记录栈元素的个数
}Queue;

2.入队

元素入队,通过单链表进行尾插来模拟队列的入队。

在入队的操作中,采取使用malloc动态内存函数来开辟内存空间存放元素。因为是尾插,所以这里我们就要提前判断一下是否为第一次入队(尾插),当然这里也可以不用判断(前提就是要有头结点)。 因为这里没有用头结点,所以需要判断一下。

代码:

//入队
void PushQueue(Queue* pq, QDataType x) 
{
	assert(pq);
	QueueNode* newnode = (QueueNode*)malloc(sizeof(QueueNode));
	if (newnode == NULL )
	{
		perror("PushQueue->malloc");
		return;
	}
	newnode->val = x;
	newnode->next = NULL;
	//判断是否为第一次进行入队
	if (pq->phead == NULL) 
	{
		//第一次入队
		pq->phead = pq->tail = newnode;
	}
	else 
	{
		//不是第一次入队直接进行尾插
		pq->tail->next = newnode;
	}
	pq->size++;//队列元素加一
}

 3.出队

元素出队,这里通过单链表的头删进行模拟出队。出队需要注意的是队列不能为空那个,所以这里使用assert来断言进行避免

代码:

//出队
void PopQueue(Queue* pq) 
{
	assert(pq);
	assert(pq->phead);
	QueueNode* next = pq->phead->next;
	free(pq->phead);
	pq->phead = next;
	//当出队最后一个元素时
	//出完队后,headz指向空,而tail却变成了访问野指了
	//所以这里要对删的是最后一个元素进行单独处理
	if (pq->phead == NULL)
	{
		pq->tail = NULL;
	}
	pq->size--;
}

4.获取队头元素

需要注意的是:队为空的情况。使用assert断言来避免

代码:

//获取队头元素
QDataType TopQueue(Queue* pq) 
{
	assert(pq);
	assert(pq->phead);
	return pq->phead->val;
}

5.获取队尾元素

当然这里也要避免队尾为空的情况

代码:

//获取队尾元素
QDataType TailQueue(Queue* pq) 
{
	assert(pq);
	assert(pq->tail);
	return pq->tail->val;
}

6.判断队列是否为空

队列为空就返回true,否则返回false

代码:

//判断队列是否为空
bool EmptyQueue(Queue* pq) 
{
	assert(pq);
	return pq->phead == NULL;
}

 7.获取队列的元素个数

返回size

 代码:

//获取队列元素的个数
int SizeQueue(Queue* pq)
{
	assert(pq);
	return pq->size;
}

8.销毁队列

  代码:

//销毁队列
void DestroyQueue(Queue* pq) 
{
	assert(pq);
	QueueNode* cur = pq->phead;
	while (cur)
	{
		QueueNode* next = cur->next; //记录下一个结点
		free(cur);
		cur = next;
	}
	pq->phead = pq->tail = 0;
	pq->size = 0;
}

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

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

相关文章

基于天鹰算法优化概率神经网络PNN的分类预测 - 附代码

基于天鹰算法优化概率神经网络PNN的分类预测 - 附代码 文章目录 基于天鹰算法优化概率神经网络PNN的分类预测 - 附代码1.PNN网络概述2.变压器故障诊街系统相关背景2.1 模型建立 3.基于天鹰优化的PNN网络5.测试结果6.参考文献7.Matlab代码 摘要:针对PNN神经网络的光滑…

pycurl>=7.43.0.5机器学习环境配置问题

去官网下载对应版本.whl文件,注意使用python --version提前查看 python版本信息和64bit还是32bit,下载对应版本。 cd 到该路径下,并pip。6

WPF树形控件TreeView使用介绍

WPF 中的 TreeView 控件用于显示层次结构数据。它是由可展开和可折叠的 TreeViewItem 节点组成的&#xff0c;这些节点可以无限嵌套以表示数据的层次。 TreeView 基本用法 例如实现下图的效果&#xff1a; xaml代码如下&#xff1a; <Window x:Class"TreeView01.Mai…

docker、elasticsearch8、springboot3集成备忘

目录 一、背景 二、安装docker 三、下载安装elasticsearch 四、下载安装elasticsearch-head 五、springboot集成elasticsearch 一、背景 前两年研究了一段时间elasticsearch&#xff0c;当时也是网上找了很多资料&#xff0c;最后解决个各种问题可以在springboot上运行了…

LeetCode(32)串联所有单词的子串【滑动窗口】【困难】(含图解)

目录 1.题目2.答案3.提交结果截图4.图解 链接&#xff1a; 串联所有单词的子串 1.题目 给定一个字符串 s 和一个字符串数组 words。 words 中所有字符串 长度相同。 s 中的 串联子串 是指一个包含 words 中所有字符串以任意顺序排列连接起来的子串。 例如&#xff0c;如果 w…

Mac中LaTex无法编译的问题

最近在使用TexStudio时&#xff0c;遇到一个棘手的问题&#xff1a; 无法编译&#xff0c;提示如下&#xff1a; kpathsea: Running mktexfmt xelatex.fmt /Library/TeX/texbin/mktexfmt: kpsewhich -var-valueTEXMFROOT failed, aborting early. BEGIN failed–compilation a…

基于原子轨道搜索算法优化概率神经网络PNN的分类预测 - 附代码

基于原子轨道搜索算法优化概率神经网络PNN的分类预测 - 附代码 文章目录 基于原子轨道搜索算法优化概率神经网络PNN的分类预测 - 附代码1.PNN网络概述2.变压器故障诊街系统相关背景2.1 模型建立 3.基于原子轨道搜索优化的PNN网络5.测试结果6.参考文献7.Matlab代码 摘要&#xf…

2023年中国油墨树脂主要环节、产量及市场规模分析[图]

油墨树脂是指用于油墨制造中的一种高分子材料&#xff0c;主要用于改善油墨的粘性、流动性、光泽度和耐磨性等性能。其主要成分为合成树脂&#xff0c;如聚酯、聚酰胺、聚丙烯酸酯等。油墨树脂在油墨制造中的应用非常广泛&#xff0c;可以用于各种类型的油墨&#xff0c;包括印…

Java架构师软件架构风格

目录 1 数据流风格1.1 管道过滤器1.2 数据流风格的优点2 调用返回风格2.1 面向对象风格2.2 调用返回风格总结3 独立构件风格3.1 事件驱动系统风格的主要特点3.2 独立构件风格总结4 虚拟机风格4.1 虚拟机风格总结5 仓库风格5.1 仓库风格总结想学习架构师构建流程请跳转:Java架构…

基于Acconeer的A121-60GHz毫米波雷达传感器SDK移植及测距示例(STM32L496为例)

基于Acconeer的A121-60GHz毫米波雷达传感器SDK移植及测距示例&#xff08;STM32L496为例&#xff09; 工程&#xff1a; Keil工程资源 参考资料&#xff1a; A121 datasheet 1.3 A121 HAL Software Integration User Guide A121 STM32CubeIDE User Guide 官方参考示例工程&a…

接口测试快速上手指南

大量线上BUG表明&#xff0c;对接口进行测试可以有效提升产品质量&#xff0c;暴露手工测试时难以发现的问题&#xff0c;同时也能缩短测试周期&#xff0c;提升测试效率。但在实际执行过程中&#xff0c;接口测试被很多同学打上了“上手难&#xff0c;门槛高”的标签。 本文旨…

使用gin 代理 web网页

问web项目的代理&#xff0c;业界常用的方案是nginx做代理&#xff0c;这个是网上最多资料的。 因为我需要做自己的流量转发&#xff0c;也就是所有访问都要经过我的一个流量分发微服务&#xff0c;这和nginx作用冲突了。如果再加个nginx来做第一层方向代理和网页的静态资源代…

如何让Python2与Python3共存

安装 首先分别安装Py2和Py3&#xff0c;我都安装到C盘根目录里了&#xff0c;然后分别将Py2和Py3都配置到系统环境变量中去&#xff1a;C:\Python36\Scripts\;C:\Python36\;C:\Python27\;C:\Python27\Scripts; 配置 修改两个版本的可执行文件名字 验证 重新配置一下pip …

警惕.locked勒索病毒,您需要知道的预防和恢复方法。

尊敬的读者&#xff1a; 随着网络技术的进步&#xff0c;勒索病毒已经成为一种极具威胁性的网络犯罪工具之一。其中&#xff0c;.locked勒索病毒是一种采用高级加密算法的恶意软件&#xff0c;目的是加密用户的文件&#xff0c;并勒索赎金以提供解密密钥。本文将介绍如何应对被…

A股风格因子看板 (2023.11第12期)

该因子看板跟踪A股风格因子&#xff0c;该因子主要解释沪深两市的市场收益、刻画市场风格趋势的系列风格因子&#xff0c;用以分析市场风格切换、组合风格暴露等。 今日为该因子跟踪第12期&#xff0c;指数组合数据截止日2023-10-31&#xff0c;要点如下&#xff1a; 近1年A股风…

LeetCode算法心得——使用最小花费爬楼梯(记忆化搜索+dp)

大家好&#xff0c;我是晴天学长&#xff0c;很重要的思想动规思想&#xff0c;需要的小伙伴可以关注支持一下哦&#xff01;后续会继续更新的。&#x1f4aa;&#x1f4aa;&#x1f4aa; 1&#xff09;使用最小花费爬楼梯 给你一个整数数组 cost &#xff0c;其中 cost[i] 是从…

OpenHarmony Axios组件使用过程中,Api9不适配问题

大家好&#xff0c;我是【八戒&#xff0c;你又涨价了哎】 以下是我个人在学习OpenHarmony过程中的分享&#xff0c;请大家多多指教 目录 问题描述 解决方法 问题描述 使用axios组件的时候&#xff0c;把应用部署到开发板&#xff0c;提示Api9不适配 解决方法 对这类版本不…

【SpringCloud微服务全家桶学习笔记-Hystrix(服务降级,熔断,接近实时的监控,服务限流等)】

服务雪崩 &#xff08;微服务面临的问题&#xff09; 多个微服务之间调用的时候&#xff0c;假设微服务A调用微服务B和微服务C&#xff0c;微服务B和微服务C又调用其它的微服务&#xff0c;这就是所谓的“扇出”。如果扇出的链路上某个微服务的调用响应时间过长或者不可用&…

一条命令彻底卸载Linux自带多个版本jdk

一条命令彻底卸载Linux自带多个版本jdk 检查系统已经安装的jdk rpm -qa | grep java卸载所有已经安装的 jdk xargs 将参数逐个传递 将已安装的 java 程序逐个当做参数传递给 rpm -e --nodeps rpm -qa | grep java | xargs rpm -e --nodeps再次检查系统已经安装的jdk rpm -qa | …

Halcon Solution Guide I basics(3): Region Of Interest(有兴趣区域/找重点)

文章目录 文章专栏前言文章解读前言创建ROI案例1&#xff1a;直接截取ROI手动截取ROI 总结ROI套路获取窗口句柄截取ROI区域获取有效区域 Stop组合 文章专栏 Halcon开发 Halcon学习 练习项目gitee仓库 CSDN Major 博主Halcon文章推荐 前言 今天来看第三章内容&#xff0c;既然是…