数据结构:栈和队列(上)

汇总代码见:登录 - Gitee.com

上一篇文章:数据结构:双向链表-CSDN博客

与本文相关的结构体传参:自定义类型:结构体-CSDN博客

1.栈

1.1概念和结构

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

栈底层结构选型:

栈的实现一般可以使用数组或者链表实现,相对而言,数组的结构实现更优一些。

原因:在入栈和出栈的时间复杂度均为O(1)的前提条件下,数组的内存利用率远高于链表,尤其是在存储小数据类型时。

1.2栈的实现

依旧建立三个文件:

1.2.1定义栈的结构


//定义栈的结构
typedef int STDataType;
typedef struct Stack {STDataType* arr;int top;//指向当前栈顶元素的索引--正好为栈中有效的数据个数int capacity;//栈的空间大小
}ST;

1.2.2初始化

//初始化
void STInit(ST* ps)
{ps->arr = NULL;ps->capacity = ps->size = 0;
}

调用调试:

1.2.3销毁

//销毁
void STDesTroy(ST* ps)
{if (ps->arr)free(ps->arr);ps->arr = NULL;ps->size = ps->capacity = 0;
}

1.2.4入栈

// ⼊栈
void STPush(ST* ps, STDataType x)
{assert(ps);//判断空间是否足够if (ps->top == ps->capacity){//增容int newCapacity = ps->capacity == 0 ? 4 : 2 * ps->capacity;STDataType* tmp = (STDataType*)realloc(ps->arr, newCapacity * sizeof(STDataType));if (tmp == NULL){perror("realloc fail!");exit(1);}ps->arr = tmp;ps->capacity = newCapacity;}//空间足够ps->arr[ps->top++] = x;
}

调用测试:

STPush(&st, 1);
STPush(&st, 2);
STPush(&st, 3);
STPush(&st, 4);
STPush(&st, 5);

1.2.5判空

//栈是否为空
bool STEmpty(ST* ps)
{assert(ps);return ps->top == 0;
}

1.2.6出栈

//出栈
void STPop(ST* ps)
{assert(!STEmpty(ps));ps->top--;
}

调用测试:

1.2.7取栈顶元素

top为指向当前栈顶元素的索引,所以需要-1。

//取栈顶元素
STDataType STTop(ST* ps)
{assert(!STEmpty(ps));return ps->arr[ps->top - 1];
}

调用测试:

while (!STEmpty(&st))
{//取栈顶STDataType top = STTop(&st);printf("%d ", top);//出栈STPop(&st);
}
printf("\n");

1.2.8获取栈中有效元素个数

//获取栈中有效元素个数
int STSize(ST* ps)
{assert(ps);return ps->top;
}

调用测试:

printf("size:%d\n",STSize(&st));

1.3解释assert(ps)与assert(!STEmpty)

assert(ps):保证传入的为有效的栈结构体变量。限制参数不能为空。

assert(!STEmpty):保证栈中的有效个数不能为空。

2.力扣算法题:有效的括号

20. 有效的括号 - 力扣(LeetCode)

理解题意:

思路:借助栈,遍历字符串,如果遇到左括号,就将字符串入栈,如果遇到右括号,就取栈顶,将其与右括号相比较,相同则出栈。

编程中遇到的问题:有空字符串或者遇到一开始就是右括号的,需要判断栈是否为空以及对于条件表达式的使用错误。

代码如下:

