数据结构之栈:原理与常用方法
1. 栈的定义
Stack是Vector的一个子类,它实现标准的后进先出堆栈。Stack只定义了创建空堆栈的默认构造方法。(实际上是实现了List接口,因为Vector是List的子类)。
Stack() // 创建一个空栈
2. 栈的基本操作
// 压栈操作
public E push(E item) // 将元素压入栈顶// 弹栈操作
public E pop() // 移除栈顶元素并返回该元素// 查看栈顶元素但不移除
public E peek() // 查看栈顶元素但不移除// 判断栈是否为空
public boolean empty() // 测试栈是否为空// 查找元素在栈中的位置(从栈顶开始为1)
public int search(Object o) // 返回对象在栈中的位置,1表示栈顶
3. 继承自Vector的方法
由于Stack继承自Vector,所以还拥有以下方法:
// 获取栈的大小
public int size() // 判断栈是否包含指定元素
public boolean contains(Object o)// 返回指定位置的元素
public E get(int index)// 清空栈
public void clear()
4. Java 中的 Stack 类
Java 提供了一个内置的 Stack
类,它扩展了 Vector
类。尽管 Stack
类仍然可用,但在现代 Java 编程中,通常推荐使用 Deque
接口的实现(如 ArrayDeque
)来模拟栈的行为。
- 由于Stack继承自Vector,所有方法都是同步的,这在多线程环境下是安全的,但在单线程环境下会有性能损失。
Deque
接口提供了更完整的栈操作,性能更好(非同步实现)
4.1. 使用 Java 的 Stack 类
import java.util.Stack;public class StackExample {public static void main(String[] args) {Stack<String> stack = new Stack<>();// 压栈操作stack.push("Apple");stack.push("Banana");stack.push("Cherry");// 查看栈大小System.out.println("Stack size: " + stack.size()); // 输出: 3// 查看栈顶元素System.out.println("Top element: " + stack.peek()); // 输出: Cherry// 弹栈操作System.out.println("Popped: " + stack.pop()); // 输出: CherrySystem.out.println("Popped: " + stack.pop()); // 输出: Banana// 判断栈是否为空System.out.println("Is stack empty? " + stack.empty()); // 输出: false// 查找元素位置System.out.println("Apple position: " + stack.search("Apple")); // 输出: 1// 清空栈stack.clear();System.out.println("Is stack empty after clear? " + stack.empty()); // 输出: true}
}
4.2. 使用 Deque 接口实现栈
import java.util.ArrayDeque;
import java.util.Deque;public class DequeAsStackExample {public static void main(String[] args) {Deque<String> stack = new ArrayDeque<>();// 压栈stack.push("Apple");stack.push("Banana");stack.push("Cherry");System.out.println("Stack: " + stack);// 出栈String top = stack.pop();System.out.println("Popped element: " + top);// 查看System.out.println("Top element: " + stack.peek());System.out.println("Updated stack: " + stack);// 判空System.out.println("Is stack empty? " + stack.isEmpty());}
}
5. 实现自定义栈
我们可以使用数组或链表来实现自定义栈。以下是使用数组实现的简单栈:
public class ArrayStack<T> {private T[] array;private int top;private int capacity;@SuppressWarnings("unchecked")public ArrayStack(int capacity) {this.capacity = capacity;array = (T[]) new Object[capacity];top = -1;}public void push(T item) {if (isFull()) {throw new IllegalStateException("Stack is full");}array[++top] = item;}public T pop() {if (isEmpty()) {throw new IllegalStateException("Stack is empty");}return array[top--];}public T peek() {if (isEmpty()) {throw new IllegalStateException("Stack is empty");}return array[top];}public boolean isEmpty() {return top == -1;}public boolean isFull() {return top == capacity - 1;}
}
6. 栈的应用
栈在计算机科学和日常编程中有广泛的应用,例如:
- 函数调用和递归
- 表达式求值和语法解析
- 撤销操作(Undo)
- 深度优先搜索(DFS)算法
- 括号匹配问题
7. 栈的实际应用示例
7.1. 括号匹配
public static boolean isBalanced(String expression) {Stack<Character> stack = new Stack<>();for (char ch : expression.toCharArray()) {if (ch == '(' || ch == '[' || ch == '{') {stack.push(ch);} else if (ch == ')' || ch == ']' || ch == '}') {if (stack.isEmpty()) {return false;}char top = stack.pop();if ((ch == ')' && top != '(') || (ch == ']' && top != '[') || (ch == '}' && top != '{')) {return false;}}}return stack.isEmpty();
}
7.2. 逆波兰表达式求值
public static int evaluateRPN(String[] tokens) {Stack<Integer> stack = new Stack<>();for (String token : tokens) {if (token.equals("+") || token.equals("-") || token.equals("*") || token.equals("/")) {int b = stack.pop();int a = stack.pop();switch (token) {case "+": stack.push(a + b); break;case "-": stack.push(a - b); break;case "*": stack.push(a * b); break;case "/": stack.push(a / b); break;}} else {stack.push(Integer.parseInt(token));}}return stack.pop();
}
8. 栈的优缺点
优点:
- 实现简单
- 后进先出的特性适用于许多算法和问题解决
- 函数调用和递归的基础
缺点:
- 只能访问最顶端的元素
- 不支持随机访问
- 大小通常是固定的(使用数组实现时)
9. 参考资料
Java 数据结构 - 栈(Stack) - KenWan - 博客园
相关文章:
数据结构之栈:原理与常用方法
1. 栈的定义 Stack是Vector的一个子类,它实现标准的后进先出堆栈。Stack只定义了创建空堆栈的默认构造方法。(实际上是实现了List接口,因为Vector是List的子类)。 Stack() // 创建一个空栈 2. 栈的基本操作 // 压栈操作 publi…...

在React框架中使用Braft Editor集成Table表格的详细教程
简介:Braft Editor是一款基于draft-js开发的React富文本编辑器,支持多媒体、自定义样式和扩展功能。其表格扩展模块允许用户插入、调整表格结构,适合需要数据展示的场景(如CMS系统、报表工具)。 1.安装依赖 yarn add…...
跳动的爱心
跳动的心形图案,通过字符打印和延时效果模拟跳动,心形在两种大小间交替跳动。 通过数学公式生成心形曲线 #include <stdio.h> #include <windows.h> // Windows 系统头文件(用于延时和清屏) void printHeart(int …...
gbase8s数据库+mybatis问题记录
在实际使用中一般都是mybatis数据库连接池组合使用,单独使用mybatis 连接数据库时,在循环使用PreparedStatement 时 会发生内存泄漏,PreparedStatement资源得不到释放 测试代码片段如下 drawMapper sqlsession.getMapper(DrawMapper.class…...
实现安卓端与苹果端互通的方案多种多样,以下是一些主要的方案
一、使用跨平台开发框架 1.React Native:通过React Native,开发者可以利用React.js的强大生态系统来构建原生移动应用。该框架允许使用相同的代码库在Android和iOS上开发应用,从而节省时间和成本。它支持热重载功能,使得开发者在…...
SpringBoot开发——Spring Boot异常处理全攻略:五大方案实战对比
文章目录 一、血泪教训:异常处理的代价二、五大异常处理方案详解2.1 全局异常处理(推荐方案)2.2 控制器级处理2.3 HTTP状态码注解2.4 ResponseEntity精细控制2.5 自定义异常体系(企业级方案)三、五大方案对比决策表四、四大避坑指南4.1 异常吞噬陷阱4.2 循环依赖问题4.3 异…...
React-props
文章目录 前言✅ 一、什么是 props?✅ 二、props 的特点✅ 三、props 的核心细节 & 常见问题1. **props 是新对象还是引用?**2. **函数作为 props:闭包陷阱**3. **默认值 & 解构默认值**4. **props.children 是什么?**5. …...
【C++篇】list模拟实现
实现接口: list的无参构造、n个val构造、拷贝构造 operator重载 实现迭代器 push_back() push_front() erase() insert() 头尾删 #pragma once #include<iostream> #include<assert.h> using namespace std;namespace liu {//定义list节点temp…...
Oracle exist
Oracle中的EXISTS是用于检查子查询结果是否为空的逻辑运算符,其核心特点和用法如下: 基础语法 SELECT columns FROM table1 WHERE EXISTS (SELECT 1 FROM table2 WHERE condition); 当子查询返回至少一行时返回TRUE,否则返回FALSE。 执…...

带sdf 的post sim 小结
1.SDF文件主要内容 Delays(module,device,interconnect,port) Timing checks(setup,hold,setuphold,recovery,removal,recrem) Timing…...
【面试】喜茶Java面试题目
1、自我介绍、项目介绍; 2、equals 和 的区别?如何重写equals方法? 3、Java中的异常体系?运行时异常和非运行时异常的区别? 4、HashMap的底层数据结构?JDK1.7和1.8的区别? 5、线程池的核心…...

深入浅出:Spring IOCDI
什么是IOC IOC IOC(Inversion of Control),是一种设计思想,在之前的SpringMVC里就在类上添加RestController和Controller注解就是使用了IOC,这两个注解就是在Spring中创建一个对象,并将注解下的类交给Spring管理,Spr…...

PlankAssembly 笔记 DeepWiki 正交视图三维重建
manycore-research/PlankAssembly | DeepWiki PlankAssembly项目原理 这个项目是一个基于深度学习的3D重建系统,其核心原理是从三个正交视图的工程图纸中重建出3D形状的结构化程序表示。 核心技术原理 1. 问题定义 PlankAssembly旨在从三个正交视图的工程图纸中…...

某验4无感探针-js逆向
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 一、总体概述二、请求分析1.分析请求流程三、逆向分析四、执行验证总结一、总体概述 本文主要实现用协议过某验4无感探针,相关的链接:aHR0cHM6Ly9ndDQuZ2VldGVzdC5jb20vZGVtb3Y0L2ludmlzaWJsZS1…...
js中common.js和ECMAScript.js区别
以下是关于 CommonJS 和 ECMAScript Modules(ESM)的详细对比分析,包含底层原理和示例说明: 🧩 核心差异对比表 特性CommonJSES Modules来源Node.js 社区规范ECMAScript 语言标准加载方式动态加载(运行时解…...
C语言操作Kafka
Kafka服务 Kafka的快速入门 文档很详细,基本上几步就可以搭建一个Kafka测试环境。 下载Kafka的二进制包,然后解压。 wget https://www.apache.org/dyn/closer.cgi?path/kafka/4.0.0/kafka_2.13-4.0.0.tgz tar -xzf kafka_2.13-4.0.0.tgz cd kafka_2.…...
STM32架构解析
在嵌入式开发领域,STM32作为广泛应用的Cortex-M系列微控制器,常常被问及一个基础而深刻的问题:STM32是哈佛结构,还是冯诺依曼结构?这个问题看似简单,却涉及到计算机架构发展的历史、理论与现实的融合。 一、计算体系结构基础:冯诺依曼 vs 哈佛 1.1 冯诺依曼结构的特性…...
在线政治采购系统架构构建指南
一、系统架构设计原则 合规性优先 系统需严格遵循《中华人民共和国政府采购法》及最新修订要求,例如采购流程需满足公开招标不少于 20 日的法定时限,合同需在中标通知书发出后 30 日内签订并备案。同时,需预留接口以适应未来法律修订带来的流…...

UHF RFID无源标签的芯片供电原理
作为无源物联网技术中最基础的一环,UHF RFID无源标签已经被广泛用于商超零售、物流仓储、图书档案、防伪溯源等量非常大的应用领域,仅2021年度,全球出货量就超过200亿。在实际应用中UHF RFID无源标签的芯片是究竟依靠什么来供电的呢? UHF RFID无源标签供电特点 1.借助无线…...

【NLP入门系列一】NLP概述和独热编码
🍨 本文为🔗365天深度学习训练营 中的学习记录博客🍖 原作者:K同学啊 博主简介:努力学习的22级本科生一枚 🌟;探索AI算法,C,go语言的世界;在迷茫中寻找光芒…...

洛谷习题V^V
1.帮贡排序 解题思路:按照题意,排序模拟即可 #include <iostream> #include <vector> #include <algorithm> #include <string> using namespace std;struct Member {string name;string position;int contribution;int level;…...

Wireshark 在 macOS 上使用及问题解决
wireshark概述 Wireshark 是被广泛使用的免费开源网络协议分析软件(network protocol analyzer)或网络数据包分析工具,它可以让你在微观层面上查看网络上发生的事情。它的主要功能是截取网络数据包,并尽可能详细地展示网络数据包…...

不同电脑同一个网络ip地址一样吗?如何更改
想象一下,你住在同一栋公寓楼里,所有住户对外共享一个统一的小区地址(类似公网IP),但每家每户又有独立的门牌号(类似内网IP)。网络世界中的IP地址也遵循这一逻辑:同一局域网内的设备…...
Qt使用智能指针
第一步:导入头文件 #include <QScopedPointer> 第二步:创建对象 .h文件 QSharedPointer<Student> m_pClass; .cpp文件 m_pClass.reset(new Student(param1,param2,...,param_n)); 第三步:绑定信号槽 connect(m_pClass.data(), &Class::sign…...

微软 Azure AI Foundry(国际版)十大重要更新
2025 年被广泛视为 “AI 智能体元年”。在过去半年,微软密集发布众多创新技术,构建起从基础设施层、开发工具层到场景应用层的完整技术矩阵,加速推动诸多具备自主决策能力的 “超级助理” 智能体落地,形成完整的 AI 赋能生态&…...
Realsense D435i 使用说明
D435i 驱动安装 及 ROS使用 Ubuntu16.04适配https://blog.csdn.net/lemonxiaoxiao/article/details/107834936 过程中遇到fatal error ; 需要添加标签。 使用下面网址的博客解决了。https://blog.csdn.net/xuzhengzhe/article/details/135407342 最终如下: target…...

PostgreSQL如何更新和删除表数据
这节说下怎样更新和删除表数据,当然认识命令了,可以问AI帮忙写。 接上节先看下天气表weather的数据,增加了杭州和西安的数据: 一.UPDATE更新命令 用UPDATE命令更新现有的行。 假设所有 杭州 5月12日的温度低了两度,用…...
【leetcode】704. 二分查找
二分查找 题目代码 题目 704. 二分查找 给定一个 n 个元素有序的(升序)整型数组 nums 和一个目标值 target ,写一个函数搜索 nums 中的 target,如果目标值存在返回下标,否则返回 -1。 示例 1: 输入: nums [-1,0,3,…...

Golang | 运用分布式搜索引擎实现视频搜索业务
把前面所设计好的搜索引擎引用进来开发一个简单的具体的视频搜索业务。代码结构: handler目录:后端接口,负责接收请求并返回结果,不存在具体的搜索逻辑。video_search目录:具体的搜索逻辑存放在这,包括reca…...
针对Helsinki-NLP/opus-mt-zh-en模型进行双向互翻的微调
引言 题目听起来有点怪怪的,但是实际上就是对Helsinki-NLP/opus-mt-en-es模型进行微调。但是这个模型是单向的,只支持中到英的翻译,反之则不行。这样的话,如果要做中英双向互翻就需要两个模型,那模型体积直接大了两倍…...