数据结构之栈的实现

news2024/11/28 1:46:37

𝙉𝙞𝙘𝙚!!👏🏻‧✧̣̥̇‧✦👏🏻‧✧̣̥̇‧✦ 👏🏻‧✧̣̥̇:  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.coloradmin.cn/o/1160376.html

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

相关文章

干货分享,大厂内部压测方案设计!

01、为什么要做压测 1、什么是压力测试&#xff1f; 不断向被测对象施加压力&#xff0c;测试系统在压力情况下的表现。 2、压力测试的目的是什么&#xff1f; 测试得出系统的极限性能指标&#xff0c;从而给出合理的承诺值或者容量告警&#xff1b; 找出系统的性能瓶颈&a…

5.1 实体完整性

思维导图&#xff1a; 前言 第5章 数据库完整性笔记 定义&#xff1a; 完整性&#xff1a;确保数据的正确性和相容性。 正确性&#xff1a;数据与现实世界语义相符、反映实际状况。相容性&#xff1a;同一对象在数据库的不同关系表中数据逻辑上是一致的。 示例&#xff1a; 学…

【发表案例】2区正刊,网络安全、智能系统领域,2个月3天录用,11天见刊,16天检索!

计算机类SCIE 【期刊简介】IF&#xff1a;4.0-5.0&#xff0c;JCR2区&#xff0c;中科院3区 【检索情况】SCIE 在检&#xff0c;正刊 【征稿领域】提高安全性和隐私性的边缘/云的智能方法的研究&#xff0c;如数字孪生等 【截稿日期】2023.11.30 录用案例&#xff1a;2个月…

LCD驱动程序——Framebuffer应用编程

1.LCD 操作原理 在 Linux 系统中通过 Framebuffer 驱动程序来控制 LCD。Frame 是帧的意思&#xff0c;buffer 是缓冲的意思&#xff0c;这意味着 Framebuffer 就是一块内存&#xff0c;里面保存着一帧图像。Framebuffer 中保存着一帧图像的每一个像素颜色值&#xff0c;假设 L…

怎样利用 AI 大模型,辅助研发管理与效能提升?

AI 大模型已经逐渐渗透到各行各业的应用场景中&#xff0c;在软件研发领域也不例外。在软件研发领域&#xff0c;从需求分析到软件设计&#xff0c;从软件开发到测试&#xff0c;以及最后发布上线&#xff0c;AI 在各个环节都发挥着重要作用。10 月 21 日&#xff0c;思码逸首席…

react条件渲染

目录 前言 1. 使用if语句 2. 使用三元表达式 3. 使用逻辑与操作符 列表渲染 最佳实践和注意事项 1. 使用合适的条件判断 2. 提取重复的逻辑 3. 使用适当的key属性 总结 前言 在React中&#xff0c;条件渲染指的是根据某个条件来决定是否渲染特定的组件或元素。这在构…

图解刘润2023年度演讲--进化的力量思维导图精华

大家好&#xff0c;我是老原。 周末&#xff0c;商业顾问刘润发表了年度演讲&#xff1a;《进化的力量&#xff1a;寒武纪大爆发》。 这两天出差期间&#xff0c;陆陆续续看完了这个长达4小时的演讲&#xff0c;梳理了2023年到底发生了些什么&#xff0c;现在的环境如何…… …

技术阅读周刊第三期

技术阅读周刊&#xff0c;每周更新。 历史更新 20231013&#xff1a;第一期20231022&#xff1a;第二期 Understanding The Linux TTY Subsystem URL: https://ishuah.com/2021/02/04/understanding-the-linux-tty-subsystem/本文讲解了 Linux TTY 的历史故事和来源。 TTY 是 t…

HNU-算法设计与分析-讨论课1

第一次小班讨论 &#xff08;以组为单位&#xff0c;每组一题&#xff0c;每组人人参与、合理分工&#xff0c;ppt中标记分工&#xff0c;尽量都有代码演示&#xff09; 1.算法分析题 2-10、2-15(要求&#xff1a;有ppt&#xff08;可代码演示&#xff09;) 2.算法实现题 2-4、…

蓝桥杯(C++ 扫雷)

