当前位置: 首页 > news >正文

数据结构入门:栈

目录

前言

1. 栈

1.1栈的概念及结构

 1.2 栈的实现

1.2.1 栈的定义

 1.2.2  栈的初始化

1.2.3 入栈

1.2.4 出栈

1.2.5  栈的元素个数

1.2.6 栈顶数据

1.2.7 栈的判空

 2.栈的应用

 2.1 题目一:括号匹配

2.1.1 思路

 2.1.2 分析

 2.1.3 题解

总结


前言

        无论你是计算机科学专业的学生、程序设计的爱好者,还是正在准备面试的求职者,本文将为你提供一份全面而深入的栈和队列指南。让我们一起探索栈和队列的双重魅力,为你的编程之路增添新的色彩。


1. 栈

1.1栈的概念及结构

栈:一种特殊的线性表,其只允许在固定的一端进行插入和删除元素操作。进行数据插入和删除操作的一端称为栈顶,另一端称为栈底

栈中的数据元素遵守后进先出LIFO(Last In First Out)的原则。

  • 压栈:栈的插入操作叫做进栈/压栈/入栈,入数据在栈顶。
  • 出栈:栈的删除操作叫做出栈。出数据也在栈顶。

 

 1.2 栈的实现

        栈的实现方法有两种,一种是顺序表的栈,另外一种就是链表实现的栈。相对而言数组的结构实现更优一些。因为数组在尾上插入数据的代价比较小,所以这里我们使用顺序表来实现栈。

         如果熟练顺序表和链表操作,那栈就会相当轻松,栈的入栈出栈就相当于是尾插尾删,顺序表尾插尾删的效率高,这也是使用顺序表实现的原因。

1.2.1 栈的定义

首先我们需要先定义一个栈:

typedef int Datatype;
typedef struct Stack
{Datatype* a;int top;int capacity;
}Stack;

 栈中有栈顶(top),有栈的容量(size),还有存储的数据(a);

 1.2.2  栈的初始化

 

void InItStack(Stack* ps)
{assert(ps);ps->top = 0;ps->a = NULL;ps->capacity = 0;
}

         这里对栈进行初始化时栈顶(top)可以置为-1,也可以置为0,置为0为了便于使用top作为数组下标插入数据。

1.2.3 入栈

        栈已经定义完成并且进行了初始化,接下来就是入栈操作。这里与顺序表的尾插略微有些不同。

void StackPush(Stack* ps, Datatype x)
{assert(ps);if (ps->top == ps->capacity){int newcapacity = (ps->capacity == 0 ? 4 : ps->capacity * 2);Datatype* tmp = (Datatype*)realloc(ps->a, sizeof(Datatype) * newcapacity);if (tmp == NULL){perror("realloc fail");exit(-1);}ps->a = tmp;ps->capacity = newcapacity;}ps->a[ps->top] = x;//top初始化为0,可以直接作为数组下标ps->top++;//入栈后top++,便于统计元素个数和下次入栈
}

        由于我们初始化时将栈的容量置为0,在这里我们在入栈操作时就需要进行开辟空间,但这里如果我们使用malloc开辟空间,就还需要进行扩容操作,所以我们直接使用realloc进行开辟空间。

 realloc在扩容时,如果原始区域空间为0,那么它的作用就类似于malloc。

         此外我们还需要有新开辟空间的大小,这里我们直接使用一个判断语句:newsize = (ps->size == 0 ? 4 : ps->size * 2);  如果size等于0就开辟4个存储数据的空间,如果不等于0就直接扩容为2倍。

1.2.4 出栈

 出栈操作就很简单了,也不需要销毁,直接进行top--:

void StackPop(Stack* ps)
{assert(ps);assert(ps->top > 0);ps->top--;
}

        但我们需要注意栈为空的情况,所有使用assert强制检查,如果为空直接报错终止程序,简单粗暴。

1.2.5  栈的元素个数

统计栈的元素个数接口也很简单,top就是栈中元素的个数

int Stacksize(Stack* ps)
{assert(ps);return ps->top;
}

1.2.6 栈顶数据

