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

news2024/11/18 6:32:01

一.栈的基本概念

栈是一种特殊的表,这种表只在表首进行插入和删除操作。
因此,表首对于栈来说具有特殊的意义,称为栈顶。相应的,表尾称为栈底。不含任何元素的栈称为空栈。
栈的修改遵循后进先出的原则,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,计算包含该直条的最大矩形a
	while(!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.coloradmin.cn/o/789028.html

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

相关文章

异常报错:The last packet sent successfully to the server was 0 milliseconds ago

本地运行项目&#xff0c;突然报错&#xff0c;日志为&#xff1a; The last packet sent successfully to the server was 0 milliseconds ago. The driver has not received any packets from the server.在网上找了一圈&#xff0c;没有找到合适的解决方案。最后猜测问题有…

基于Java+SpringBoot+vue前后端分离在线商城系统设计实现

博主介绍&#xff1a;✌全网粉丝30W,csdn特邀作者、博客专家、CSDN新星计划导师、Java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专…

华为战略方法论:BLM模型之关键任务与依赖关系

内容简介 在 BLM 模型中&#xff0c;执行部分包括四个模块&#xff0c;分别是&#xff1a; 关键任务与依赖关系&#xff1b;组织与绩效&#xff1b;人才&#xff1b;氛围与文化。 详细内容&#xff0c;大家可以参看下面这张图。 这四个模块其实是可以进一步划分成两个关键点…

【LeetCode】300.最长递增子序列

首先分析这个问题&#xff0c;以示例1为例。 已经求得最大递增子序列长度为4&#xff0c;而且该子序列中最后一个数为101&#xff0c; 那么一定存在一个数ai&#xff0c;使得ai以及ai之前的所有数组成的序列中&#xff0c; 最大递增子序列长度为3&#xff0c;而且该子序列中…

Linux环境Arduino IDE中配置ATOM S3

linux选择ubuntu发行版。 硬件设备有多小呢&#xff1a; 功能超级强大。 之前的ROS1和ROS2案例已经全部移植完成并测试结束&#xff08;三轮纯人力校验&#x1f60e;&#xff09;。 官网文档信息非常非常好&#xff1a; https://docs.m5stack.com/zh_CN/quick_start/atoms3…

AI学习笔记一:软件和环境搭建

若该文为原创文章&#xff0c;转载请注明原文出处。 工欲善其事必先利其器。 一、环境説明 1、win10, 无CPU。 2、云服务器AutoDL 3、安装的软件&#xff1a;pyCharm(比较少用&#xff0c;所以不安装&#xff09; 4、环境&#xff1a;miniconda 二、miniconda 安装 1、…

List的各种排序

目录 Collections.sort对list进行排序 对象中某个属性进行排序 通过比较器进行比较 JAVA8特性Stream流进行排序 Stream升降序组合使用 Collections.sort对list进行排序 public static void main(String[] args) {List<Integer> list new ArrayList<>();list…

渗透测试流程

目录 前言&#xff1a; 渗透测试流程 1、先了解下渗透测试与入侵的最大区别 2、一般渗透测试流程 前言&#xff1a; 在软件开发中&#xff0c;渗透测试是一种非常重要的安全测试方法&#xff0c;它可以帮助我们更加全面地检测软件中的安全漏洞和风险。 渗透测试流程 1、…

I2C通讯EEPROM

1。对I2C写数据的时候&#xff0c;首先发一个停止信号&#xff0c;确保接下来发送新的数据保存至EEPROM。 2。发送起始信号 3。发送EEPROM设备地址 根据对应的EEPROM&#xff0c;规格书&#xff0c;以及线路图&#xff0c;发送地址。 根据线路图A0,A1,A2接地&#xff0c;表…

Vite多页面应用简单构建(Vite4.4.1)

目录 概述 配置多页面 步骤1&#xff1a;vite创建空vue项目 步骤2&#xff1a;创建子页面 步骤3&#xff1a;打包配置 完毕&#xff0c;测试 概述 此篇博客说明&#xff1a;使用Vite构建一个vue项目&#xff0c;并配置多页面应用。 目标&#xff1a;给新创建的项目配置…

26.垂直滚动板

垂直滚动板 html部分 <div class"slider-container"><div class"left-slide"><div style"background-color: red;">1</div><div style"background-color: aquamarine;">2</div><div style&q…

京东技术专家首推:Spring 微服务架构设计,GitHub 星标 128K

前言 本书提供了实现大型响应式微服务的实用方法和指导原则&#xff0c;并通过示例全面 讲解如何构建微服务。本书深入介绍了 Spring Boot、Spring Cloud、 Docker、Mesos 和 Marathon&#xff0c;还会教授如何用 Spring Boot 部署自治服务&#xff0c;而 无须使用重量级应用服…

8款常用系统镜像烧录软件

系统烧录软件是一种用于将操作系统或其他软件程序安装到嵌入式系统、嵌入式设备或存储设备中的工具。它通常用于将预先编译好的二进制文件或源代码烧录到硬件设备的非易失性存储器中&#xff0c;例如闪存芯片、EEPROM、EPROM或其他存储介质。系统烧录软件提供了一个便捷的方式&…

基于Java+SpringBoot+vue前后端分离海滨体育馆管理系统设计实现

博主介绍&#xff1a;✌全网粉丝30W,csdn特邀作者、博客专家、CSDN新星计划导师、Java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专…

selenium的三种等待方式(强制等待,隐式等待,显示等待)

目录 1.强制等待&#xff08;无条件等待&#xff09; 2.隐式等待 3.显示等待 有时候做自动化测试&#xff0c;需要进行等待&#xff0c;因为下一步的操作依赖于上一步的结果&#xff0c;但是程序执行的很快&#xff0c;有时候页面还未加载完成就进行了下一步的操作&#xff…

【数据挖掘】使用 LSTM 进行时间和序列预测

一、说明 每天&#xff0c;人类在执行诸如过马路之类的任务时都会做出被动预测&#xff0c;他们估计汽车的速度和与汽车的距离&#xff0c;或者通过猜测球的速度并相应地定位手来接球。这些技能是通过经验和实践获得的。然而&#xff0c;由于涉及众多变量&#xff0c;预测天气或…

网络安全 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…

12.Netty源码之整体架构脉络

Netty 整体架构脉络 Netty 的逻辑处理架构为典型网络分层架构设计&#xff0c;共分为网络通信层、事件调度层、服务编排层&#xff0c;每一层各司其职。 网络通信层 网络通信层的职责是执行网络 I/O 的操作。它支持多种网络协议和 I/O 模型的连接操作。当网络数据读取到内核缓冲…

一分钟叫你怎样AI绘画 Vega Ai

先看效果图&#xff1a; 是不是也想自己去创造这样的图片呢&#xff0c;注意已经不需要自己画了&#xff01;&#xff01; Vega AI 简介 Vega AI是一款能够 文字生成图片、根据图片文字进行生成图片、条件生成图片 、根据多张图片训练出自己的风格&#xff0c;在风格广场选择…

使用 OpenCV 和 GrabCut 算法进行交互式背景去除

一、说明 我想&#xff0c;任何人都可以尝试从图像中删除背景。当然&#xff0c;有大量可用的软件或工具能够做到这一点&#xff0c;但其中一些可能很昂贵。但是&#xff0c;我知道有人使用窗口绘画3D魔术选择或PowerPoint背景去除来删除背景。 如果您是计算机视觉领域的初学者…