算法与数据结构(三)--栈

一.栈的基本概念

栈是一种特殊的表,这种表只在表首进行插入和删除操作。
因此,表首对于栈来说具有特殊的意义,称为栈顶。相应的,表尾称为栈底。不含任何元素的栈称为空栈。
栈的修改遵循后进先出的原则,Last In First Out,可以想象成一个水桶。

二.常用的栈运算

栈也是一个抽象数据类型。常用的栈运算如下:
(1)StackEmpty(S):测试栈S是否为空
(2)StackFull(S):测试栈S是否以满
(3)StackTop(S):返回栈S的栈顶元素
(4)Push(x,S):在栈S的栈顶插入元素x,简称为将元素x入栈
(5)Pop(S):删除并返回栈S的栈顶元素,简称为抛栈

三.栈的实现

1.用数组实现栈

实现与表类似,只不过要实现的运算不同。略

2.用指针实现栈

用这种方法实现的栈也叫做链栈。
因为栈是一种特殊的表,所以实现与表类似,只不过要实现的运算不同。

四.栈的应用

例一:在对用高级语言编写的程序进行编译时会遇到表达式或字符串的括号匹配问题。


在从左到右逐个字符对给定的表达式expr进行扫描的过程中,将所遇到的左括号存入一个栈中。每当扫描到一个有括号时,如果栈非空,就将其与栈顶的左括号想匹配,并从栈顶删除该左括号;若栈已空,则所遇到的右括号不匹配。在完成对表达式的扫描后,若栈非空,则留在栈中的左括号均不匹配。


例二:直方图最大面积矩形问题--单调栈

直方图最大面积矩形问题要找出包含在这个直方图中边平行于坐标轴的最大面积矩形。每个直条的宽度均为1。如上,当给出的h=[6,2,5,4,5,1,6]时,最大面积矩形的面积是12。
设最大面积矩形为s,则易知与其相交的直条中高度最小的直条整个包含在s中。而对直方图中的每个高度为h[i]的直条i都有一个包含该直条的最大矩形,设其面积为a[i]。显而易见,直方图最大面积矩形s的面积是当i取1到n的a[i]中的最大值。因此,关键问题是对每个高度为h[i]的直条i,计算包含该直条的最大矩形a[i]。(化归转化)
要计算a[i],就要计算直条i的左侧距i最近的高度小于h[i]的直条位置l(i),和直条i的右侧距i最近的高度小于h[i]的直条位置r(i)。由l(i)和r(i)的值可得,a[i]=h[i]*(r(i)-l(i)-1)。为此目的,可以用一个栈stk来存储直条i的位置l(i)。从左到右依次考察直条,并根据栈顶元素的值来计算a[i]。

int histo() {//首先,创建一个栈 stk,并初始化为空栈。 Stack stk=StackInit(n);//定义变量 i 和 max,分别表示遍历直方图数组的索引和最大矩形面积。int i=0,max=0;//进入循环,循环条件是 i < n,即遍历直方图数组,遍历的直方图遇到比它大的栈顶,栈顶弹出,直到遇到比它小的才入栈。 while(i<n) {//在循环内部,首先检查栈是否为空或者当前直方图高度大于等于栈顶元素所对应的高度。//如果满足条件,则将当前索引 i 入栈,并将 i 加 1。if(StackEmpty(stk)||h[StackTop(stk)]<=h[i])Push(i++,stk);//如果不满足条件,说明当前直方图高度小于栈顶元素所对应的高度。此时需要计算以栈顶元素为高度的矩形的面积。	else {//首先,将栈顶元素出栈,并保存在变量 tmp 中。int tmp=StackTop(stk);Pop(stk);//计算矩形的面积,即高度乘以宽度,保存在变量 a 中。//怎么计算矩形的宽度呢? //如果栈为空,则宽度为当前索引 i //【因为如果栈为空,说明出栈的元素为第一个元素,那么宽度刚好就是索引1,//如果不是,也就是说右侧的直方图都出栈,右侧的直方图高度递减,宽度也为索引】 //否则宽度为当前索引 i 减去栈顶元素对应的索引再减去 1。//【简单说如果不为空,此时栈中的直方图是单调递增的,但考虑那些弹出的直方图都比此时直方图小,所以就为i-StackTop(stk)-1】 int a=h[tmp]*(StackEmpty(stk)?i:i-StackTop(stk)-1);//如果当前矩形面积 a 大于最大面积 max,则更新 max 的值。if(max<a)max=a;}}//此时栈中剩余直方图是单调递增的,重新遍历 //保证对每个高度为h[i]的直条i,计算包含该直条的最大矩形awhile(!StackEmpty(stk)) {//下面操作和上面一样 int tmp=StackTop(stk);Pop(stk);int a=h[tmp]*(StackEmpty(stk)?i:i-StackTop(stk)-1);if(max<a)max=a;}//返回最大值return max;
}


 

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

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