Datatype TopData(Stack* ps)
{assert(ps);assert(ps->top > 0);return ps->a[ps->top - 1];
}

这个也非常简单,需要注意栈为空的情况。

1.2.7 栈的判空

bool IsEmpty(Stack* ps)
{assert(ps);return (ps->top == 0);
}

 2.栈的应用

         这些栈的基本操作我们已经实现了,接下来我们来实际应用一下。虽然栈的基本操作更为简单,但是栈在应用时数据的结构更加复杂,前边的顺序表和链表是栈和队列的基础。

 2.1 题目一:括号匹配

        这道题目我们可以使用数组实现并解决,但我们已经了解了栈,这道题目我们就使用顺序表栈来实现。我们可以直接复制上述栈基本操作的代码。将 typedef  int  Datatype;

 改为:typedef  char  Datatype;

题目描述:

 示例:

 题目链接:

有效括号

2.1.1 思路

         这道题目的思路很明确,入栈左括号,遇到匹配的右括号就出栈。如果最终栈为空就匹配成功。但匹配失败的情况有很多,接下来我们进行逐个分析。

 2.1.2 分析

         首先是入栈,如果为左括号就入栈,为右括号就匹配出栈。这里使用if…else语句更为简洁,入栈就需要我们调用入栈的函数接口。

        其次就是匹配、出栈。但在匹配之前我们还需要考虑特殊情况,就是如果没有出栈元素就直接匹配的情况,所以首先我们需要有一个判空操作,如果匹配时栈就为空就直接匹配失败,并销毁栈,这个属于左括号与右括号数量匹配失败。

         接着就是顺序匹配失败,这里就需要我们用到栈顶元素了,如果栈顶元素与匹配的括号不匹配就直接返回false,匹配失败,销毁栈。

        最后,匹配结束,存放括号数组为空,栈也为空就匹配成功。

 2.1.3 题解

匹配括号接口:

bool isValid(char* s) {Stack st;InItStack(&st);char top;while (*s){if (*s == '(' || *s == '[' || *s == '{'){StackPush(&st, *s);}else{if(IsEmpty(&st)){DestoryStack(&st);return false;}top=TopData(&st);StackPop(&st);if((*s==']'&&top!='[')||(*s==')'&&top!='(')||(*s=='}'&&top!='{')){DestoryStack(&st);return false;}}s++;}bool ret = IsEmpty(&st);DestoryStack(&st);return ret;
}

整体代码:

typedef char Datatype;
typedef struct Stack
{Datatype* a;int top;int size;
}Stack;void InItStack(Stack* ps);void DestoryStack(Stack* ps);void StackPush(Stack* ps, Datatype x);void StackPop(Stack* ps);int Stacksize(Stack* ps);Datatype TopData(Stack* ps);bool IsEmpty(Stack* ps);void InItStack(Stack* ps)
{assert(ps);ps->top = 0;ps->a = NULL;ps->size = 0;
}void DestoryStack(Stack* ps)
{assert(ps);ps->top = ps->size = 0;free(ps->a);ps->a = NULL;
}
void StackPush(Stack* ps, Datatype x)
{assert(ps);if (ps->top == ps->size){int newsize = (ps->size == 0 ? 4 : ps->size * 2);Datatype* tmp = (Datatype*)realloc(ps->a, sizeof(Datatype) * newsize);if (tmp == NULL){perror("realloc fail");exit(-1);}ps->a = tmp;ps->size = newsize;}ps->a[ps->top] = x;ps->top++;
}
void StackPop(Stack* ps)
{assert(ps);assert(ps->top > 0);ps->top--;
}
int Stacksize(Stack* ps)
{assert(ps);return ps->top;
}
Datatype TopData(Stack* ps)
{assert(ps);assert(ps->top > 0);return ps->a[ps->top - 1];
}
bool IsEmpty(Stack* ps)
{assert(ps);return (ps->top == 0);
}
bool isValid(char* s) {Stack st;InItStack(&st);char top;while (*s){if (*s == '(' || *s == '[' || *s == '{'){StackPush(&st, *s);}else{if(IsEmpty(&st)){DestoryStack(&st);return false;}top=TopData(&st);StackPop(&st);if((*s==']'&&top!='[')||(*s==')'&&top!='(')||(*s=='}'&&top!='{')){DestoryStack(&st);return false;}}s++;}bool ret = IsEmpty(&st);DestoryStack(&st);return ret;
}

         栈相对于链表和顺序表没有那么多的操作,更为简单,但在实际应用时数据结构更加复杂,但是别担心,后续学习C++后可以直接使用现成的库函数,不需要再对栈的各个操作进行实现。


  

