数据结构入门(C语言版)栈和队列之栈的介绍及实现

news2024/11/18 13:28:38

在这里插入图片描述

  • 栈的概念
  • 栈的实现过程
  • 栈的结构体与接口的定义
    • 1、静态栈结构
    • 2、动态栈结构
    • 3、栈的接口定义
  • 栈的接口实现
    • ①初始化栈(StackInit)
    • ②入栈(StackPush)
    • ③出栈(StackPop)
    • ④栈顶(StackTop)
    • ⑤栈元素个数(StackSize)
    • ⑥检测栈是否为空(StackEmpty)
    • ⑦销毁栈(StackDestroy)
  • 结语

栈的概念

栈:一种特殊的线性表,其只允许在固定的一端进行插入和删除元素操作。进行数据插入和删除操作的一端称为栈顶,另一端称为栈底。栈中的数据元素遵守后进先出LIFO(Last In First Out)的原则。
压栈:栈的插入操作叫做进栈/压栈/入栈,入数据在栈顶
出栈:栈的删除操作叫做出栈。出数据也在栈顶
在这里插入图片描述

栈的实现过程

栈可以使用两种主要的数据结构实现:数组和链表。

使用数组实现的栈称为顺序栈(或者静态栈),其基本操作的时间复杂度为 O(1)。在实现时需要预先分配一定大小的数组作为存储空间,当栈的元素个数超过数组的大小时,需要进行扩容操作。

使用链表实现的栈称为链式栈(或者动态栈),其基本操作的时间复杂度同样为 O(1)。相比顺序栈,链式栈没有固定的大小限制,可以动态添加和删除节点,因此实现上更为灵活。

除了以上两种主要的数据结构,还有一些其他的数据结构可以用于实现栈,例如双向链表等。但是在实际应用中,数组和链表是最常见的两种栈实现方式。

栈的结构体与接口的定义

1、静态栈结构

定长的静态栈结构
代码如下:

typedef int STDataType;
#define N 10
typedef struct Stack
{
 STDataType _a[N];
 int _top; // 栈顶
}Stack;

2、动态栈结构

静态结构实际中一般不实用,所以我们主要实现下面的支持动态增长的栈
代码如下:

typedef int STDataType;
typedef struct Stack
{
	STDataType* a;
	int top;     //栈顶
	int capacity;//容量
}ST;

虽然这里使用的是动态扩容
但还是用顺序结构来实现栈
以便于初学者的理解

3、栈的接口定义

代码如下:

void StackInit(ST* ps);//初始化栈
void StackPush(ST* ps, STDataType x);//入栈
void StackPop(ST* ps);// 出栈
STDataType StackTop(ST* ps);// 获取栈顶元素
int StackSize(ST* ps);// 获取栈中有效元素个数
bool StackEmpty(ST* ps);// 检测栈是否为空,如果为空返回ture,如果不为空返回false
void StackDestroy(ST* ps);// 销毁栈

可以看到栈的接口函数比起之前的顺序表和链表都要简单很多
其实实现起来也是非常的简单,接下来我们实现这些接口

栈的接口实现

①初始化栈(StackInit)

代码如下:

void StackInit(ST* ps)
{
	assert(ps);
	ps->a = NULL;
	ps->top = 0; // ps->top = -1;
	ps->capacity = 0;
}

栈的初始化先将元素置空,栈顶指向0,当然你也可以指向-1,后面的接口函数也要做相应调整,可以根据自己习惯来设定,没有固定标准,然后容量初始化为0。

②入栈(StackPush)

代码如下:

void StackPush(ST* ps, STDataType x)
{
	assert(ps);

	if (ps->top == ps->capacity)
	{
		int newCapacity = ps->capacity == 0 ? 4 : ps->capacity * 2;
		STDataType* tmp = realloc(ps->a, sizeof(STDataType) * newCapacity);
		if (tmp == NULL)
		{
			printf("realloc fail\n");
			exit(-1);
		}
		ps->a = tmp;
		ps->capacity = newCapacity;
	}
	ps->a[ps->top] = x;
	ps->top++;
}

入栈的写法有点类似顺序表的尾插,首先是一个经典的三目操作符判断容量,容量不够则进行增容,再向内存申请空间,这里的if是为了防止申请失败而找不到中断原因写的一个提示,类似断言,将元素插入,增容,再将栈顶指向新元素,栈顶++完成入栈操作。

③出栈(StackPop)

代码如下:

void StackPop(ST* ps)
{
	assert(ps);
	assert(!StackEmpty(ps));//判断是否为空

	ps->top--;
}

这里的出栈就很简单了,先进行断言,这里的StackEmpty函数在后面实现,直接将top–就完成出栈操作了。

④栈顶(StackTop)

代码如下:

