栈(Stack)是一种常见的数据结构,它遵循“后进先出”(LIFO, Last In First Out)的原则。栈在计算机科学中有广泛的应用,例如在函数调用、表达式求值、括号匹配等场景中。Java提供了内置的Stack
类来实现栈的功能,同时我们也可以通过数组或链表等数据结构来自定义实现栈。本文将详细介绍如何在Java中模拟栈的实现,并探讨如何使用Java内置的Stack
类。
栈是一种线性数据结构,它只允许在一端进行插入和删除操作。这一端被称为栈顶(Top),另一端被称为栈底(Bottom)。栈的操作主要包括:
栈在计算机科学中有广泛的应用,以下是一些常见的应用场景:
在Java中,我们可以通过数组或链表等数据结构来自定义实现栈。下面我们将分别介绍这两种实现方式。
使用数组实现栈时,我们需要定义一个数组来存储栈中的元素,并维护一个指针(通常称为top
)来指示栈顶的位置。初始时,top
指向-1,表示栈为空。每次压栈时,top
指针加1,并将元素存储在数组的相应位置。每次弹栈时,返回top
指针指向的元素,并将top
指针减1。
public class ArrayStack {
private int maxSize; // 栈的最大容量
private int[] stackArray; // 存储栈元素的数组
private int top; // 栈顶指针
// 构造函数,初始化栈
public ArrayStack(int size) {
this.maxSize = size;
this.stackArray = new int[maxSize];
this.top = -1;
}
// 判断栈是否为空
public boolean isEmpty() {
return top == -1;
}
// 判断栈是否已满
public boolean isFull() {
return top == maxSize - 1;
}
// 压栈操作
public void push(int value) {
if (isFull()) {
System.out.println("栈已满,无法压入元素");
return;
}
stackArray[++top] = value;
}
// 弹栈操作
public int pop() {
if (isEmpty()) {
throw new RuntimeException("栈为空,无法弹出元素");
}
return stackArray[top--];
}
// 查看栈顶元素
public int peek() {
if (isEmpty()) {
throw new RuntimeException("栈为空,无法查看栈顶元素");
}
return stackArray[top];
}
// 获取栈的大小
public int size() {
return top + 1;
}
// 打印栈中的元素
public void printStack() {
if (isEmpty()) {
System.out.println("栈为空");
return;
}
for (int i = top; i >= 0; i--) {
System.out.println(stackArray[i]);
}
}
}
public class ArrayStackTest {
public static void main(String[] args) {
ArrayStack stack = new ArrayStack(5);
stack.push(1);
stack.push(2);
stack.push(3);
stack.push(4);
stack.push(5);
System.out.println("栈中的元素:");
stack.printStack();
System.out.println("栈顶元素:" + stack.peek());
System.out.println("弹出栈顶元素:" + stack.pop());
System.out.println("栈中的元素:");
stack.printStack();
System.out.println("栈的大小:" + stack.size());
}
}
使用链表实现栈时,我们可以使用单链表来存储栈中的元素。链表的头节点作为栈顶,每次压栈时,将新元素插入到链表的头部。每次弹栈时,移除链表的头节点并返回其值。
public class LinkedListStack {
private Node top; // 栈顶节点
// 内部类,表示链表的节点
private class Node {
int value;
Node next;
Node(int value) {
this.value = value;
}
}
// 判断栈是否为空
public boolean isEmpty() {
return top == null;
}
// 压栈操作
public void push(int value) {
Node newNode = new Node(value);
newNode.next = top;
top = newNode;
}
// 弹栈操作
public int pop() {
if (isEmpty()) {
throw new RuntimeException("栈为空,无法弹出元素");
}
int value = top.value;
top = top.next;
return value;
}
// 查看栈顶元素
public int peek() {
if (isEmpty()) {
throw new RuntimeException("栈为空,无法查看栈顶元素");
}
return top.value;
}
// 获取栈的大小
public int size() {
int size = 0;
Node current = top;
while (current != null) {
size++;
current = current.next;
}
return size;
}
// 打印栈中的元素
public void printStack() {
if (isEmpty()) {
System.out.println("栈为空");
return;
}
Node current = top;
while (current != null) {
System.out.println(current.value);
current = current.next;
}
}
}
public class LinkedListStackTest {
public static void main(String[] args) {
LinkedListStack stack = new LinkedListStack();
stack.push(1);
stack.push(2);
stack.push(3);
stack.push(4);
stack.push(5);
System.out.println("栈中的元素:");
stack.printStack();
System.out.println("栈顶元素:" + stack.peek());
System.out.println("弹出栈顶元素:" + stack.pop());
System.out.println("栈中的元素:");
stack.printStack();
System.out.println("栈的大小:" + stack.size());
}
}
Java提供了内置的Stack
类来实现栈的功能。Stack
类继承自Vector
类,因此它是线程安全的。Stack
类提供了与栈相关的基本操作,如push
、pop
、peek
等。
Stack
类提供了push(E item)
方法用于将元素压入栈顶。
Stack<Integer> stack = new Stack<>();
stack.push(1);
stack.push(2);
stack.push(3);
Stack
类提供了pop()
方法用于移除并返回栈顶元素。
int topElement = stack.pop(); // 返回3
Stack
类提供了peek()
方法用于返回栈顶元素但不移除它。
int topElement = stack.peek(); // 返回2
Stack
类提供了isEmpty()
方法用于判断栈是否为空。
boolean isEmpty = stack.isEmpty(); // 返回false
Stack
类提供了size()
方法用于获取栈的大小。
int size = stack.size(); // 返回2
import java.util.Stack;
public class StackExample {
public static void main(String[] args) {
Stack<Integer> stack = new Stack<>();
stack.push(1);
stack.push(2);
stack.push(3);
System.out.println("栈中的元素:" + stack);
System.out.println("栈顶元素:" + stack.peek());
System.out.println("弹出栈顶元素:" + stack.pop());
System.out.println("栈中的元素:" + stack);
System.out.println("栈的大小:" + stack.size());
System.out.println("栈是否为空:" + stack.isEmpty());
}
}
虽然Stack
类提供了栈的基本操作,但由于它继承自Vector
类,因此在某些场景下可能不够灵活。例如,Stack
类是线程安全的,但在单线程环境下,这种线程安全性可能会带来额外的性能开销。此外,Stack
类的方法命名与Java集合框架中的其他类不一致,可能会导致代码的可读性下降。
本文详细介绍了如何在Java中模拟栈的实现,并探讨了如何使用Java内置的Stack
类。通过数组和链表两种方式实现栈,我们可以更好地理解栈的工作原理。同时,Java内置的Stack
类为我们提供了便捷的栈操作,但在某些场景下可能需要考虑其局限性。在实际开发中,我们可以根据具体需求选择合适的方式来实现栈的功能。
希望本文能帮助你更好地理解栈的概念及其在Java中的实现方式。如果你有任何问题或建议,欢迎在评论区留言讨论。
亿速云「云服务器」,即开即用、新一代英特尔至强铂金CPU、三副本存储NVMe SSD云盘,价格低至29元/月。点击查看>>
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。
原文链接:https://juejin.cn/post/7224430957222232101