数据结构----栈

news2024/9/20 18:40:19

前言

Hello,小伙伴们,今天我们继续数据结构的学习,前面我们学习了顺序表和链表的实现,今天的栈知识也是和前面的知识相辅相成。

如果你喜欢我的内容的话,就请不要吝啬自己手中的三连哟,万分感谢!!好,废话不多说,开始我们今天的正题。

1.栈的概念和结构

栈:一种特殊的线性表,其只允许在固定的一端进行插入和删除元素的操作。进行数据插入和数据删除的一端,我们称之为栈顶,另一端我们称之为栈底。栈中的数据元素遵守后进先出的原则(Last In First Out)

压栈:栈的插入操作叫做进栈/压栈/入栈,入数据在栈顶;

出栈:栈的删除操作就叫做出栈。出数据也在栈顶。

栈的底层结构选型:

栈的实现一般可以使用数组或者链表,相对而言数组的结构要更加的简洁。因为数组在尾上插入数据的代价比较小。

2.栈的实现

更前几期的数据结构实现一样,我们还是先在VS2022上创建三个文件:

2.1 栈的定义:

 前面我们说到,栈的底层结构我们采用数组的方式是最好的,所以我们可以怎样来定义栈呢?

诶,我们是不是可以想到我们之前学习过的顺序表呢,他们们的底层逻辑都可以通过数组来实现,整体功能大同小异。

那我们就来试试这样定义栈的结构:

typedef int SDataType;
typedef struct Stack
{
	SDataType* arr;
	int capacity;
	int top;
}stack;

 而在实现栈的功能时我们只要注意,栈的数据插入和数据删除都只是在一端进行就好了!!

2.2 栈的初始化

初始化栈,我们应当怎么来做呢?

我们先来看实现该功能的函数:


2.2.1  void InitStack(stack* ps)函数的定义和实现

/首先实现栈的初始化
void InitStack(stack* ps);

看到这这里有没有人觉得很熟悉呢?

对,其实这里的初始化就是和顺序表的初始化一样的所以开始的时候,我们需要

将 ps->arr置为NULL 

ps->capacity = ps->top = 0;

函数我们就可以这样实现:
 

//首先实现栈的初始化
void InitStack(stack* ps)
{
	assert(ps);
	ps->arr = NULL;
	ps->capacity = ps->top = 0;
}

2.2.2 函数功能测试

2.3压栈的实现

2.3.1  void StackPush(stack* ps, SDataType x)的定义和实现

其实,压栈的函数和前面我们遇到的顺序表和链表的实现大致相同:

我们先来看压栈函数的定义:

//实现入栈操作
void StackPush(stack* ps, SDataType x);

再来看看函数的实现逻辑:
在这里我们还是要注意,插入数据的前提就是必须要有足够的空间来存储数据。

所以我们还是要用到CheckCapacity函数来检查存储空间

还不了解这个函数的同学,可以看看我往期的文章中关于顺序表的尾插,里面对该函数有介绍:

文章链接为:http://t.csdnimg.cn/sHzPc

void CheckCapacity(stack* ps)
{
	if (ps->capacity == ps->top)
	{

		int newcapacity = ps->capacity == 0 ? 4 : 2 * ps->capacity;
		SDataType* newstack = (SDataType*)realloc(ps->arr, newcapacity * sizeof(SDataType));
		if (newstack == NULL)
		{
			perror("CheckCapacity, realloc:");
			exit(1);
		}
		ps->arr = newstack;
		ps->capacity = newcapacity;
	}
}

//实现入栈操作
void StackPush(stack* ps, SDataType x)
{
	assert(ps);
	CheckCapacity(ps);
	ps->arr[ps->top++] = x;//ps->表示栈中有效数据的个数,每插入数据一次,ps->top就+1
}

2.3.2压栈函数的测试: 

 

2.4 出栈函数的实现

2.4.1 void StackPop(stack* ps)函数的定义和实现

//出栈函数的实现
void StackPop(stack* ps);

实现出栈函数其实就和顺序表元素的尾删相似:

 在这里我们需要注意尾删的前提就是必须要有数据可删

bool IsEmpty(stack *ps)
{
	return ps->top == 0;
}
//出栈操作只能在栈顶进行
void StackPop(stack* ps)
{
	assert(ps);
	assert(!IsEmpty(ps));
	ps->top--;
}

 

出栈,就是将当前的栈顶元素排除在有效的数据范围之外,使栈不再包含该数据,在后面插入数据时,新的数据会直接将原来的数据覆盖,不会对栈产生什么影响。

2.4.2 出栈函数的测试:

 2.5获取栈顶元素

2.5.1 GetTop(satck* ps)函数的定义和实现

定义:

SDataType GetTop(stack *ps);

 实现:

SDataType GetTop(stack* ps)
{
	assert(ps && !IsEmpty(ps));
	return ps->arr[ps->top - 1];
}

得到栈顶元素十分的简单,这里实现他,是为下面一个能够展示栈的重要特性的函数的实现做好铺垫!!

2.5.2 获取栈顶元素测试:

2.6 展示栈中的元素

 2.6.1 StackShow 函数的定义和实现

定义:

void StackShow(stack* ps);

实现:

注意:根据栈的特性,栈中的数据不能被遍历也不能被随机访问,只能从栈顶依次取出。

void StackShow(stack* ps)
{
	assert(ps);
//所以在ps->不为NULL的前提下,依次出栈,使所有的数据都有机会成为栈顶元素,这样才能被取出
//这是栈结构的特性!!!
	while (!IsEmpty(ps))
	{
		SDataType data = GetTop(ps);
		printf("%d ", data);
		StackPop(ps);
	}
}

因此,一个栈的数据只能展示一次,之后,栈中的数据全部出栈,失去了访问权限!!

2.6.2 栈元素展示测试:

 

 接下来我们来实现最后一个栈函数。

2.7 获取栈中元素的个数

这个函数的实现十分的简单,因为栈中的元素个数就是ps->top

定义:

SDataType StackCount(stack* ps);

实现:

SDataType StackCount(stack* ps)
{
	assert(ps);
	return ps->top;
}

2.7.1 StackCount 函数的测试

到这里,栈的结构就是实现完了,虽然栈相比于前的链表和顺序表要简单,但他在数据结构中的地十分的重要,在后面的学习中,我们经常会使用栈来解决问题,所以大家一定要认真地理解栈!! 

结语

今天关于栈的学习就到这里,如果你喜欢我的内容就请不要吝啬自己的三连哟!!

咱们下期再见!!!

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

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

相关文章

# Redis 入门到精通(七)-- redis 删除策略

Redis 入门到精通(七)-- redis 删除策略 一、redis 删除策略–过期数据的概念 1、Redis 中的数据特征 Redis 是一种内存级数据库,所有数据均存放在内存中,内存中的数据可以通过TTL指令获取其状态。 XX :具有时效性…

Android Studio引入ndk编译的so库, 通过jni给Java程序使用

前言 工作要求将一个C老项目的函数用ndk打包成库给安卓同事的java程序调用。 这个任务我debuff拉满: 自己之前从来没接触过安卓开发,问了老板为什么不让安卓开发来干,老板说安卓开发不懂c,公司就我一个是懂c的。。。项目开发年…

【STM32嵌入式系统设计与开发---拓展】——1_10矩阵按键

这里写目录标题 1、矩阵按键2、代码片段分析 1、矩阵按键 通过将4x4矩阵按键的每一行依次设为低电平,同时保持其它行为高电平,然后读取所有列的电平状态,可以检测到哪个按键被按下。如果某列变为低电平,说明对应行和列的按键被按下…

day2 单机并发缓存

文章目录 1 sync.Mutex2 支持并发读写3 主体结构 Group3.1 回调 Getter3.2 Group 的定义3.3 Group 的 Get 方法 4 测试 本文代码地址: https://gitee.com/lymgoforIT/gee-cache/tree/master/day2-single-node 本文是7天用Go从零实现分布式缓存GeeCache的第二篇。 …

go 实现websocket以及详细设计流程过程,确保通俗易懂

websocket简介: WebSocket 是一种网络传输协议,可在单个 TCP 连接上进行全双工通信,位于 OSI 模型的应用层。WebSocket 协议在 2011 年由 IETF 标准化为 RFC 6455,后由 RFC 7936 补充规范。 WebSocket 使得客户端和服务器之间的数…

昇思学习打卡-21-生成式/Diffusion扩散模型

文章目录 Diffusion扩散模型介绍模型推理结果 Diffusion扩散模型介绍 关于扩散模型(Diffusion Models)有很多种理解,除了本文介绍的离散时间视角外,还有连续时间视角、概率分布转换视角、马尔可夫链视角、能量函数视角、数据增强…

《样式设计003:布局-自定义view模块》

描述:在开发小程序过程中,发现一些不错的案例,平时使用也比较多,稍微总结了下经验,以下内容可以直接复制使用,希望对大家有所帮助,废话不多说直接上干货! 一、布局-自定义view模块 …

el-popover嵌套select弹窗点击实现自定义关闭

需求 el-popover弹窗内嵌套下拉选择框,点击el-popover弹出外部区域需关闭弹窗,点击查询、重置需关闭弹窗, 实现 根据需求要自定义弹窗的关闭和显示,首先想到的是visible属性,在实现过程中经过反复的测验&#xff0…

服务级别协议SLA与运营水平协议OLA

