数据结构之栈的实现

𝙉𝙞𝙘𝙚!!👏🏻‧✧̣̥̇‧✦👏🏻‧✧̣̥̇‧✦ 👏🏻‧✧̣̥̇:  Solitary-walk

      ⸝⋆   ━━━┓
     - 个性标签 - :来于“云”的“羽球人”。 Talk is cheap. Show me the code
┗━━━━━━━  ➴ ⷯ

本人座右铭 :   欲达高峰,必忍其痛;欲戴王冠,必承其重。

👑💎💎👑💎💎👑 
💎💎💎自💎💎💎
💎💎💎信💎💎💎
👑💎💎 💎💎👑    希望在看完我的此篇博客后可以对你有帮助哟

👑👑💎💎💎👑👑   此外,希望各位大佬们在看完后,可以互赞互关一下,看到必回
👑👑👑💎👑👑👑   

 今日本up主将为大家share 一下如何实现栈的基本操作

一·栈的初始化


二·栈的销毁


三·进栈


四·判断栈空


五·取栈顶元素


六·出栈


 这里姑且就以顺序栈为例

1.栈的特征就是先进后出

2.栈的构成:数据域,栈顶指针,栈的空间容量

3.注意栈顶指针只是用来指示位置的,并非真正的指针

1.初始化

因为我们采用的是顺序栈,所以这里就涉及到是用动态还是静态的数组

暂时选择动态的数组

初始状态栈空间容量是0

有个问题大家思考一下初始态我的top是为0还是为-1???,以及对应状态下所表示的逻辑意义

 

 其实对top 的初始值并没有强制性的规定只要是明白自己所写的top 的逻辑意义即可

这里就暂时以top = 0,来测试,一定要明白这一点,否则在自己进行敲代码的时候就会晕

 top = 0,表示当前top位置的下一个位置即为栈顶元素 的位置

 

void STInit(ST* pst)//栈的初始化
{
	assert(pst);//判断所传的结构体的指针是否为空
	pst->a = NULL;
	pst->capacity = pst->top = 0;// 注意这里top = 0,表示当前top位置的下一个位置即为栈顶元素 的位置
	//注意,以下所有接口函数都是基于top = 0 来执行的
}
2.销毁

 对于栈的销毁我们只需把数组所指向的 那一块空间进行free即可

free(pst->a);

void STDestroy(ST* pst)
{
	assert(pst);
	free(pst->a);//直接把这块空间free就行
	pst->a = NULL;
}
3进栈

草图如下:

1. 注意:因为top =  0,表示 当前top位置的下一个位置即为栈顶元素 的位置,此时元素的个数为0,如第一个图

在进栈的时候到底是先移top这个指针还是插入我的数据,注意此时top = 0哟

因为我是把数据放在top所对应的位置,所以就是先插入数据后移动top

若是先移动top指针后进行插入数据那所对应的topd 初始值就不是0了,而是我的top = -1

2.在插入数据的时候我们需要先判断是否为空

3.因为初始化之后我的数组空间为0,这里就需要进行开辟空间

 

  

void STPush(ST* pst,STDataType x)//进栈
{
	assert(pst);
	//先判断栈是否为空
	//	STDataType tmp = (STDataType)realloc(pst->a, sizeof(newcapacity));//注意这样是错误的
	int newcapacity ;
	if (pst->top == pst->capacity)
	{
	    newcapacity = pst->capacity == 0 ? 4 : 2 * (pst->capacity);
	//	STDataType tmp = (STDataType)realloc(pst->a, sizeof(newcapacity));//注意这样是错误的
		STDataType* tmp= (STDataType*)realloc(pst->a, newcapacity*sizeof(pst->capacity));//sizeof()求大小的时候是以字节为单位进行的
		if (tmp == NULL)
	{
		perror("realloc faail\n");//为什么不用malloc 

		return;
	}
	//来到这,扩容成功,对我的空间以及空间容量进行更新
	pst->a = tmp;
	pst->capacity = newcapacity;

	}
	//进栈操作
	pst->a[pst->top] = x;
	pst->top++;//永远指向栈顶元素下一个位置
}

 这里面有许多小点,稍不注意就会跳进坑,比如空间的开辟

还有就是栈容量初始是0,我们需要定义一个新的newcapacity来反映此时栈的容量,否则在后面空间开辟的时候就会有问题

大家可能就会写成下面的代码,这是错误滴

 

STDataType* tmp= (STDataType*)realloc(pst->a, capacity*sizeof(pst->capacity));//sizeof()求大小的时候是以字节为单位进行的

 