总结

        栈是一种重要的数据结构,它以后进先出的方式操作数据。栈在递归算法、表达式求值、函数调用等场景中发挥着重要作用。通过学习栈,我们能够更好地理解数据结构的本质和算法的设计思想。栈不仅仅是一种数据存储的方式,更是一种思维方式和问题解决的工具。无论是计算机科学的学习者、程序设计的爱好者,还是正在准备面试的求职者,通过探索栈的原理和应用,我们能够提升自己的编程能力和解决问题的能力。让我们一起深入探索栈的魅力,为编程之路增添新的色彩。最后,感谢阅读!

相关文章:

数据结构入门:栈

目录 前言 1. 栈 1.1栈的概念及结构 1.2 栈的实现 1.2.1 栈的定义 1.2.2 栈的初始化 1.2.3 入栈 1.2.4 出栈 1.2.5 栈的元素个数 1.2.6 栈顶数据 1.2.7 栈的判空 2.栈的应用 2.1 题目一:括号匹配 2.1.1 思路 2.1.2 分析 2.1.3 题解 总结 前言 无论你是计算机科学专…...

《UNUX环境高级编程》(14)高级I/O

1、引言 2、 非阻塞I/O 系统调用分为两类:低速系统调用和其他系统调用。低速系统调用是可能会使进程永远阻塞的一类系统调用,包括: 如果某些文件类型(如读管道、终端设备和网络设备)的数据并不存在,读操作…...

第5讲:如何构建类的方法

【分享成果,随喜正能量】在这个社会上,对别人好一点,多站在别人的角度考虑,不要为小事争执,不要取笑他人,不要在别人背后嚼舌根,更不能逼人太甚。凡事退一步,对你有好处。。 《VBA中…...

【TypeScript】TS接口interface类型(三)

【TypeScript】TS接口interface类型(三) 【TypeScript】TS接口interface类型(三)一、接口类型二、实践使用2.1 常规类型2.2 设置属性只读 readonly2.3 设置索引签名2.4 设置可选属性2.5 函数类型接口 一、接口类型 TypeScript中的…...

Python web实战之Django 的 RESTful API 设计详解

关键词: Python, Web 开发, Django, RESTful API 1 API的一些事儿 1.1 什么是API? API是应用程序编程接口(Application Programming Interface)的缩写。它是一种定义了不同软件组件之间交互方式的规范。API允许不同的应用程序之间进行通信和…...

Python 程序设计入门(014)—— Python 的 Lambda 函数(匿名函数)

Python 程序设计入门(014)—— Python 的 Lambda 函数(匿名函数) 目录 Python 程序设计入门(014)—— Python 的 Lambda 函数(匿名函数)一、匿名函数的定义二、匿名函数的特征三、匿…...

【MySQL系列】表约束的学习

