【日撸 Java 300行】Day 14(栈)
目录
Day 14:栈
一、栈的基本知识
二、栈的方法
1. 顺序表实现栈
2. 入栈
3. 出栈
三、代码及测试
拓展:
小结
Day 14:栈
Task:
- push 和 pop 均只能在栈顶操作.
- 没有循环, 时间复杂度为 O(1).
一、栈的基本知识
详细的介绍,可以参考这篇学习笔记:【数据结构】栈-CSDN博客。本博文中只选取部分知识点讲解。
简单来说,我们可以把栈理解成一种 “运算受限” 的线性表,即后进先出(Last In First Out,简称LIFO)或先进后出(First In Last Out,简称FILO)的原则进行的线性表,因此,栈又称为LIFO表或FILO表。
对于栈这种数据结构的定位,我们可以从栈这个字本身出发。
“ 栈 ”是一个用于存储货物的房间,就像我们古代用于旅人驻脚歇店的客栈,人们不会在这久居,不过是中转站罢了。
这个翻译可谓很灵性了,计算机中的“ 栈 ”(Stack)也确实也可以理解为暂时存储的容器。比如在函数调用时,底层编译器会把我们当前的数据放于这个临时的容器中存储,避免在进入函数后当前上下文环境的信息丢失,之后,待到函数返回后再从Stack中取出。
当然,这种数据中转存储的数据类型我们不是说都称之为栈,还包括有有队列性质的高速缓存与各种正常的顺序存储的文件系统等,只是说栈有些独有方面的特例。
二、栈的方法
1. 顺序表实现栈
同时需要注意的一点,根据线性表的分类(顺序表和链表) ,我们可以用这两种方式来实现栈的构建,即分为顺序栈和链栈。本博文中通过顺序表来实现栈,具体构造原理可以参考学习笔记,这里不做展开。
/*** The depth.*/public static final int MAX_DEPTH = 10;/*** The actual*/int depth;/*** The data*/char[] data;/************************ Construct an empty char stack.**********************/public CharStack() {depth = 0;data = new char[MAX_DEPTH];}// Of the first constructor/************************ Overrides the method claimed in Object, the superclass of any class.**********************/public String toString() {String resultString = "";for (int i = 0; i < depth; i++) {resultString += data[i];} // Of for ireturn resultString;}// Of toString
这里的属性与静态顺序表中的内容无差,构造函数完成栈深度(长度)初始化,空间开辟遵循静态链表开辟的方法——使用new开辟固定“MAX_DEPTH”大小的空间。
但注意,栈是于栈顶一端进行删除与插入的结构,而为了顺序表的实现方便,我们往往在下标较大处插入,因此我们定义栈顶在数组的最右侧。
所以,按照从左向右打印的习惯,toString()函数完成的就是栈底向栈顶的打印过程。
2. 入栈
本质上就是加入一个元素,只不过位置被限定在栈顶。
从顺序表的角度来看,其意义就是在顺序表的最后一个元素后面再插入一个元素。
由于位置固定,所以我们只需要给末尾元素之后的空位赋值并且让栈深度+1即可(对于从0开始记录的任何表,表长都默认值最后一个元素的下一个位置)
/************************ Push an element.* * @param paraChar The given char.* @return Success or not.**********************/public boolean push(char paraChar) {if (depth == MAX_DEPTH) {System.out.println("Stack full.");return false;} // Of ifdata[depth] = paraChar;depth++;return true;}// Of push
对于任何顺序表的插入都不要忘记判断表满的情况,因此,这里先进行一次判满的判断,这是栈的基本健壮性保证。
之后的入栈操作怎么写,要根据你的栈顶指针的默认指向来确定。
这里我们用depth来表示栈深度,同时,自然也用于表示栈顶指针。这种情况的话,depth默认指向的位置刚好就是尾元素后面的空位,刚好可以直接插入,于是可以使用:
data[depth] = paraChar;depth++;
我们可以做如下简写:
data[depth++] = paraChar;
当然,若栈顶指针假设指向末尾元素本身的话,这里我们假设这个变量为top。在插入元素时需要保证栈顶指针要先移动到末尾元素后面的空位才能进行插入,于是就要使用:
top++;data[top] = paraChar;
当然,也可以简写成:
data[++top] = paraChar;
习惯上,我们会将入栈操作定义为 Boolean 类型,这是因为布尔信息能够明确的告诉我们该操作是否成功。
3. 出栈
同顺序表一样,元素删除需要先判断是否为空,以保证程序的健壮性。
出栈时,使用resultChar先接收栈顶数据,之后再进行栈指针的下移操作,实现逻辑上元素减少(但是实际上这个值还是存放在原指针所指的位置的),因为我们确定栈元素的多少仅依靠栈顶指针的具体值而定。
这个操作与入栈的操作是完全相逆的,而且也会因为栈顶指针的含义不同而变化,即:栈顶指针指向栈顶有效元素的上方的一个无数据位,一般我们令其值为 -1。由于这里我们采用的是 depth(深度),所以最小值为0,但观察可知,实际操作中读取的 depth - 1,是等效的。
public char pop() {if (depth == 0) {System.out.println("Nothing to pop.");return '\0';} // Of ifchar resultChar = data[depth - 1];depth--;return resultChar;}// Of pop
三、代码及测试
package datastructure.stack;/*** Char stack. I do not use Stack because it is already defined in Java.** @author: Changyang Hu joe03@foxmail.com* @date created: 2025-05-13*/
public class CharStack {/*** The depth.*/public static final int MAX_DEPTH = 10;/*** The actual depth.*/int depth;/*** The data*/char[] data;/************************ Construct an empty char stack.**********************/public CharStack() {depth = 0;data = new char[MAX_DEPTH];}// Of the first constructor/************************ Overrides the method claimed in Object, the superclass of any class.**********************/public String toString() {String resultString = "";for (int i = 0; i < depth; i++) {resultString += data[i];} // Of for ireturn resultString;}// Of toString/*** ********************** @Title: push* @Description: Push an element.** @param paraChar The given char.* @return Success or not.* @return boolean **********************/public boolean push(char paraChar) {if (depth == MAX_DEPTH) {System.out.println("Stack full.");return false;} // Of ifdata[depth] = paraChar;depth++;return true;}// Of push/*** ********************** @Title: pop* @Description: Pop an element.** @return The popped char.* @return char **********************/public char pop() {if (depth == 0) {System.out.println("Nothing to pop.");return '\0';} // Of ifchar resultChar = data[depth - 1];depth--;return resultChar;}// Of pop/*** ********************** @Title: main* @Description: The entrance of the program.** @param args Not used now.* @return void **********************/public static void main(String args[]) {CharStack tempStack = new CharStack();for (char ch = 'a'; ch < 'm'; ch++) {tempStack.push(ch);System.out.println("The current stack is: " + tempStack);} // Of for chchar tempChar;for (int i = 0; i < 12; i++) {tempChar = tempStack.pop();System.out.println("Poped: " + tempChar);System.out.println("The current stack is: " + tempStack);} // Of for i}// Of main}// Of CharStack
拓展:
栈:【数据结构】栈-CSDN博客
小结
通过顺序表来实现栈操作,本身并不复杂,只是说一些要点需要我们在使用前就想好:
- 采用 depth(指向栈顶的下一个元素)还是 top(指向栈顶)作为下标
- 采用顺序表来实现还是链表(链表相关参考学习笔记)
栈虽然本身简单,但是其在数据传输中的战略地位极高。
栈实现了“ 调用 ”思想的核心。栈的临时存储与栈出数据总是最近一次栈入的数据的特性非常符合嵌套调用与返回的特性。所以如今我们使用的各种函数都用到了栈的思想,任何使用函数完成的算法体系都可以使用栈完成模拟。
栈贯穿了计算机的各个邻域,栈的概念在硬件中就早有使用,因为栈的实现,促成了操作系统的中断特性的实现,而中断的特性又促成后来批处理操作系统的诞生,是当代计算机的奠基石。也许毫不夸张说,没有栈,就没有我们如今的计算机的基础。
相关文章:

【日撸 Java 300行】Day 14(栈)
目录 Day 14:栈 一、栈的基本知识 二、栈的方法 1. 顺序表实现栈 2. 入栈 3. 出栈 三、代码及测试 拓展: 小结 Day 14:栈 Task: push 和 pop 均只能在栈顶操作.没有循环, 时间复杂度为 O(1). 一、栈的基本知识 详细的介…...

2025最新出版 Microsoft Project由入门到精通(七)
目录 优化资源——在资源使用状况视图中查看资源的负荷情况 在资源图表中查看资源的负荷情况 优化资源——资源出现冲突时的原因及处理办法 资源过度分类的处理解决办法 首先检查任务工时的合理性并调整 增加资源供给 回到资源工作表中双击对应的过度分配资源 替换资…...

修改(替换)文件中的指定内容并保留文件修改前的时间(即修改前后文件的最后修改时间保持不变)
🤟致敬读者 🟩感谢阅读🟦笑口常开🟪生日快乐⬛早点睡觉 📘博主相关 🟧博主信息🟨博客首页🟫专栏推荐🟥活动信息 文章目录 修改(替换)文件中的指…...
Linux云计算训练营笔记day07(MySQL数据库)
数据库 DataBase 保存数据的仓库 数据库管理系统 DBMS 这是一个可以独立运行,用于维护磁盘上的数据的一套软件 特点: 维护性高,灵活度高,效率高,可扩展性强 常见的DBMS Mysql Mariadb Oracle DB2 SQLServer MySQL是一个关系型…...

应用探析|千眼狼PIV测量系统在职业病防治中的应用
1、职业病防治背景 随着《职业病防治法》及各省市“十四五”职业病防治规划的深入推进,工作场所粉尘危害监测与防控已成为疾控部门的核心任务。以矿山、建材、冶金、化工等行业为例,粉尘浓度、分布及传播特性的精准测量是评估职业病风险的关键。 传统的…...
获取accesstoken时,提示证书解析有问题,导致无法正常获取token
错误: https://qyapi.weixin.qq.com/cgi-bin/gettoken": sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested targ…...
面试中被问到谈谈你对threadlocal的理解
ThreadLocal 的核心理解 1. 基本概念 ThreadLocal 是 Java 提供的线程局部变量机制,用于在多线程环境中为每个线程维护独立的变量副本,实现线程隔离。其核心思想是空间换时间,通过避免共享变量带来的同步开销,提升并发性能。 2…...

nvidia驱动更新-先卸载再安装-ubuntu
显卡驱动升级前,卸载旧版本,可采用两种方式。 1.命令行 (1)查找已安装的 NVIDIA 驱动和相关包:dpkg -l | grep nvidia (2)完全卸载 NVIDIA 驱动:sudo apt remove purge nvidia-*…...
FlashInfer - 安装
FlashInfer - 安装 flyfish 一、JIT 版安装FlashInfer 对于 JIT 版本(即每次都从源代码编译每个内核,此过程需要 NVCC),可通过 PyPI 进行安装。 解释 JIT 版本(JIT Version) JIT 即 Just-In-Time Compi…...

推荐算法工程化:ZKmall模板商城的B2C 商城的用户分层推荐策略
在 B2C 电商竞争激烈的市场环境中,精准推荐已成为提升用户体验、促进商品销售的关键。ZKmall 模板商城通过推荐算法工程化手段,深度挖掘用户数据价值,制定科学的用户分层推荐策略,实现 “千人千面” 的个性化推荐,帮助…...
jackson-dataformat-xml引入使用后,响应体全是xml
解决方案: https://spring.io/blog/2013/05/11/content-negotiation-using-spring-mvc import org.springframework.context.annotation.Configuration; import org.springframework.http.MediaType; import org.springframework.web.servlet.config.annotation.Con…...
嵌入式硬件篇---TOF|PID
文章目录 前言1. 硬件准备主控芯片ToF模块1.VL53L0X2.TFmini 执行机构:电机舵机其他 2. 硬件连接(1) VL53L0X(IC接口)(2) TFmini(串口通信) 3. ToF模块初始化与数据读取(1) VL53L0X(基于HAL库)(…...
Realtek 8126驱动分析第四篇——multi queue相关
Realtek 8126是 5G 网卡,因为和 8125 较为接近,第四篇从这里开始也无不可。本篇主要是讲 multi queue 相关,其他的一些内容在之前就已经提过,不加赘述。 1 初始化 1.1 rtl8126_init_one 从第一篇我们可以知道每个 PCI 驱动都注…...

基于Java和PostGIS的AOI面数据球面面积计算实践
目录 前言 一、计算方法简介 二、球面面积计算 1、AOI数据转Polygon 2、Geotools面积计算 3、GeographicLib面积计算 4、PostGIS面积计算 三、结果分析 1、不同算法结果对比 2、与互联网AOI对比 3、与天地图测面对比 四、总结 前言 在现代地理信息系统(G…...

Spring Boot之Web服务器的启动流程分析
如何判断创建哪种web容器:servlet?reactive? 我们在启动Spring Boot程序的时候,会使用SpringApplication.run方法来启动,在启动流程中首先要判断的就是需要启动什么类型的服务器,是servlet?或者…...
C# SQLite高级功能示例
目录 1 主要功能 2 程序结构和流程 3 详细实现说明 3.1 基础设置 3.2 事务演示 3.3 索引演示 3.4 视图演示 3.5 触发器演示 3.6 全文搜索演示 3.7 窗口函数演示 3.8 外键约束演示 4 高级功能示例 5 单个方法详细介绍 5.1 SetupExampleData()方法 5.2 UseTransact…...

【周输入】510周阅读推荐-1
本号一年了,有一定的成长,也有很多读者和点赞。自觉更新仍然远远不够,需要继续努力。 但是还是要坚持2点: 在当前这个时代,信息大爆炸,层次不齐,不追加多, 信息输入可以很多&#x…...

基于动态规划的强化学习方法
目录 # 动态规划 # 基于动态规划的强化学习方法 # 求解过程: ## 策略评估 ## 策略提升 # 价值迭代算法 # 参考 # 动态规划 动态规划的基本思想是将待求解问题分解成若干个子问题,先求解子问题,然后从这些子问题的解得到目标问题的解。…...
启动 spyder ModuleNotFoundError: No module named ‘PyQt5.QtWebKitWidgets‘
一、根本原因 Spyder 版本兼容性:Spyder 4.x 依赖 QtWebKitWidgets,但该模块在 PyQt5 5.15 中已被移除。 PyQt5 版本冲突:如果你安装了较新的 PyQt5(如 5.15),则会缺少 QtWebKitWidgets。 二、解决方案 方法…...
ChemBlender:科研绘图创新解决方案
一、研究背景与冲突 (一)研究背景 在科学研究领域,可视化表达对于成果的呈现与交流至关重要。科研绘图作为科学可视化的关键手段,涵盖了从微观分子结构到宏观实验现象等广泛的内容。随着科研的深入发展,研究对象的复杂…...

Uniapp Android/IOS 获取手机通讯录
介绍 最近忙着开发支付宝小程序和app,下面给大家介绍一下 app 获取通讯录的全部过程吧,也是这也是我app开发中的一项需求吧。 效果图如下 勾选配置文件 使用uniapp开发的童鞋都知道有一个配置文件 manifest.json 简单的说一下,就是安卓/ios/…...
设计一个分布式系统:要求全局消息顺序,如何使用Kafka实现?
一、高吞吐低延迟 Kafka 集群设计要点 1. 分区策略优化 // 计算合理分区数公式(动态调整) int numPartitions max(Tp, Tc) / min(Tp, Tc) // Tp生产者吞吐量 Tc消费者吞吐量建议初始按业务键(如订单ID)哈希分区单分区吞吐建议…...

2025年RIS SCI2区,改进白鲸优化算法+复杂非线性方程组求解,深度解析+性能实测
目录 1.摘要2.白鲸优化算法BWO原理3.改进策略4.结果展示5.参考文献6.代码获取7.读者交流 1.摘要 本文提出了一种改进白鲸优化算法(ABWOA)用来解决非线性方程组(SNLEs)求解问题。ABWOA引入了平衡因子和非线性自适应参数࿰…...

Java后端开发day48--反射动态代理
(以下内容全部来自上述课程) 反射 反射允许对成员变量,成员方法和构造方法的信息进行编程访问。 就是获取里面的成员变量、构造方法和成员方法,idea中打代码跳出来的提示就是反射。 1. 获取class对象的三种方式 Class.for…...
十四、继承与组合(Inheritance Composition)
十四、继承与组合(Inheritance & Composition) 引言 C最引人注目的特性之一是代码复用。组合:在新类中创建已有类的对象。继承:将新类作为已有类的一个类型来创建。 14.1 组合的语法 Useful.h //C14:Useful.h #ifndef US…...

ValueError: Caught ValueError in DataLoader worker process 0.
参考链接: https://stackoverflow.com/questions/1841565/valueerror-invalid-literal-for-int-with-base-10 它提示我有个地方值错误空字符 果然因为格式处理没有传进去东西,找下原因,让它正常处理 原来是相对路径的.影响了程序运行 将v…...

【数据结构】——链表OJ(下)
前面我们已经刷了几道单链表的题目,下面我们继续看几道题目。 一、相交链表 这道题题目的要求是很好理解的,就是现在我们有两个链表,然后我们就相办法进行判断,这两个链表是否是相交的,那么链表的相交其实就是有没有共…...

Adobe Acrobat pro在一份PDF中插入空白页
在Adobe Acrobat pro中先打开我们的PDF文件; 用鼠标点击需要插入空白页处的上一页; 然后如下图操作: 默认会在光标处的下一页插入一张空白页,你也可以修改插入页的页码或者向前一页插入...

java-----异常
对于Error:表示系统级错误或者资源耗尽的状况,像OutOfMemoryError、StackOverflowError等。这类错误是程序无法处理的,通常也不应该尝试去处理。 对于Exception:表示程序可以处理的异常。它又能细分为: 受检查异常&a…...

[工具]B站缓存工具箱 (By 郭逍遥)
📌 项目简介 B站缓存工具箱是一个多功能的B站缓存工具,包含视频下载、缓存重载、文件合并及系统设置四大核心功能。基于yutto开发,采用图形化界面操作,极大简化B站资源获取与管理流程。 工具可以直接将原本缓存的视频读取&#…...