Java实现一个简单的堆栈
堆栈(Stack)是一种常见的数据结构,符合后进先出(First In Last Out)原则,通常用于实现对象存放顺序的逆序。栈的基本操作有push(添加到堆栈),pop(从堆栈删除),peek(检测栈顶元素且不删除)。
第一种实现方式:普通数组实现
/** * Created by Frank */ public class ToyStack { /** * 栈的最大深度 **/ protected int MAX_DEPTH = 10; /** * 栈的当前深度 */ protected int depth = 0; /** * 实际的栈 */ protected int[] stack = new int[MAX_DEPTH]; /** * push,向栈中添加一个元素 * * @param n 待添加的整数 */ protected void push(int n) { if (depth == MAX_DEPTH - 1) { throw new RuntimeException("栈已满,无法再添加元素。"); } stack[depth++] = n; } /** * pop,返回栈顶元素并从栈中删除 * * @return 栈顶元素 */ protected int pop() { if (depth == 0) { throw new RuntimeException("栈中元素已经被取完,无法再取。"); } // --depth,dept先减去1再赋值给变量dept,这样整个栈的深度就减1了(相当于从栈中删除)。 return stack[--depth]; } /** * peek,返回栈顶元素但不从栈中删除 * * @return */ protected int peek() { if (depth == 0) { throw new RuntimeException("栈中元素已经被取完,无法再取。"); } return stack[depth - 1]; } }
第二种实现方式:deque双向队列
import java.util.ArrayDeque; import java.util.Deque; public class IntegerStack { private Deque<Integer> data = new ArrayDeque<Integer>(); public void push(Integer element) { data.addFirst(element); } public Integer pop() { return data.removeFirst(); } public Integer peek() { return data.peekFirst(); } public String toString() { return data.toString(); } public static void main(String[] args) { IntegerStack stack = new IntegerStack(); for (int i = 0; i < 5; i++) { stack.push(i); } System.out.println("After pushing 5 elements: " + stack); int m = stack.pop(); System.out.println("Popped element = " + m); System.out.println("After popping 1 element : " + stack); int n = stack.peek(); System.out.println("Peeked element = " + n); System.out.println("After peeking 1 element : " + stack); } } /* 输出 After pushing 5 elements: [4, 3, 2, 1, 0] Popped element = 4 After popping 1 element : [3, 2, 1, 0] Peeked element = 3 After peeking 1 element : [3, 2, 1, 0] */
ArrayDeque源码
//java.util.ArrayDeque的源码: private transient E[] elements; private transient int head; private transient int tail; /*此处存放e的位置是从elements数组最后的位置开始存储的*/ public void addFirst(E e) { if (e == null) throw new NullPointerException(); elements[head = (head - 1) & (elements.length - 1)] = e;//首次数组容量默认为16,head=(0-1)&(16-1)=15 if (head == tail) doubleCapacity(); } /*每次扩容都按插入的先后顺序重新放入一个新的数组中,最新插入的放在数组的第一个位置。*/ private void doubleCapacity() { assert head == tail; int p = head; int n = elements.length; int r = n - p; // number of elements to the right of p int newCapacity = n << 1; if (newCapacity < 0) throw new IllegalStateException("Sorry, deque too big"); Object[] a = new Object[newCapacity]; System.arraycopy(elements, p, a, 0, r); System.arraycopy(elements, 0, a, r, p); elements = (E[])a; head = 0; tail = n; } public E removeFirst() { E x = pollFirst(); if (x == null) throw new NoSuchElementException(); return x; } public E pollFirst() { int h = head; E result = elements[h]; // Element is null if deque empty if (result == null) return null; elements[h] = null; // 重新设置数组中的这个位置为null,方便垃圾回收。 head = (h + 1) & (elements.length - 1);//将head的值回退,相当于将栈的指针又向下移动一格。例如,12--〉13 return result; } public E peekFirst() { return elements[head]; // elements[head] is null if deque empty }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· DeepSeek如何颠覆传统软件测试?测试工程师会被淘汰吗?