【数据结构】栈 与【LeetCode】20.有效的括号详解
目录
- 一、栈
- 1、栈的概念及结构
- 2、栈的实现
- 3、初始化栈和销毁栈
- 4、打印栈的数据
- 5、入栈操作---栈顶
- 6、出栈---栈顶
- 6.1栈是否为空
- 6.2出栈---栈顶
- 7、取栈顶元素
- 8、获取栈中有效的元素个数
- 二、栈的相关练习
- 1、练习
- 2、AC代码
个人主页,点这里~
数据结构专栏,点这里~

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

以上这张图片很好的反映了栈的结构,及出入栈的顺序。
2、栈的实现
栈的实现⼀般可以使用数组或者链表实现,相对而言数组的结构实现更优⼀些。因为数组在尾上插入,数据的代价比较小。数组在尾上插入整型数据只需要增加4个字节,但链表增加的字节就大的多了。
typedef int STDataType;
typedef struct Stack
{STDataType* arr;int top; //指向栈顶位置int capacity;//数据容量
}ST;
3、初始化栈和销毁栈
我们已经知道用什么方法实现栈,并且已经将栈的结构写出来了,接下来就该初始化了。
初始化:
void StackInit(ST* ps)
{ps->arr = NULL;ps->top = 0;ps->capacity = 0;
}
初始化栈十分简单,只需把arr数组置为空,栈顶top和容量capacity置为0即可。
销毁:
void StackDestroy(ST* ps)
{if (ps->arr)//如果不为NULL{ps->arr = NULL;}ps->top = ps->capacity = 0;
}
以上就是栈的初始化以及销毁的代码了,和我们讲顺序表的时候差不多。
4、打印栈的数据
void SPrint(ST* ps)
{assert(ps);for (int i = 0;i < ps->top;i++){printf("%d", ps->arr[i]);if (i < ps->top - 1){printf("->");}}
}
5、入栈操作—栈顶
我们知道栈只能从栈顶入数据和出数据,所以我们就大概知道如何入栈了。
//入栈---栈顶
void StackPush(ST* ps, STDataType x)
{assert(ps);if (ps->top == ps->capacity)//如果栈空间满了就增容{int newcapacity = ps->capacity == 0 ? 4 : 2 * ps -> capacity;STDataType* set = (STDataType*)realloc(ps->arr,sizeof(STDataType) * newcapacity);if (set == NULL){perror("realloc fail!");return 1;}ps->arr = set;ps->capacity = newcapacity;}ps->arr[ps->top++] = x;
}
以上是入栈的代码,但在入栈之前呢,我们要考虑栈空间是不是满了,也就是栈顶是不是和容量一样大,如果满了,我们需要增容,在进行增容之前,我们还要考虑top和capacity是不是都为0,如果为0的话,我们要把容量大小置为4,否则的话容量扩大为二倍。
测试代码:
#include "Stack.h"void test()
{ST plist;StackInit(&plist);StackPush(&plist, 1);StackPush(&plist, 2);StackPush(&plist, 3);SPrint(&plist);
}int main()
{test();return 0;
}
测试结果:

6、出栈—栈顶
在实现出栈之前我们要考虑栈里面的元素是否为空,如果为空就终止操作,所以我们先写一个判空函数,这样我们就可以在出栈之前知道栈是否为空了。
6.1栈是否为空
bool StackEmpty(ST* ps)
{assert(ps);return ps->top == 0;
}
这里用到了bool类型记得要加上#include<stdbool.h>头文件。
6.2出栈—栈顶
void StackPop(ST* ps)
{assert(!StackEmpty(ps));ps->top--;
}
这里实现出栈是只需要实现top减一即可,因为我们不会访问top之后的元素。
7、取栈顶元素
STDataType StackTop(ST* ps)
{assert(!StackEmpty(ps));return ps->arr[ps->top - 1];
}
这里取栈顶元素时,我们只需要判断一下栈是否为空,再将栈顶元素返回即可。
8、获取栈中有效的元素个数
int StackSize(ST* ps)
{return ps->top;
}
以上就是栈的常见操作,接下来让我们做一道练习题试一下吧!
二、栈的相关练习
1、练习
题目描述:

题目链接,点击这里~
没有做过的,可以先看题目思考一下,下面会给出题解。
我们根据题目描述可以知道题目让我们判断括号匹配是否正确,如果正确返回true,如果错误返回false。
我们在利用栈思想(先进后出)进行求解的时候,可以当遇到左括号让它入栈,然后再遇到右括号的时候让栈顶的和它匹配(在括号匹配的情况下,最后出现的左括号总与最先出现的右括号匹配),如果不匹配就一定是非法的,返回false,如果都匹配的话就是合法的,返回true。这里可以用数组模拟栈。我们在遇到左括号例如'('时我们可以在栈中保存')',这样在比较的时候容易比较。
- 特殊情况一:
字符数目是奇数,只要是奇数就一定不匹配,直接返回false。
int len=strlen(s);if(len%2==1){return false;}
- 特殊情况二:
如果全是左括号,那么最后栈顶top一定大于0,而如果是正确匹配的情况下,到最后top肯定是0。因为我们初始化top为0。所以遇到top大于0的情况直接返回false。
//到最后top大于0的情况if(top>0){return false;}
- 如果全是右括号,那么在比较的时候,
top一定为0,此时栈中没有元素,也就无法比较,所以遇到比较时top为0的情况也直接返回false。
if(top==0||s[i]!=stack[--top]){return false;}
2、AC代码
AC代码:
bool isValid(char* s)
{int len=strlen(s);if(len%2==1){return false;}char stack[10005];int top=0;int i;for(i=0;i<len;i++){if(s[i]=='('){stack[top++]=')';}else if(s[i]=='['){stack[top++]=']';}else if(s[i]=='{'){stack[top++]='}';}else{if(top==0||s[i]!=stack[--top]){return false;}}}if(top>0){return false;}return true;
}
总结:
以上就是本期博客分享的全部内容啦!如果觉得文章还不错的话可以三连支持一下,你的支持就是我前进最大的动力!
技术的探索永无止境! 道阻且长,行则将至!后续我会给大家带来更多优质博客内容,欢迎关注我的CSDN账号,我们一同成长!
(~ ̄▽ ̄)~
相关文章:
【数据结构】栈 与【LeetCode】20.有效的括号详解
目录 一、栈1、栈的概念及结构2、栈的实现3、初始化栈和销毁栈4、打印栈的数据5、入栈操作---栈顶6、出栈---栈顶6.1栈是否为空6.2出栈---栈顶 7、取栈顶元素8、获取栈中有效的元素个数 二、栈的相关练习1、练习2、AC代码 个人主页,点这里~ 数据结构专栏,…...
实时目标检测新突破:AnytimeYOLO——随时中断的YOLO优化框架解析
目录 一、论文背景与核心价值 二、创新技术解析 2.1 网络结构革新:Transposed架构 2.2 动态路径优化算法 三、实验结果与性能对比 3.1 主要性能指标 3.2 关键发现 四、应用场景与部署实践 4.1 典型应用场景 4.2 部署注意事项 五、未来展望与挑战 一、论文背景与核心…...
Redis设计与实现-哨兵
哨兵模式 1、启动并初始化sentinel1.1 初始化服务器1.2 使用Sentinel代码1.3 初始化sentinel状态1.4 初始化sentinel状态的master属性1.5 创建连向主服务器的网络连接 2、获取主服务器信息3、获取从服务器的信息4、向主从服务器发送信息5、接受主从服务器的频道信息6、检测主观…...
C++进阶——封装哈希表实现unordered_map/set
与红黑树封装map/set基本相似,只是unordered_map/set是单向迭代器,模板多传一个HashFunc。 目录 1、源码及框架分析 2、模拟实现unordered_map/set 2.1 复用的哈希表框架及Insert 2.2 iterator的实现 2.2.1 iteartor的核心源码 2.2.2 iterator的实…...
第4.1节:使用正则表达式
1 第4.1节:使用正则表达式 将正则表达式用斜杠括起来,就能用作模式。随后,该正则表达式会与每条输入记录的完整文本进行比对。(通常情况下,它只需匹配文本的部分内容就能视作匹配成功。)例如,以…...
【算法day25】 最长有效括号——给你一个只包含 ‘(‘ 和 ‘)‘ 的字符串,找出最长有效(格式正确且连续)括号子串的长度。
32. 最长有效括号 给你一个只包含 ‘(’ 和 ‘)’ 的字符串,找出最长有效(格式正确且连续)括号子串的长度。 https://leetcode.cn/problems/longest-valid-parentheses/ 2.方法二:栈 class Solution { public:int longestValid…...
Jenkins + CICD流程一键自动部署Vue前端项目(保姆级)
git仓库地址:参考以下代码完成,或者采用自己的代码。 南泽/cicd-test 拉取项目代码到本地 使用云服务器或虚拟机采用docker部署jenkins 安装docker过程省略 采用docker部署jenkins,注意这里的命令,一定要映射docker路径,否则无…...
C 语言的未来:在变革中坚守核心价值
一、从 “古老” 到 “长青”:C 语言的不可替代性 诞生于 20 世纪 70 年代的 C 语言,历经半个世纪的技术浪潮,至今仍是编程世界的 “基石语言”。尽管 Python、Java 等高级语言在应用层开发中占据主流,但 C 语言在系统级编程和资…...
一款超级好用且开源免费的数据可视化工具——Superset
认识Superset 数字经济、数字化转型、大数据等等依旧是如今火热的领域,数据工作有一个重要的环节就是数据可视化。 看得见的数据才更有价值! 现如今依旧有多数企业号称有多少多少数据,然而如果这些数据只是呆在冷冰冰的数据库或文件内则毫无…...
Vue3组合式API与选项式API的核心区别与适用场景
Vue.js作为现代前端开发的主流框架之一,在Vue3中引入了全新的组合式API(Composition API),与传统的选项式API(Options API)形成了两种不同的开发范式。在当前开发中的两个项目中分别用到了组合式和选项式,故记录一下。本文将全面剖析这两种AP…...
RedHatLinux(2025.3.22)
1、创建/www目录,在/www目录下新建name和https目录,在name和https目录下分别创建一个index.htm1文件,name下面的index.html 文件中包含当前主机的主机名,https目录下的index.htm1文件中包含当前主机的ip地址。 (1&…...
【C++篇】类与对象(上篇):从面向过程到面向对象的跨越
💬 欢迎讨论:在阅读过程中有任何疑问,欢迎在评论区留言,我们一起交流学习! 👍 点赞、收藏与分享:如果你觉得这篇文章对你有帮助,记得点赞、收藏,并分享给更多对C感兴趣的…...
深搜专题13:分割回文串
描述 给你一个字符串 s,请你将 s 分割成一些子串,使每个子串都是回文串。返回 s 所有可能的分割方案数。 例如: 输入:“aab” 输出:2 2种方案数是[“a”,“a”,“b”]和[“aa”,“b”] 输入描述 一个字符串 s&#…...
OGG故障指南:OGG-01163 Bad column length (xxx) specified for column
报错 OGG-01163 Bad column length (xxx) specified for column AAA in table OWNER.TABLE, maximum allowable length is yyy原因 源端修改了字段长度。 虽然源端和目标端的长度已经通过DDL语句修改到一致,在extract进程未重启的情况下,生成的trail文…...
智慧运维平台:赋能未来,开启高效运维新时代
在当今数字化浪潮下,企业IT基础设施、工业设备及智慧城市系统的复杂度与日俱增,传统人工运维方式已难以满足高效、精准、智能的管理需求。停机故障、低效响应、数据孤岛等问题直接影响企业运营效率和成本控制。大型智慧运维平台(AIOps, Smart…...
基于大语言模型的智能音乐创作系统——从推荐到生成
一、引言:当AI成为音乐创作伙伴 2023年,一款由大语言模型(LLM)生成的钢琴曲《量子交响曲》在Spotify冲上热搜,引发音乐界震动。传统音乐创作需要数年专业训练,而现代AI技术正在打破这一壁垒。本文提出一种…...
Reactive编程:什么是Reactive编程?Reactive编程思想
文章目录 **1. Reactive编程概述****1.1 什么是Reactive编程?****1.1.1 Reactive编程的定义****1.1.2 Reactive编程的历史****1.1.3 Reactive编程的应用场景****1.1.4 Reactive编程的优势** **1.2 Reactive编程的核心思想****1.2.1 响应式(Reactive&…...
深度剖析:U盘突然无法访问的数据拯救之道
一、引言 在数字化办公与数据存储日益普及的当下,U盘凭借其小巧便携、即插即用的特性,成为了人们工作、学习和生活中不可或缺的数据存储工具。然而,U盘突然无法访问这一棘手问题却时常困扰着广大用户,它不仅可能导致重要数据的丢失…...
23种设计模式中的备忘录模式
在不破坏封装的前提下,捕获一个对象的内部状态,并允许在对象之外保存和恢复这些状态。 备忘录模式,主要用于捕获并保存一个对象的内部状态,以便将来可以恢复到该状态。 备忘录的模式主要由三个角色来实现:备忘录、发起…...
蓝桥杯-特殊的三角形(dfs/枚举/前缀和)
思路分析 深度优先搜索(DFS)思路 定义与参数说明 dfs 函数中,last 记录上一条边的长度,用于保证新选边长度大于上一条边,实现三边互不相等 。cnt 记录已选边的数量,当 cnt 达到 3 时,就构成了…...
我的编程之旅:从零到无限可能
一、自我介绍 大家好,我是望云山,一名智能科学与技术专业的大一学生 痴迷于用代码解决现实问题,尤其是自动化工具开发与智能硬件交互方向 2024年偶然用Python写了一个自动整理文件的脚本,第一次感受到“代码即魔法”的震撼 二、…...
一文详解k8s体系架构知识
0.云原生 1.k8s概念 1. k8s集群的两种管理角色 Master:集群控制节点,负责具体命令的执行过程。master节点通常会占用一股独立的服务器(高可用部署建议用3台服务器),是整个集群的首脑。 Master节点一组关键进程…...
wx162基于springboot+vue+uniapp的在线办公小程序
开发语言:Java框架:springbootuniappJDK版本:JDK1.8服务器:tomcat7数据库:mysql 5.7(一定要5.7版本)数据库工具:Navicat11开发软件:eclipse/myeclipse/ideaMaven包&#…...
Baklib内容中台的核心优势是什么?
智能化知识管理引擎 Baklib的智能化知识管理引擎通过多源数据整合与智能分类技术,实现企业知识资产的自动化归集与动态更新。系统内置的语义分析算法可自动识别文档主题,结合自然语言处理技术生成结构化标签体系,大幅降低人工标注成本。针对…...
【C++】C++11介绍列表初始化右值引用和移动语义
个人主页 : zxctscl 如有转载请先通知 文章目录 1. C11简介2. 统一的列表初始化2.1{}初始化2.2 std::initializer_list 3. 声明3.1 auto3.2 decltype3.3 nullptr 4. 范围for循环4.1 范围for的语法4.2 范围for的使用条件 5. STL中一些变化6. 右…...
搜广推校招面经六十一
美团推荐算法 一、ANN算法了解么?说几种你了解的ANN算法 ANN 近似最近邻搜索(Approximate Nearest Neighbor Search)算法 1.1. KD-Tree(K-Dimensional Tree,K 维树) 类型: 空间划分数据结构适用场景: 低…...
人工智能与软件工程结合的发展趋势
AI与软件工程的结合正在深刻改变软件开发的流程、工具和方法,其发展方向涵盖了从代码生成到系统维护的整个生命周期。以下是主要的发展方向和技术趋势: 1. 软件架构体系的重构 从“面向过程”到“面向目标”的架构转型: AI驱动软件设计以目标…...
nacos 外置mysql数据库操作(docker 环境)
目录 一、外置mysql数据库原因: 二、数据库准备工作 三、构建nacos容器 四、效果展示 一、外置mysql数据库原因: 想知道nacos如何外置mysql数据库之前,我们首先要知道为什么要外置mysql数据库,或者说这样做有什么优点和好处&am…...
动力电池热失控:新能源汽车安全的“隐形火山”如何预防?
一、火山爆发前的征兆:热失控的演化逻辑 在锂离子电池内部,正负极材料与电解液的 “亲密接触” 本是能量转换的基石,但当温度突破 180℃临界点,电解液就像被点燃的火药库。以三元锂电池为例,镍钴锰氧化物在 200℃以上…...
【数电】半导体存储电路
组合逻辑电路输入和输出之间是确定关系,与之前的历史记录没有任何关系。时序逻辑电路则有相应的存储元件,要把之前的状态保存起来。 要构成时序逻辑电路,必须要有相应的存储元件,第五章讲述相应的存储元件 一、半导体存储电路概…...