使用美团或饿了么在线订餐时,您将体验到即时的送餐提醒服务。首先,选择您想要的食品。系统会根据餐厅与您的位置、所选食品的种类,以及下单的具体时间,计算预计的等待时间和送餐费用,并将这些信息与您共享。这种信息的…

剖析SGI-STL二级空间配置器

概述 SGI-STL与C标准库提供的STL一样&#xff0c;都通过空间配置器allocator来申请或释放容器的空间。空间配置器的作用可以参考&#xff1a;浅谈C空间配置器allocator及其重要性 // C标准库的vector template < class T, class Alloc allocator<T> > class vec…

混淆专题一——简单AA,JJ,JSFuck混淆处理办法

以AA混淆为例 网址&#xff1a;Scrape | NBA 想要获取球员的信息&#xff0c;但找不到包。 刷新页面&#xff0c;main.js中找到混淆的代码&#xff0c;这串混淆代码就是球员信息。 如何处理&#xff1a; 复制下来&#xff0c;去除最后的笑脸 (_)&#xff0c;然后在控制台打…

启智集装箱箱号识别技术,更高效快捷

在当今这个信息技术高速发展的时代&#xff0c;集装箱箱号识别技术在全球物流领域扮演着至关重要的角色。随着物流行业的不断壮大和复杂化&#xff0c;对集装箱箱号识别的准确性、效率性和便捷性提出了更高的要求。启智集装箱箱号识别技术应运而生&#xff0c;以其高效快捷的特…

python-快速上手爬虫

目录 前言 爬虫需谨慎&#xff0c;切勿从入门到入狱&#xff01; 一点小小的准备工作 直接上手爬取网页 1.获取UA伪装 2.获取url 3.发送请求 4.获取数据并保存 总结 前言 爬虫需谨慎&#xff0c;切勿从入门到入狱&#xff01; 一点小小的准备工作 对pip进行换源&#xf…

【EI检索】第二届机器视觉、图像处理与影像技术国际会议(MVIPIT 2024)

一、会议信息 大会官网&#xff1a;www.mvipit.org 官方邮箱&#xff1a;mvipit163.com 会议出版&#xff1a;IEEE CPS 出版 会议检索&#xff1a;EI & Scopus 检索 会议地点&#xff1a;河北张家口 会议时间&#xff1a;2024 年 9 月 13 日-9 月 15 日 二、征稿主题…

vue3前端开发-小兔鲜项目-面包屑导航的渲染

vue3前端开发-小兔鲜项目-面包屑导航的渲染&#xff01;今天来完成&#xff0c;一级分类页面顶部&#xff0c;面包屑导航的渲染。 1&#xff1a;完善好一级页面内的基础模块代码。 <script setup> import {getCategoryAPI} from /apis/category import {ref,onMounted} …

【知识蒸馏】YOLO object detection 逻辑蒸馏

YOLO检测蒸馏 和分类和分割蒸馏的差异&#xff1a; 由于YOLOv3检测框的位置输出为正无穷到负无穷的连续值&#xff0c;和上面将的分类离散kdloss不同&#xff0c;而且由于yolo是基于anchor的one stage模型&#xff0c;head out中99%都是背景预测。 Object detection at 200 F…

【论文阅读笔记】Hierarchical Neural Coding for Controllable CAD Model Generation

摘要 作者提出了一种CAD的创新生成模型&#xff0c;该模型将CAD模型的高级设计概念表示为从全局部件排列到局部曲线几何的三层神经代码的层级树&#xff0c;并且通过指定目标设计的代码树来控制CAD模型的生成或完成。具体而言&#xff0c;一种带有“掩码跳过连接”的向量量化变…

【BUG】已解决:To update, run: python.exe -m pip install --upgrade pip

To update, run: python.exe -m pip install --upgrade pip 目录 To update, run: python.exe -m pip install --upgrade pip 【常见模块错误】 解决办法&#xff1a; 欢迎来到英杰社区https://bbs.csdn.net/topics/617804998 欢迎来到我的主页&#xff0c;我是博主英杰&…

「MQTT over QUIC」与「MQTT over TCP」与 「TCP 」通信测试报告

一、结论 在实车5G测试中「MQTT Over QUIC」整体表现优于「TCP」&#xff0c;可在系统架构升级时采用MQTT Over QUIC替换原有的TCP通讯&#xff1b;从实现原理上基于QUIC比基于TCP在弱网、网络抖动导致频繁重连场景延迟更低。 二、测试方案 网络类型&#xff1a;实车5G、实车…

FPGA-计数器

前言 之前一直说整理点FPGA控制器应用的内容&#xff0c;今天就从计数器这个在时序逻辑中比较重要的内容开始总结一下&#xff0c;主要通过还是通过让一个LED闪烁这个简单例子来理解。 寄存器 了解计数器之前先来认识一下寄存器。寄存器是时序逻辑设计的基础。时序逻辑能够避…