4.判空

 对于判空操作,我们这里只需看top == 0即可

 

bool STEmpty(ST* pst)
{
	assert(pst);
	return pst->top == 0;//没必要用if else,直接一步到位
}
5.出栈

出栈我们这里永远都是从栈顶的这个位置进行出栈,切忌,不要让我的top指针进行移动啊(也就是说,不要改变我top的值

重要的事情说三遍:永远都是从栈顶的这个位置进行出栈,永远都是从栈顶的这个位置进行出栈永远都是从栈顶的这个位置进行出栈

STDataType STTop(ST* pst)//取栈顶元素
{
	assert(pst);
	/*assert(STEmpty(pst));*/// 断言是否为空,这样写是错的
	assert(!STEmpty(pst));//正常逻辑,STEmpty(pst)应该是不为空,STEmpty(pst)这个函数返回0,!STEmpty(pst)取反操作就是1
	return  pst->a[pst->top-1];//因为top = 0,所以在用的时候先减1,指向当前栈顶元素
	//return  pst->a[pst->top--];注意这样写是错误的
}

 

return  pst->a[pst->top--];注意这样写是错误的

对于我们这些刚刚开始学习栈的小伙伴们来说,可能就会这样写,比如说,我就是之一

如果我们这里写成top--的话就会改变我们top  的值,也就是说top的位置就会变

对于我的top-1并不会改变我的top的一个值,即不会改变top的位置


Stack.c完整代码如下:

 

#define _CRT_SECURE_NO_WARNINGS 1
#include"Stack.h"
void STInit(ST* pst)//栈的初始化
{
	assert(pst);//判断所传的结构体的指针是否为空
	pst->a = NULL;
	pst->capacity = pst->top = 0;// 注意这里top = 0,表示当前top位置的下一个位置即为栈顶元素 的位置
	//注意,以下所有接口函数都是基于top = 0 来执行的
}
void STDestroy(ST* pst)
{
	assert(pst);
	free(pst->a);//直接把这块空间free就行
	pst->a = NULL;
}
void STPop(ST* pst)//出栈
{
	assert(pst);
	//assert(pst->top != 0);//为空就不能删除,也可以换种写法
	assert(!STEmpty(pst));//正常逻辑,STEmpty(pst)应该是不为空,STEmpty(pst)这个函数返回0,!STEmpty(pst)取反操作就是1
	//top 永远指向栈顶元素的下一个位置
	pst->top--;//直接top-- 就行,没有必要free

}
void STPush(ST* pst,STDataType x)//进栈
{
	assert(pst);
	//先判断栈是否为空
	//	STDataType tmp = (STDataType)realloc(pst->a, sizeof(newcapacity));//注意这样是错误的
	int newcapacity ;
	if (pst->top == pst->capacity)
	{
	    newcapacity = pst->capacity == 0 ? 4 : 2 * (pst->capacity);
	//	STDataType tmp = (STDataType)realloc(pst->a, sizeof(newcapacity));//注意这样是错误的
		STDataType* tmp= (STDataType*)realloc(pst->a, newcapacity*sizeof(pst->capacity));//sizeof()求大小的时候是以字节为单位进行的
		if (tmp == NULL)
	{
		perror("realloc faail\n");//为什么不用malloc 

		return;
	}
	//来到这,扩容成功,对我的空间以及空间容量进行更新
	pst->a = tmp;
	pst->capacity = newcapacity;

	}
	//进栈操作
	pst->a[pst->top] = x;
	pst->top++;//永远指向栈顶元素下一个位置
}
bool STEmpty(ST* pst)
{
	assert(pst);
	return pst->top == 0;//没必要用if else,直接一步到位
}
STDataType STTop(ST* pst)//取栈顶元素
{
	assert(pst);
	/*assert(STEmpty(pst));*/// 断言是否为空,这样写是错的
	assert(!STEmpty(pst));//正常逻辑,STEmpty(pst)应该是不为空,STEmpty(pst)这个函数返回0,!STEmpty(pst)取反操作就是1
	return  pst->a[pst->top-1];//因为top = 0,所以在用的时候先减1,指向当前栈顶元素
	//return  pst->a[pst->top--];注意这样写是错误的
}

Stack.h完整代码如下:

#include<stdbool.h>
#include<assert.h>
//对顺序栈而言,有三部分,数据域,栈顶指针,栈的空间容量
typedef int STDataType;//类型重命名
typedef struct STStack
{
	STDataType* a;//数据域
	int top; // 栈顶指针
	int capacity;//栈的空间容量
}ST;

void STInit(ST* pst);//栈的初始化
void STDestroy(ST* pst);//销毁
void STPush(ST* pst,STDataType x);//进栈
bool STEmpty(ST* pst);//判断栈是否为空
STDataType STTop(ST* pst);//取栈顶元素
void STPop(ST* pst);//出栈
//void STPrint(ST* pst);// 打印栈中元素,一般不这样写,不符合实际应用场景,都是一边访问一边打印,多用循环

ok以上就是我要 为大家share的一些基本操作,要是觉得还不错的话,烦劳各位大佬点个赞,互关一下呗,以便彼此留个联系方式,哈哈哈。

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

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

相关文章

springboot打包时依赖jar和项目jar分开打包;jar包瘦身

概述 最近感觉项目在部署时时jar包传输太慢了&#xff1b; 看了下jar包内容&#xff0c;除了项目代码&#xff0c;其余大部分都是依赖jar&#xff1b; 平时改动较多的只是项目代码&#xff0c;依赖jar改动比较少&#xff1b; 所以就在想能不能分开打包&#xff1b;这样只部署项…

ONNX的结构与转换

ONNX的结构与转换 1. 背景2. ONNX结构分析与修改工具2.1. ONNX结构分析2.2. ONNX的兼容性问题2.3. 修改ONNX模型 3. 各大深度学习框架如何转换到ONNX&#xff1f;3.1. MXNet转换ONNX3.2. TensorFlow模型转ONNX3.3. PyTorch模型转ONNX3.4. PaddlePaddle模型转ONNX3.4.1. 简介3.4…

钉钉会议室无需API开发轻松连接OA、电商、营销、CRM、用户运营、推广、客服等近千款系统

钉钉会议室支持成员管理、主持人权限管理、高级会控、组织内会议全员静音、共享权限控制等会议管理能力&#xff0c;确保会议安全可控的进行。 官网&#xff1a;https://page.dingtalk.com/wow/z/dingtalk/Rax/RoomsIntro 集简云无代码集成平台&#xff0c;轻松连接钉钉会议室…

动态规划算法实现------转换(编辑、变换)问题

目录 一、字符串转换问题 1.1问题 1.2确定动态规则(DP、状态转移方程)、初始值 (1)插入操作实现状态转移 (2)删除操作实现状态转移 (3)替换操作实现状态转移 (4)初始值 1.3动态规划算法代码实现 (1)完整代码 (2)程序速度优化 二、矩阵变换问题 2.1问题 2.2矩阵乘法 (1)矩阵相乘…

实验记录之——git push

平时做开发的时候经常push代码不成功&#xff0c;如下图 经好友传授经验&#xff0c;有如下方法 Win cmd使用Clash&#xff08;端口是7890&#xff09;代理操作&#xff0c;在cmd中输入&#xff1a; set http_proxy127.0.0.1:7890 set https_proxy127.0.0.1:7890Linux export …

Elasticsearch:在你的数据上训练大型语言模型 (LLM)

过去的一两年&#xff0c;大型语言模型&#xff08;LLM&#xff09;席卷了互联网。 最近 Google 推出的 PaLM 2 和 OpenAI 推出的 GPT 4激发了企业的想象力。 跨领域构思了许多潜在的用例。 多语言客户支持、代码生成、内容创建和高级聊天机器人都是一些例子。 这些用例要求 LL…

echarts的图表立体感——实现立体柱状图和立体饼图的详细教程

&#x1f602;博主&#xff1a;小猫娃来啦 &#x1f602;文章核心&#xff1a;使用echarts实现立体柱状图和立体饼图的详细教程 文章目录 简单介绍立体柱状图和立体饼图环境配置实现立体柱状图实现立体饼图总结 简单介绍立体柱状图和立体饼图 立体柱状图和立体饼图是数据可视化…

Youtube DNN:Deep Neural Networks for YouTube Recommendations

1.介绍 本文主要解决的三个挑战&#xff1a; 大规模的推荐场景&#xff0c;能够支持分布式训练和提供有效率的服务。不断更新的新物料。稀疏的用户行为&#xff0c;包含大量的噪声。 2.推荐系统 文章包含推荐系统的两阶段模型&#xff1a;召回和排序。 召回网络根据用户的历…

【JAVA学习笔记】58 - 泛型

项目代码 https://github.com/yinhai1114/Java_Learning_Code/tree/main/IDEA_Chapter15/src/com/yinhai/generic_ https://github.com/yinhai1114/Java_Learning_Code/tree/main/IDEA_Chapter15/src/com/yinhai/customgeneric_ 一、泛型的入门和好处 1)请编写程序&#xff0c;…

创新工具箱!重塑手机页面原型设计体验

在2024年&#xff0c;随着移动设备的普及和用户对移动体验的要求不断提升&#xff0c;手机页面原型设计工具变得越来越重要。在这篇文章中&#xff0c;我将为您推荐几款在2024年非常流行且值得一试的手机页面原型设计工具。 Pixso Pixso是一款基于云端的协作设计工具&#xf…

三相电表逆相序是由于负载造成的吗

大家好&#xff0c;最近有蛮多客户问三相电表逆相序是由于负载造成的吗&#xff1f;那么答案是&#xff1a;是的&#xff0c;但是负载只是导致三相电表出现逆向序的原因之一&#xff0c;下面&#xff0c;小编来带大家一起了解下三相电表出现逆相序的原因有哪些&#xff0c;一起…

比亚迪今年的薪资。。

大家或许已经对比亚迪在西安的宣讲会有所耳闻&#xff0c;那场面真的是座无虚席。如果你稍微迟到了一些&#xff0c;那么你可能只能在门外或是走廊听了。 事实上&#xff0c;许多人早早地抵达了&#xff0c;只要稍微晚到&#xff0c;就可能错过了室内的位置。 更令人震惊的是&…

Go语言集成开发环境(IDE):GoLand 2023中文

GoLand 2023是一款由JetBrains开发的现代化、功能丰富的Go语言集成开发环境&#xff08;IDE&#xff09;。它提供了智能代码提示和自动完成、强大的内置调试器以及代码重构工具&#xff0c;帮助开发者提高编码效率并确保代码质量。GoLand 2023还支持多种版本控制系统&#xff0…

QT 信号和槽

不讲那么多大道理&#xff0c;直接上 前面用Python QT 发现在线程或者定时器里操作控件&#xff0c;有很大概率导致程序闪退&#xff0c;所以如果想要在线程和定时器中操作控件&#xff0c;需要自定义信号和槽&#xff0c;不知道CQT会不会有这个问题&#xff0c;这个经验不是很…

MySQL的3种索引合并优化⭐️or到底能不能用索引?

MySQL的3种索引合并优化⭐️or到底能不能用索引? 前言 前文我们讨论过MySQL优化回表的多种方式&#xff1a;索引条件下推ICP、多范围读取MRR、覆盖索引等 这篇文章我们来聊聊MySQL提供的另一种优化回表的手段&#xff1a;index merge 索引合并 在阅读本文前&#xff0c;你…

集简云slack(自建)无需API开发轻松连接OA、电商、营销、CRM、用户运营、推广、客服等近千款系统

slack是一个工作效率管理平台&#xff0c;让每个人都能够使用无代码自动化和 AI 功能&#xff0c;还可以无缝连接搜索和知识共享&#xff0c;并确保团队保持联系和参与。在世界各地&#xff0c;Slack 不仅受到公司的信任&#xff0c;同时也是人们偏好使用的平台。 官网&#x…

移动云:IDC容器安全行业代表,领跑云原生安全技术演进

近日&#xff0c;全球领先的IT电信市场研究和咨询公司IDC发布了《中国容器安全市场洞察&#xff0c;2023》报告&#xff08;简称《报告》&#xff09;&#xff0c;分析了国内容器安全市场现状以及主要供应商并提供了行动建议。移动云云原生应用安全获得本次IDC报告认可&#xf…

5.1 创建和销毁线程

方法 pthread_create(thread, attr, start_routine, arg)pthread_exit(status)pthread_cancel(thread)pthread_attr_init(attr)pthread_attr_destroy(attr) 创建线程 最开始main()程序只有一个默认的线程&#xff0c;其他的线程需要由编程人员显式创建。pthread_create()可以…

如何在麒麟上安装 ONLYOFFICE 桌面编辑器

我们很高兴地告诉大家&#xff0c;ONLYOFFICE 桌面编辑器现已上架麒麟软件商店。请阅读下文了解详情。 关于麒麟 麒麟是一款国产操作系统&#xff0c;主要是为了满足中国市场的需求和偏好而设计的。 它能够与各种硬件平台和软件应用程序的广泛兼容&#xff0c;因而受到认可。…

HALCON的综合应用案例【01】: 3D 算法处理在 Visual Studio 2019 C# 环境中的集成实例

前言: HALCON 为一款比较流行的商业视觉处理软件,他提供了多种开发的模式,可以在HALCON中开发,也可以将HALCON的设计通过导出库的形式集成到其他开发环境里面,以方便系统集成。本文为笔者自己的一个3D 视觉检测项目,利用HALCON的3D 库开发算法,然后,将算法集成到 MS-V…
最新文章