题目&#xff1a; 思想&#xff1a; 1、遍历每个点是否有地雷&#xff0c;有地雷则直接返回为9&#xff0c;无地雷则遍历该点的周围八个点&#xff0c;计数一共有多少个地雷&#xff0c;则返回该数。 代码&#xff1a; #include<iostream> using namespace std; int g[…

【Java 进阶篇】Java中的响应输出字节数据

在Java Web应用程序开发中&#xff0c;处理响应是一个常见的任务。有时&#xff0c;您可能需要向客户端发送字节数据&#xff0c;而不仅仅是文本或HTML内容。这可以用于传输各种内容&#xff0c;如图像、文件、视频等。本文将详细介绍如何在Java中使用Response对象输出字节数据…

sql语句性能进阶必须了解的知识点——索引失效分析

在前面的文章中讲解了sql语句的优化策略 sql语句性能进阶必须了解的知识点——sql语句的优化方案-CSDN博客 sql语句的优化重点还有一处&#xff0c;那就是—— 索引&#xff01;好多sql语句慢的本质原因就是设置的索引失效或者根本没有建立索引&#xff01;今天我们就来总结一…

160. 相交链表、Leetcode的Python实现

博客主页&#xff1a;&#x1f3c6;看看是李XX还是李歘歘 &#x1f3c6; &#x1f33a;每天分享一些包括但不限于计算机基础、算法等相关的知识点&#x1f33a; &#x1f497;点关注不迷路&#xff0c;总有一些&#x1f4d6;知识点&#x1f4d6;是你想要的&#x1f497; ⛽️今…

从零开始制作一个桶装水小程序

随着互联网的发展&#xff0c;越来越多的消费者通过线上购买桶装水。为了满足这一需求&#xff0c;我们需要制作一个专门的小程序商城&#xff0c;以便用户可以方便地购买桶装水。本文将通过乔拓云平台&#xff0c;从零开始制作一个桶装水小程序&#xff0c;并详细解析制作步骤…

二、类与对象(一)

1 面向过程和面向对象初步认识 C语言是面向过程的&#xff0c;关注的是过程&#xff0c;分析出求解问题的步骤&#xff0c;通过函数调用逐步解决问题。以洗衣服为例&#xff0c;通常洗衣服会经历以下过程&#xff1a; 而C是基于面向对象的&#xff0c;关注的是对象&#xff0c…

云安全—K8s APi Server 6443 攻击面

0x00 前言 在未授权的一文中&#xff0c;详细描述了k8s api中的8080端口未授权的问题&#xff0c;那么本篇主要来说6443端口的利用。 0x01 API连接攻击面 1.匿名用户访问 匿名开放方式&#xff1a;kubectl create clusterrolebinding cluster-system-anonymous --clusterro…

信号、进程、线程、I/O介绍

文章目录 信号进程进程通信线程可/不可重入函数线程同步互斥锁条件变量自旋锁读写锁 I/O操作阻塞/非阻塞I/OI/O多路复用存储映射I/O 信号 信号是事件发生时对进程的通知机制&#xff0c;可以看做软件中断。信号与硬件中断的相似之处在于其能够打断程序当前执行的正常流程。大多…

paas配置及构建问题处理

目录 CI配置在前端中的作用 为什么生产环境需要付出额外的精力&#xff0c;进行构建&#xff1f; 服务 CI 通常分为两个主要部分&#xff1a; 构建环境&#xff1a; Dockerfile 镜像&#xff1a; CI配置在前端中的作用 开发分为三个环境&#xff1a;开发环境、测试环境和生…

QMI8658A_QMC5883L(9轴)-EVB 评估板——索引博文

0.前言 【初见姿态传感器】 在做一个4轴飞行器的时候了解到有这样一个可以控制飞行器姿态的传感器&#xff0c;而后在哔哩哔哩看到利用姿态传感做很多很好玩的作品。目前在自己的本职工作中广泛会用姿态传感器IMU的应用。 1.博文索引 【基础内容】 【QMI8658 - 姿态传感器学习…

一次性剪辑大量视频的教程,逻辑讲解,很实用

在短视频领域&#xff0c;视频剪辑的效率如何提升也成为了广大短视频创作者需要解决的问题之一。批量剪辑这个词汇也不断被提起。那么该如何自学批量视频剪辑呢&#xff1f; 想要进行批量视频剪辑&#xff0c;那就先需要一款好用的软件&#xff0c;小编这里给大家良心推荐超级…