「前言」文章内容大致是MySQL的表的约束。 「归属专栏」MySQL 「主页链接」个人主页 「笔者」枫叶先生(fy) 目录 一、MySQL表的约束1.1 空属性1.2 默认值(default)1.3 列描述(comment)1.4 zerofill1.5 主键(primary ke…...

低功耗LoRaWAN国产低功耗LoRa+RF射频前端芯片XD6500S

目录 典型应用XD6500S简介芯片特性 LoRa系列选型参考 LoRa是为低数据速率、远距离距离和超低功耗而优化的扩频协议,用于LPWAN应用程序的通信。 典型应用 一、智慧农业   智慧农业大田解决方案利用传感设备、自动化控制设备、气象站实时监测采集田间土壤墒情、气象…...

【基础IO】文件系统 {磁盘的物理结构,存储结构,逻辑结构;CHS 和 LBA 寻址方式;磁盘分区和块组;文件inode;软硬链接}

文件系统 文件分为: 内存文件:被进程打开的文件,文件被加载到内存中供进程快速读写。磁盘文件:没有被打开的文件,保存在磁盘上。磁盘文件被分门别类的存储和管理,用于支持更好的存取。 提示: …...

全角字符和半角字符

全角字符的由来 全角符号是双字节中文编码的历史遗留问题。当年在纯文本的界面中,为了让西文和中日韩的方块字对齐,就让西文字母、数字和标点也占用一个汉字的视觉空间,并使用 2 个字节存储。后来,其中的一些全角字符因为比较有用…...

【java】【经验】java: 错误: 不支持发行版本 6

前言:配置过maven之后,发现原来的一些项目运行提示java: 错误: 不支持发行版本 6或者java: 错误: 不支持发行版本 5,主要原因:是因为项目使用的Java版本和安装的Java版本不符合 目录 1 设置项目java版本 2 设置模块版本 3 set…...

Spring Boot3.0(四):Thymeleaf 使用详解

Thymeleaf 介绍 简单说,Thymeleaf 是一个跟 Velocity、FreeMarker 类似的模板引擎,它可以完全替代 JSP 。相较与其他的模板引擎,它有如下三个极吸引人的特点: 1.Thymeleaf 在有网络和无网络的环境下皆可运行,即它可以…...

杨辉三角【Java二维数组】

这个代码中,我们定义了一个二维数组nums来存储杨辉三角的每一个数字。在for循环中,我们初始化每一行的第一个和最后一个数字,并且根据上一行的数字来计算出中间的数字。 接着,我们使用两个嵌套的for循环来输出杨辉三角。第一个循…...

解决SpringBoot服务返回数据存在$ref $.data等相关问题

1、场景 ​ 在日常的开发中,我们数据接口返回数据使用了FastJson序列化数据,当返回一个数据list时候出现" r e f " " ref" " ref"".data" 等类似乱码一样的数据,当时我比较匪夷所思,我写…...

【iOS安全】开启任意app的WebView远程调试

参考:https://mp.weixin.qq.com/s/bNKxQaVrPaXsZ5BPbsXy7w (来自周智老师的公众号) 概述 Safari 有一个内置的前端调试器, 在iPhone通过局域网或者USB连接MacBook 并启用Safari 远程调试之后,前端调试器默认情况下对…...

windows下 java程序无窗口启动、无窗口启动java -jar

创建一个.bat文件,其他照抄,注意一下你自己的jar包路径和日志路径:例:java -jar C:\data\operation-1.0-SNAPSHOT.jar > C:\data\log.log 2>&1 & ------------文件内容 echo off %1 mshta vbscript:CreateObject(…...

锦程消费金融业务生变:App下架,部分自营信贷暂停

来源 | 镭射财经(leishecaijing) 被誉为消金房抵一哥的锦程消费金融,调整旗下自营信贷业务,展业回归房抵场景。 「镭射财经」独家获悉,锦程消费金融已暂停部分自营小额信贷业务,旗下锦囊贷App已经下架&am…...

Python爬虫在框架下的合规操作与风险控制

大家好!作为一名专业的爬虫代理供应商,我今天要和大家分享一些关于Python爬虫在法律框架下的合规操作与风险控制的知识。随着互联网的发展,数据爬取在商业和研究领域扮演着重要的角色,但我们也必须遵守相关法律和规定,…...

前端页面如何创建表格?table的结构、属性有哪些?

聚沙成塔每天进步一点点 ⭐ 专栏简介⭐ HTML是什么?⭐ table标签的属性⭐ 注意事项⭐ 写在最后 ⭐ 专栏简介 前端入门之旅:探索Web开发的奇妙世界 记得点击上方或者右侧链接订阅本专栏哦 几何带你启航前端之旅 欢迎来到前端入门之旅!这个专栏…...

神码ai伪原创工具【php源码】

大家好,小编为大家解答python炫酷烟花表白源代码的问题。很多人还不知道html代码烟花特效python,现在让我们一起来看看吧! 火车头采集ai伪原创插件截图: 目录 前言 环境准备 代码编写 效果展示 前言 Python实现浪漫的烟花特效 现在…...

接口测试中缓存处理策略

在接口测试中,缓存处理策略是一个关键环节,直接影响测试结果的准确性和可靠性。合理的缓存处理策略能够确保测试环境的一致性,避免因缓存数据导致的测试偏差。以下是接口测试中常见的缓存处理策略及其详细说明: 一、缓存处理的核…...

利用ngx_stream_return_module构建简易 TCP/UDP 响应网关

一、模块概述 ngx_stream_return_module 提供了一个极简的指令&#xff1a; return <value>;在收到客户端连接后&#xff0c;立即将 <value> 写回并关闭连接。<value> 支持内嵌文本和内置变量&#xff08;如 $time_iso8601、$remote_addr 等&#xff09;&a…...

CVPR 2025 MIMO: 支持视觉指代和像素grounding 的医学视觉语言模型

CVPR 2025 | MIMO&#xff1a;支持视觉指代和像素对齐的医学视觉语言模型 论文信息 标题&#xff1a;MIMO: A medical vision language model with visual referring multimodal input and pixel grounding multimodal output作者&#xff1a;Yanyuan Chen, Dexuan Xu, Yu Hu…...

苍穹外卖--缓存菜品

1.问题说明 用户端小程序展示的菜品数据都是通过查询数据库获得&#xff0c;如果用户端访问量比较大&#xff0c;数据库访问压力随之增大 2.实现思路 通过Redis来缓存菜品数据&#xff0c;减少数据库查询操作。 缓存逻辑分析&#xff1a; ①每个分类下的菜品保持一份缓存数据…...

Cloudflare 从 Nginx 到 Pingora:性能、效率与安全的全面升级

在互联网的快速发展中&#xff0c;高性能、高效率和高安全性的网络服务成为了各大互联网基础设施提供商的核心追求。Cloudflare 作为全球领先的互联网安全和基础设施公司&#xff0c;近期做出了一个重大技术决策&#xff1a;弃用长期使用的 Nginx&#xff0c;转而采用其内部开发…...

Module Federation 和 Native Federation 的比较

前言 Module Federation 是 Webpack 5 引入的微前端架构方案&#xff0c;允许不同独立构建的应用在运行时动态共享模块。 Native Federation 是 Angular 官方基于 Module Federation 理念实现的专为 Angular 优化的微前端方案。 概念解析 Module Federation (模块联邦) Modul…...

Spring Boot+Neo4j知识图谱实战:3步搭建智能关系网络!

一、引言 在数据驱动的背景下&#xff0c;知识图谱凭借其高效的信息组织能力&#xff0c;正逐步成为各行业应用的关键技术。本文聚焦 Spring Boot与Neo4j图数据库的技术结合&#xff0c;探讨知识图谱开发的实现细节&#xff0c;帮助读者掌握该技术栈在实际项目中的落地方法。 …...

C++.OpenGL (14/64)多光源(Multiple Lights)

多光源(Multiple Lights) 多光源渲染技术概览 #mermaid-svg-3L5e5gGn76TNh7Lq {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-3L5e5gGn76TNh7Lq .error-icon{fill:#552222;}#mermaid-svg-3L5e5gGn76TNh7Lq .erro…...

Python基于历史模拟方法实现投资组合风险管理的VaR与ES模型项目实战

说明&#xff1a;这是一个机器学习实战项目&#xff08;附带数据代码文档&#xff09;&#xff0c;如需数据代码文档可以直接到文章最后关注获取。 1.项目背景 在金融市场日益复杂和波动加剧的背景下&#xff0c;风险管理成为金融机构和个人投资者关注的核心议题之一。VaR&…...

Webpack性能优化:构建速度与体积优化策略

一、构建速度优化 1、​​升级Webpack和Node.js​​ ​​优化效果​​&#xff1a;Webpack 4比Webpack 3构建时间降低60%-98%。​​原因​​&#xff1a; V8引擎优化&#xff08;for of替代forEach、Map/Set替代Object&#xff09;。默认使用更快的md4哈希算法。AST直接从Loa…...