相关文章

Zabbix邮件报警(163网易邮箱)

目录 一、电脑登录网易邮箱配置 二、Server端安装配置邮件服务器 邮箱查看 三、编辑zabbix_server.conf 引用邮件脚本 查看邮件 五、配置zabbix web监控项邮件报警 操作思路 Server.zabbix.com web操作 确认报警媒介信息 配置zabbix中的用户所使用的报警媒介类型以及接收邮…

【网络】HTTPS协议

目录 一、概念 1、HTTPS 2、加密解密 3、加密的必要性 4、常见的加密方式 4.1、对称加密 4.2、非对称加密 5、数据摘要 && 数据指纹 6、数字签名 二、HTTPS的工作过程 1、只使用对称加密 2、只使用非对称加密 3、双方都使用非对称加密 4、非对称加密 对…

rust gtk 桌面应用 demo

《精通Rust》里介绍了 GTK框架的开发&#xff0c;这篇博客记录并扩展一下。rust 可以用于桌面应用开发&#xff0c;我还挺惊讶的&#xff0c;大学的时候也有学习过 VC&#xff0c;对桌面编程一直都很感兴趣&#xff0c;而且一直有一种妄念&#xff0c;总觉得自己能开发一款很好…

深入学习 Redis - 深挖经典数据类型之 set

目录 前言 一、Set 类型 1.1、操作命令 sadd / smembers&#xff08;添加&#xff09; sismember&#xff08;判断存在&#xff09; scard&#xff08;获取元素个数&#xff09; spop&#xff08;删除元素&#xff09; smove&#xff08;移动&#xff09; srem&#x…

Golang time 包以及日期函数

time 包 在 golang 中 time 包提供了时间的显示和测量用的函数。 time.Now()获取当前时间 可以通过 time.Now()函数获取当前的时间对象&#xff0c;然后获取时间对象的年月日时分秒等信息。 示例代码如下&#xff1a; package mainimport ("fmt""time" )…

Redis原理篇(二)

Redis原理 Redis数据结构 Redis网络模型 RESP协议 Redis内存回收 Redis原理篇 一、原理篇-Redis数据结构 1.1 Redis数据结构-动态字符串 我们都知道Redis中保存的Key是字符串&#xff0c;value往往是字符串或者字符串的集合。可见字符串是Redis中最常用的一种数据结构。 不…

网络安全 Day19-计算机网络基础知识04(网络协议)

计算机网络基础知识04&#xff08;网络协议&#xff09; 1. ARP1.1 ARP通讯原理1.2 arp欺骗1.3 ARP欺骗与预防1.4 排查ARP病毒 2. DHCP工作原理&#xff08;自动分配内网IP&#xff09;3. TCP协议三次握手、四次挥手原理4. DNS协议工作原理 1. ARP Linux查看arp&#xff1a;ar…

聊聊STM32 ADC的话题

STM32 微控制器系列提供了多个模拟数字转换器&#xff08;ADC&#xff09;模块&#xff0c;用于实现模拟信号的采集和转换为数字信号。ADC 在很多应用中都是非常重要的&#xff0c;例如传感器数据采集、电压测量等。 在 STM32 中&#xff0c;ADC 可以通过 STM32HAL 库提供的函…

自动驾驶感知系统-超声波雷达

超声波雷达&#xff0c;是通过发射并接收40kHz的超声波&#xff0c;根据时间差算出障碍物距离。其测距精度是1~3cm.常见的超声波雷达有两种&#xff1a;第一种是安装在汽车前后保险杠上的&#xff0c;用于测量汽车前后障碍物的驻车雷达或倒车雷达&#xff0c;称为超声波驻车辅助…

时间复杂度和空间复杂度

