【数据结构】栈 与【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;
}

以上是入栈的代码,但在入栈之前呢,我们要考虑栈空间是不是满了,也就是栈顶是不是和容量一样大,如果满了,我们需要增容,在进行增容之前,我们还要考虑topcapacity是不是都为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。因为我们初始化top0。所以遇到top大于0的情况直接返回false
    //到最后top大于0的情况if(top>0){return false;}
  • 如果全是右括号,那么在比较的时候,top一定为0,此时栈中没有元素,也就无法比较,所以遇到比较时top0的情况也直接返回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账号,我们一同成长!
(~ ̄▽ ̄)~

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

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

相关文章

攻破tensorflow,勇创最佳agent(2)---损失(loss) 准确率(accuracy)问题

实战播: 怎么判定一个模型好不好,你设置的值对不对? 需要再看几个值: 例如: model Sequential()for units in model_structure:model.add(Dense(units, activationrelu))model.add(Dropout(train_config.get(dropout_rate, 0.3)))model.add(Dense(1, activationsigmoid)) 他…

pdfh5 pdf

踩坑1&#xff1a; 渲染失败 &#xff08;1&#xff09;在vue项目中&#xff0c;读取本地的pdf文件需要放到public下static文件夹中&#xff0c;不能放在别的地方&#xff1b; &#xff08;2&#xff09;引用时&#xff0c;不能使用相对路径&#xff0c;因为使用public文件下…

6.5 模拟专题:LeetCode 38. 外观数列

1. 题目链接 LeetCode 38. 外观数列 2. 题目描述 给定一个正整数 n&#xff0c;生成外观数列的第 n 项。外观数列的定义如下&#xff1a; 第 1 项为 "1"。第 n 项是对第 n-1 项的描述。例如&#xff0c;第 2 项描述第 1 项&#xff08;"1"&#xff09;为…

什么是具身智能

具身智能&#xff08;Embodied Intelligence&#xff09;是人工智能与机器人学交叉的前沿领域&#xff0c;强调智能体通过身体与环境的动态交互实现自主学习和进化&#xff0c;其核心在于将感知、行动与认知深度融合‌。通俗地讲&#xff0c;就是机器人或者智能系统在物理环境中…

git命令使用小记(打补丁)

需求&#xff1a;需要从开发分支提取本人提交代码&#xff0c;然后合并到主分支 一、制作补丁包 mkdir -p patches for commit in $(git log commitA..commitB --author"username" --reverse --prettyformat:"%h"); do …

mapbox基础,加载popup弹出窗

👨‍⚕️ 主页: gis分享者 👨‍⚕️ 感谢各位大佬 点赞👍 收藏⭐ 留言📝 加关注✅! 👨‍⚕️ 收录于专栏:mapbox 从入门到精通 文章目录 一、🍀前言1.1 ☘️mapboxgl.Map 地图对象1.2 ☘️mapboxgl.Map style属性1.3 ☘️popup 弹出窗 api1.3.1 ☘️构造函数1.…

C++11--(1)

目录 1.列表初始化 {}初始化 C98中 C11中 内置置类型和自定义类型 创建对象也适用 std::initializer_list 2.变量类型推导 auto C98 C11 decltype nullptr 3.范围for循环 4.STL中一些变化 array 1.创建和初始化 2.访问元素 ​编辑 3.修改操作 4.支持迭代器…

Promise的状态和方法是什么?

Promise 的状态和方法 1. Promise 的状态 一个 Promise 可以处于以下三种状态之一&#xff1a; - Pending&#xff08;待定&#xff09;&#xff1a;初始状态&#xff0c;表示异步操作正在进行中&#xff0c;Promise 还没有被解决或拒绝。 - Fulfilled&#xff08;已完成&…

Windows云服务器支持哪些数据库管理系统?

Windows云服务器因其良好的兼容性和企业级支持&#xff0c;广泛用于网站托管、企业管理系统、金融应用、数据分析等场景。在这些应用中&#xff0c;数据库管理系统(DBMS)起着至关重要的作用。Windows 服务器支持多种数据库&#xff0c;包括关系型数据库(SQL)和非关系型数据库(N…

MongoDB 实际工作中应用场景