// 需要借助栈
// 定义栈的结构
typedef char STDataType;
typedef struct Stack {STDataType* arr;int top;      // 指向当前栈顶元素的索引--正好为栈中有效的数据个数int capacity; // 栈的空间大小
} ST;
// 初始化
void STInit(ST* ps) {ps->arr = NULL;ps->capacity = ps->top = 0;
}// 销毁
void STDesTroy(ST* ps) {if (ps->arr)free(ps->arr);ps->arr = NULL;ps->top = ps->capacity = 0;
}// ⼊栈
void STPush(ST* ps, STDataType x) {assert(ps);// 判断空间是否足够if (ps->top == ps->capacity) {// 增容int newCapacity = ps->capacity == 0 ? 4 : 2 * ps->capacity;STDataType* tmp =(STDataType*)realloc(ps->arr, newCapacity * sizeof(STDataType));if (tmp == NULL) {perror("realloc fail!");exit(1);}ps->arr = tmp;ps->capacity = newCapacity;}// 空间足够ps->arr[ps->top++] = x;
}// 栈是否为空
bool STEmpty(ST* ps) {assert(ps);return ps->top == 0;
}// 出栈
void STPop(ST* ps) {assert(!STEmpty(ps));ps->top--;
}// 取栈顶元素
STDataType STTop(ST* ps) {assert(!STEmpty(ps));return ps->arr[ps->top - 1];
}// 获取栈中有效元素个数
int STSize(ST* ps) {assert(ps);return ps->top;
}
// 以上为栈结构的定义与常见方法
bool isValid(char* s) {ST st;STInit(&st);char* i = s;while (*i != '\0') {// 左括号入栈if (*i == '(' || *i == '[' || *i == '{') {STPush(&st, *i);} else {// 右括号取栈顶,出栈或返回false// 若第一个为右括号,为空栈if (STEmpty(&st)) {STDesTroy(&st);return false;}char top = STTop(&st);if((top == '[' && *i != ']') || (top == '{' && *i != '}')|| (top == '(' && *i != ')')){STDesTroy(&st);return false;} //匹配-出栈STPop(&st);}i++;}// 栈是否为空//  if(STEmpty(&st))//  {//      STDesTroy(&st);//      return true;//  }// STDesTroy(&st);// return false;bool ret = STEmpty(&st) ? true : false;STDesTroy(&st);return ret;
}

最终通过测试。

本章完。

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

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

相关文章

文档抽取技术:提取非结构化文档中的关键信息,提升档案管理、金融保险和法律合规领域的效率与准确性

在信息爆炸的时代,各种机构、企业等都面临着海量非结构化文档数据的挑战。报告、合同、票据、档案记录、法律文书等文档中蕴藏着巨大的数据,但传统依靠人工阅读、理解和录入的方式效率低下、成本高昂且容易出错。文档抽取技术作为人工智能和自然语言处理…

雷柏VT1 MAX评测:原生中小手形电竞鼠标 但既不仅限于中小手形 也不仅限于电竞

一、前言:真正针对中小手形设计的电竞鼠标 雷柏第二代VT系列电竞鼠标我们已经体验过很多款了,基本都是针对大中手形设计的外形模具,只有VT3s系列是VT3系列的缩小版,更适合中小手形使用,但也只是对中大手形模具重新优化…

新客户 | TDengine 时序数据库赋能开源鸿蒙物联展区实时监控与展示

在工业物联网快速发展的当下,企业普遍面临着两大挑战:一是设备种类繁多、接入标准不一,导致系统建设容易陷入“数据孤岛”;二是实时监控和多场景联动的需求越来越强烈,但传统数据库在高频写入与多维分析上难以兼顾&…

深入剖析 ConcurrentHashMap:Java 并发编程的基石

目录 【1】Java 7 中 ConcurrentHashMap 的实现原理 1.分段锁(Segment) 2. 数据结构 3. 操作流程 【2】Java 8 中 ConcurrentHashMap 的改进 1.红黑树的引入 2.CAS 操作 3.数据结构的变化 【3】ConcurrentHashMap 的常用方法及使用示例 1.put(…

【会员专享数据】2020-2022年我国乡镇的逐日地表气压数据(Shp/Excel格式)

之前我们分享过2020—2022年中国0.01分辨率逐日地表气压栅格数据(可查看之前的文章获悉详情)!该数据是研究者张凌, 胡英屹等发布在国家冰川冻土沙漠科学数据中心平台上的高分辨地表气压数据。很多小伙伴拿到数据后反馈栅格数据不太方便使用&a…

第二阶段WinForm-12:UI控件库

1_验证码与条形码 1.1_条码基础知识 条码:条码是由一组按一定编码规则排列的条、空符号组成,用以表示一定的字符、数字及符号组成的信息 1.2_一维码 (1)Code 128 Code 128 是一种密度很高的字母数字代码系统,可对其…

别再误会了!Redis 6.0 的多线程,和你想象的完全不一样

技术解析核心误区:Redis 6.0是完全多线程的吗?No. Redis 6.0引入的多线程,只用于网络I/O的读写和数据的解析。而核心的命令执行(比如 GET, SET, HGETALL 等)依然是单线程的。Redis的架构演进,就像是把一个复…

23种设计模式——抽象工厂模式(Abstract Factory Pattern)详解

✅作者简介:大家好,我是 Meteors., 向往着更加简洁高效的代码写法与编程方式,持续分享Java技术内容。 🍎个人主页:Meteors.的博客 💞当前专栏:设计模式 ✨特色专栏:知识分享 &#x…

本地部署开源数据生成器项目实战指南

本地部署开源数据生成器项目实战指南 前言 在当今大数据和人工智能时代,高质量数据集对于模型训练和算法开发至关重要。然而,获取真实且合规的数据集往往面临隐私、成本和法律等多重挑战。合成数据生成技术为此提供了优雅的解决方案,它能够…

2025React面试题集锦

1. React 是什么?它有哪些主要特点? React 是由Facebook开发的开源JavaScript库,用于构建用户界面(UI),尤其适合开发复杂的单页应用(SPA)。 主要特点: 声明式编程:只需描述UI应该是什么样子(如return <div>Hello</div>),React会自动处理DOM更新,无需…

设计模式:迭代器模式(Iterator Pattern)

文章目录一、概念二、实例分析三、示例代码一、概念 迭代器模式 是一种 行为型设计模式&#xff0c;用于在不暴露集合对象内部结构的前提下&#xff0c;顺序访问集合中的元素。 换句话说&#xff1a; 集合类只负责数据存储&#xff1b;迭代器类负责遍历集合&#xff1b;使用者…

Vue 3 学习路线指南

阶段一:基础入门 (1-2周) 1.1 环境准备 # 安装 Node.js (推荐 18+ 版本) # 安装 Vue CLI 或使用 Vite npm create vue@latest my-vue-app cd my-vue-app npm install npm run dev1.2 Vue 3 核心概念 响应式系统:ref(), reactive(), computed() 组合式 API:setup() 函数 模…

使用 `hover:not-[:has(:hover)]` 避免「父元素和子元素同时 hover」时的样式冲突

:hover:not-(:has(:hover)) has() CSS 4 引入的“父选择器”&#xff0c;意思是&#xff1a;匹配那些里面包含某个子元素/状态的元素。 例如&#xff1a;:has(:hover) 表示「自身包含正在被 hover 的子元素」。 :not() 取反伪类&#xff0c;表示不匹配里面的条件。 比如我…

第三十天-DMA串口实验

一、DMA概述二、DMA通道注意&#xff0c;想要往串口中写数据&#xff0c;外部请求信号应该是USARTx_TX&#xff0c;当DR寄存器为空时&#xff0c;产生TX信号&#xff0c;请求DMA。反之&#xff0c;从串口中读数据&#xff0c;外部请求信号应该是USARTx_RX&#xff0c;当DR寄存器…

C/C++ 中的inline(内联函数关键字)详解

在 C/C 编程中&#xff0c;函数调用虽然带来了代码复用和可读性提升&#xff0c;但频繁调用小型函数可能会产生额外的调用开销&#xff08;call overhead&#xff09;&#xff0c;比如栈帧的建立与销毁、参数传递等。 为了减少这种开销&#xff0c;C 引入了 inline&#xff08;…

2025 年高教社杯全国大学生数学建模竞赛A 题 烟幕干扰弹的投放策略完整成品 思路 模型 代码 结果 全网首发高质量!!!

烟幕干扰弹主要通过化学燃烧或爆炸分散形成烟幕或气溶胶云团,在目标前方特定空域形成遮蔽&#xff0c;干扰敌方导弹&#xff0c;具有成本低、效费比高等优点。随着烟幕干扰技术的不断发展&#xff0c;现已有多种投放方式完成烟幕干扰弹的定点精确抛撒,即在抛撒前能精确控制烟幕…

嵌入式第四十五天(51单片机相关)

一.1.CPU、MPU、MCU、GPU&#xff1a; CPU&#xff08;中央处理器&#xff09;&#xff1a;计算机的核心部件&#xff0c;负责执行指令和处理数据。 MPU&#xff08;微处理器&#xff09;&#xff1a;通常指更通用的处理器&#xff0c;强调计算能力。 MCU&#xff08;微控制器&…

今天面了一个Java后端工程师,真的让我猛抬头

今天面了一个Java后端工程师,真的让我猛抬头啊. 现在面试不像传统的八股文面试,我更多问的都是项目场景相关的问题,但是都能回答的不错.这一点我还是很惊讶的。 不仅如此,她的技术也很扎实,对Java核心机制&#xff08;JVM、并发、集合等&#xff09;理解深入&#xff0c;回答…

拦截器和过滤器(理论+实操)

拦截器和过滤器 本文旨在夯实基础以及实战加深理解,目的是更深的理解以便掌握,希望能跟着动手敲一遍,绝对受益匪浅 在本文,我会先给出两者的区别(理论知识),随后是两者各自的实操实现 文章目录拦截器和过滤器什么是过滤器和拦截器?1.过滤器2.拦截器执行整体流程拦截器和过滤器…

HTB 赛季8靶场 - Guardian

各位好&#xff0c;最近我的kali崩掉了&#xff0c;崩掉了&#xff0c;建议大家避K 番茄C盘瘦身&#xff0c;这家伙修改了我的avrt.dll文件&#xff0c;导致virtualbox不接受我的avrt.dll文件的签名了&#xff0c;从而导致virtualbox的虚拟机环境全崩无法开机。弄了几天&#x…