STDataType StackTop(ST* ps)
{
	assert(ps);
	assert(!StackEmpty(ps));

	return ps->a[ps->top - 1];
}

栈顶值返回只要将a[最高位下标]返回即可,如果你初始化定义的top=-1,那么这里就是
ps->a[ps->top]的值了。

⑤栈元素个数(StackSize)

代码如下:

int StackSize(ST* ps)
{
	assert(ps);

	return ps->top;
}

栈元素个数直接返回top值即可,如果你初始化定义的top=-1,那么这里就是top++的值了

⑥检测栈是否为空(StackEmpty)

代码如下:

bool StackEmpty(ST* ps)
{
	assert(ps);

	if (ps->top == 0)
	{
		return true;
	}
	else
	{
		return false;
	}
}

首先返回类型可以是int,这里我使用bool类型也是一样的,只不过我这返回的是逻辑值true或是false,如果为空返回ture,如果不为空返回false。这段代码还有更简洁的方式,
代码如下:

bool StackEmpty(ST* ps)
{
	assert(ps);
	return ps->top == 0;
}

同样返回的是逻辑值,更简洁高效。

⑦销毁栈(StackDestroy)

代码如下:

void StackDestroy(ST* ps)
{
	assert(ps);
	free(ps->a);
	ps->a = NULL;
	ps->capacity = ps->top = 0;
}

实现销毁栈,先释放元素所占空间,再置空进行初始化即可。

结语

其实不管是栈还是队列,实现方式也都很简单,虽然简单,但也是同样重要的知识点,一定要好好理解和掌握,这一节就到这里了,下一节我们再讲讲队列的概念及接口实现。

制作不易,如有不正之处敬请指出,感谢大家的来访,UU们的观看是我坚持下去的动力,在时间的催化剂下,让我们彼此都成为更优秀的人吧!!!
请添加图片描述

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

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

相关文章

【EXata】在 Visual Studio 2010 上编译与调试 EXata

一、在 VS2010 中编译 Exata 通过命令行的形式来编译调试 EXata 的方式太过麻烦,一次两次还好,时间长了慢慢就烦了,于是想着有没有什么方法能够简化这些操作,翻看手册,发现是可以在 IDE 中进行编译,于是就有…

mysql分库分表分片分区及常见问题

1.前言 MySQL单库数据量在5000万以内性能比较好,超过阈值后性能会随着数据量的增大而变弱。MySQL单表的数据量是500w-1000w之间性能比较好,超过1000w性能也会下降。 2.mysql分布式 分库 分库一般有两种目的:将库中不同表进行拆分&#xff…

英国访问学者T5签证所需相关材料

英国访问学者T5签证所需相关材料,下面就随知识人网小编一起来看一看。 1、完整填写的申请表格并亲笔签名。 2、近期护照规格白色背景彩色照片并贴在签证表格首页右上角。 3、签证后至少剩余6个月有效期的护照及申请人所持有的旧护照。 4、邀请信原件。 邀请信主要内容包括&…

基于SSM框架便利店管理系统(进销存管理系统)(java+spring+springmvc+mybatis+maven+mysql+html)

一、项目简介 本项目是一套基于SSM框架便利店管理系统(进销存管理系统),主要针对计算机相关专业的正在做毕设的学生与需要项目实战练习的Java学习者。 包含:项目源码、项目文档、数据库脚本、软件工具等,该项目附带全部源码可作为毕设使用。…

BT8918D---huart模块分析

1 huart模块 huart模块从名字可以看出,用于串口UART通讯,H的含义,目前还不知道,待了解。该模块源码未公开,已经编译成库文件,供开发者使用。 2 huart模块分析 2.1 特性 默认特性: Baud rat…

R语言处理数据——janitor包的介绍及使用

janitor功能介绍 janitor可以检查并清理脏数据,适用于R语言用户。主要功能如下: 1、完美格式化数据框的列名; 2、创建并格式化1-3个变量的频率表,可以看作是一个改进的table()函数; 3、提供用于清理和检查数据框的其他…

CCS通过dat文件导入数据计算出结果再导出数据