在计算机科学中&#xff0c;算法的效率是一个重要的概念。算法的效率可以通过复杂度来度量&#xff0c;其中包括时间复杂度和空间复杂度。 了解算法的复杂度对于程序员来说非常重要。在解决实际问题时&#xff0c;我们需要选择合适的算法来保证程序的性能和效率。因此&#xff…

【前端笔记】本地运行cli项目报错ERR_OSSL_EVP_UNSUPPORTED

报错原因 Node版本>17.x&#xff0c;本地npm run 起项目后会发现终端报错&#xff0c;具体有以下2块关键信息&#xff1a; Error: error:0308010C:digital envelope routines::unsupported和 opensslErrorStack: [ error:03000086:digital envelope routines::initializa…

SpringCloud学习路线(9)——服务异步通讯RabbitMQ

一、初见MQ &#xff08;一&#xff09;什么是MQ&#xff1f; MQ&#xff08;MessageQueue&#xff09;&#xff0c;意思是消息队列&#xff0c;也就是事件驱动架构中的Broker。 &#xff08;二&#xff09;同步调用 1、概念&#xff1a; 同步调用是指&#xff0c;某一服务…

ProtoBuf入门概念

目录&#xff1a; 序列化概念ProtoBuf是什么ProtoBuf的使⽤特点安装ProtoBuf如何学习ProtoBuf 1.序列化概念 序列化和反序列化 序列化&#xff1a;把对象转换为字节序列的过程称为对象的序列化。反序列化&#xff1a;把字节序列恢复为对象的过程称为对象的反序列化。 什么…

【搜索引擎Solr】Apache Solr 神经搜索

Sease[1] 与 Alessandro Benedetti&#xff08;Apache Lucene/Solr PMC 成员和提交者&#xff09;和 Elia Porciani&#xff08;Sease 研发软件工程师&#xff09;共同为开源社区贡献了 Apache Solr 中神经搜索的第一个里程碑。 它依赖于 Apache Lucene 实现 [2] 进行 K-最近邻…

【Python笔记】Python + xlrd + pymysql读取excel文件数据并且将数据插入到MySQL数据库里面

这篇文章&#xff0c;主要介绍Python xlrd pymysql读取excel文件数据并且将数据插入到MySQL数据库里面。 目录 一、Python读取excel 1.1、安装xlrd库 1.2、打开excel工作簿 1.3、获取sheet工作表 1.4、操作row数据行 1.5、操作column数据列 1.6、操作单元格 二、读取…

Bean 作用域和生命周期

1.通过⼀个案例来看 Bean 作⽤域的问题 假设现在有⼀个公共的 Bean&#xff0c;提供给 A ⽤户和 B ⽤户使⽤&#xff0c;然⽽在使⽤的途中 A ⽤户却“悄悄”地修 改了公共 Bean 的数据&#xff0c;导致 B ⽤户在使⽤时发⽣了预期之外的逻辑错误。 1.1 被修改的 Bean 案例 公…

openfeign调用文件服务的文件上传接口报错:Current request is not a multipart request

解决办法&#xff1a; Api 接口 Api(tags "文件上接口") RestController public class FileController {Autowiredprivate FileFeignService fileFeignService;ApiOperation("上传文件")PostMapping(value "/uploadFile")public ResData<…

入门前端监控

背景 前端监控是指通过一系列手段对Web页面或应用程序进行实时监控和数据采集&#xff0c;以了解页面或应用程序的性能状况、用户行为等等&#xff0c;并及时发现和解决潜在的问题。一个完整的前端监控平台可以包括&#xff1a;数据收集与上报、数据整理与存储、数据展示这里仅…

Java连锁门诊医院HIS信息管理系统源码

Java连锁门诊医院HIS信息管理系统源码&#xff1a;SaaS运维平台多医院多机构多门诊入驻强大的电子病历完整开发文档 一、系统概述 ❉采用主流成熟技术&#xff0c;软件结构简洁、代码规范易阅读&#xff0c;SaaS应用&#xff0c;全浏览器访问前后端分离&#xff0c;多服务协同…

通过两种实现方式理解CANoe TC8 demo是如何判断接收的以太网报文里的字段的

假设有一个测试用例,需求是:编写一个测试用例,发送一条icmpv4 echo request报文给DUT,identifier字段设置为10。判断DUT能够回复icmpv4 echo reply报文,且identifier字段值为10。 实现:在canoe的simulation setup界面插入一个test节点,ip地址为:192.168.0.1,mac地址为…