博主介绍&#xff1a;✌全网粉丝5W&#xff0c;全栈开发工程师&#xff0c;从事多年软件开发&#xff0c;在大厂呆过。持有软件中级、六级等证书。可提供微服务项目搭建与毕业项目实战&#xff0c;博主也曾写过优秀论文&#xff0c;查重率极低&#xff0c;在这方面有丰富的经验…

03 相机标定图像采集

学完本文,您将获取一下技能: 1:如何提升标定质量,如选择标定板,标定图像采集的注意事项, 2:实现标定图像自动筛选的代码 3:量产场景如何通过一张图像来标定相机 为了实现良好的标定效果,以下因素在标定数据采集前必须设置得当。 标定板选择 标定板尺寸准确材料平…

GitHub美化个人主页3D图表显示配置操作

这个功能主要是用的这个开源仓库&#xff1a;https://github.com/yoshi389111/github-profile-3d-contrib 想看效果的话&#xff0c;我的个人主页&#xff1a;https://github.com/Sjj1024 开始操作 1.创建自己的github主页属性项目——跟你github用户名一致即可&#xff0c;…

buu-jarvisoj_fm-好久不见52

格式化字符串漏洞题 x等于4x等于4​​​​​​​x等于4​​​​​​​x等于4 可以知道是第11个参数&#xff0c;%11$ 定位到这个位置&#xff0c;然后%n往这个位置写入4 1.先用pwndbg调试得到偏移量 2.查看获取x的地址 3.构造ROP链&#xff0c;发送连接 from pwn import *# …

AwesomeQt分享3(含源码)

AwesomeQt 这个项目包含了多个Qt组件的使用示例&#xff0c;旨在展示Qt各种强大功能的实现方式。 源码分享 github: awesome_Qtgitee: 后续同步 项目进度 QCustomPlot曲线控件示例 支持排序和筛选的列表控件示例 支持排序和筛选的表格控件示例 属性表示例 Dock窗口示例 自绘…

ubuntu 安装 g++

文章目录 前提一、安装 g1.1 安装1.2 验证 前提 安装 tflite_support 报错 error: subprocess-exited-with-error RuntimeError: Unsupported compiler -- at least C11 support is needed!一、安装 g 1.1 安装 # 安装编译工具链&#xff08;如g&#xff09;和依赖库 sudo …

【NLP 50、损失函数 KL散度】

目录 一、定义与公式 1.核心定义 2.数学公式 3.KL散度与交叉熵的关系 二、使用场景 1.生成模型与变分推断 2.知识蒸馏 3.模型评估与优化 4.信息论与编码优化 三、原理与特性 1.信息论视角 ​2.优化目标 3.​局限性 四、代码示例 代码运行流程 核心代码解析 抵达梦想靠的不是狂热…

使用QT画带有透明效果的图

分辨率&#xff1a;24X24 最大圆 代码: #include <QApplication> #include <QImage> #include <QPainter>int main(int argc, char *argv[]) {QImage image(QSize(24,24),QImage::Format_ARGB32);image.fill(QColor(0,0,0,0));QPainter paint(&image);…

【Unity网络编程知识】使用Socket实现简单TCP通讯

1、Socket的常用属性和方法 创建Socket TCP流套接字 Socket socketTcp new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); 1.1 常用属性 1&#xff09;套接字的连接状态 socketTcp.Connected 2&#xff09;获取套接字的类型 socketTcp.So…

青少年编程与数学 02-013 初中数学知识点 02课题、概要

青少年编程与数学 02-013 初中数学知识点 02课题、概要 一、数与代数二、图形与几何三、统计与概率四、综合与实践五、课程理念与目标 根据2022年版义务教育数学课程标准&#xff0c;初中数学知识点可以总结为以下四大领域。 一、数与代数 数与式 有理数与实数&#xff1a;理解…

深入探索 libarchive

深入探索 libarchive&#xff1a;跨平台归档处理的终极解决方案 一、背景与历史沿革 1.1 归档处理的演进之路 从1979年tar格式的诞生到现代云存储时代&#xff0c;归档技术经历了四个关键阶段&#xff1a; Unix时代&#xff1a;tar/cpio主导系统备份互联网黎明期&#xff1…