之前有很多博主讲过在matlab当中导出数据,到DSP里面进行计算,然后再将数据导出到matlab当中进行使用。 以前使用过matlab当中的dat数据,大家可以看一下区别: fid fopen(A.dat,wt);%将所得的数据存在A.dat当中 fprintf(fid,%g\n…

Hadoop配置

静态IP vi /etc/sysconfig/network-scripts/ifcfg-ens33 BOOTPROTOstatic ONBOOTyes IPADDR192.168.10.11 NETMASK255.255.255.0 GATEWAY192.168.138.2 DNS1114.114.114.114 DNS28.8.8.8 重启网络服务 service network restart 修改主机名 hostnamectl set-hostname ‘hadoop…

【Vue】学习笔记03-数据绑定

学习笔记03-数据绑定v-bind 单向绑定v-model 双向绑定错误案例&#xff1a;简写总结v-bind 单向绑定 <!--准备好一个容器--><div id"root">单向数据绑定&#xff1a;<input type"text" v-bind:value"name"></div><…

C++ 实现 matlab 的 buttap 函数

文章目录1. matlab buttap 函数的功能2. matlab buttap 函数的使用方法3. C实现4. 测试1. matlab buttap 函数的功能 输入模拟低通巴特沃斯滤波器的最低阶数&#xff0c;输出对应模拟低通巴特沃斯滤波器的传递函数的零点、极点、增益 其中&#xff0c;零点都为0&#xff0c;增…

详解 OSPF 协议

今天海翎光电的小编和大家聊一聊 OSPF 协议。 OSPF 是一种基于 SPF 算法的链路状态路由协议。 上图是在一个 OSPF 区域里面添入一台新的路由器的时候&#xff0c;OSPF 协议的工作过程&#xff0c;如果你能非常详细的叙述出这张图的话&#xff0c;基本上 OSPF 协议的工作过程你…

Hadoop 开启 histotryserver

Hadoop 开启 histotryserver Hadoop自带了一个历史服务&#xff0c;可以通过历史服务在web端查看已经运行完的Mapreduce作业记录&#xff0c; 默认情况下&#xff0c;Hadoop历史服务是没有启动的&#xff0c;需要自行启动。 启动后&#xff0c;在下图中点击history可跳转至历史…

论文阅读 —— Graph Self-Supervised Learning: A Survey (自监督图学习综述)

论文链接&#xff1a;https://arxiv.org/pdf/2103.00111.pdf 目录 摘要 1 引言 2 定义和符号&#xff08;notation&#xff09; 2.1 术语定义 2.2 符号 3 框架和分类 3.1 图自监督学习的统一框架和数学公式 3.2 图自监督学习的分类 3.3自我监督训练计划的分类 3.4 下游…

【通过Cpython3.9源码看看字典到底是咋回事】

字典结构 /* The ma_values pointer is NULL for a combined table* or points to an array of PyObject* for a split table*/ typedef struct {PyObject_HEAD/* Number of items in the dictionary */Py_ssize_t ma_used;/* Dictionary version: globally unique, value cha…

更灵敏、更精准、更智能,机器人避障也能“随心所欲”

对于穿梭在人群中的机器人们而言&#xff0c;避障的重要性不言而喻。 随着机器人应用越来越广泛&#xff0c;机器人的作业场景的复杂度在显著增加&#xff0c;与人类的接触也越加密集&#xff0c;这对机器人的避障功能提出了新要求&#xff0c;不仅要更加精准灵敏&#xff0c;还…

js对象赋值

js对象赋值1. 含有相同的键进行赋值2. 复制对象&#xff08;遍历赋值&#xff09;3. 复制对象&#xff08;直接赋值&#xff09;4. es6的Object.assign()方法拷贝对象 &#xff08;深拷贝&#xff0c;但没完全深&#xff09;5. JSON.parse(JSON.stringify(obj))7. 总结&#xf…

深度学习 - 39. EGES 与推荐系统用户冷启动

目录 一.引言 二.EGES 算法演进 1.淘宝推荐系统简介 2.BGE、GES、EGES 简介 2.1 用户行为序列构建 2.2 BGE / Base Graph Embedding 2.3 GES / Graph Embedding with Side Information 2.4 EGES / Enhanced Graph Embedding with Side Information 三.模型试验 1.离…

TryHackMe-Ra 2(Windows渗透测试)

Ra 2 WindCorp最近发生了安全漏洞。从那以后&#xff0c;他们加强了基础设施&#xff0c;从错误中吸取教训。但也许还不够&#xff1f;您已经设法进入了他们的本地网络… 端口扫描 循例 nmap 域名跟Ra前部基本一样, 多了个selfservice SMB枚举 smbmap enum4linux也没什么信…

CLIP:语言-图像表示之间的桥梁

最近GPT4的火爆覆盖了一个新闻&#xff1a;midjourney v5发布&#xff0c;DALLE2&#xff0c;midjourney都可以从文本中生成图像&#xff0c;这种模型要求人工智能同时理解语言和图像数据。 传统的基于人工智能的模型很难同时理解语言和图像。因为自然语言处理和计算机视觉一直…

每日一练——Day 13

前言&#xff1a; 小亭子正在努力的学习编程&#xff0c;接下来将开启编程题的练习~~ 分享的文章都是学习的笔记和感悟&#xff0c;如有不妥之处希望大佬们批评指正~~ 同时如果本文对你有帮助的话&#xff0c;烦请点赞关注支持一波, 感激不尽~~ 第一题 题目描述&#xff1a; 刷…