Java 数据结构 - 栈(Stack)

Java 数据结构 - 栈(Stack)

Java 中的栈(Stack)数据结构

1. 栈的定义

栈是一种遵循后进先出(LIFO:Last In First Out)原则的线性数据结构。它类似于一叠盘子:你只能在顶部添加或移除盘子。在栈中,我们只能访问最顶端的元素。

2. 栈的基本操作

压栈(Push):将元素添加到栈顶

出栈(Pop):移除并返回栈顶元素

查看(Peek):查看栈顶元素但不移除

判空(isEmpty):检查栈是否为空

3. Java 中的 Stack 类

Java 提供了一个内置的 Stack 类,它扩展了 Vector 类。尽管 Stack 类仍然可用,但在现代 Java 编程中,通常推荐使用 Deque 接口的实现(如 ArrayDeque )来模拟栈的行为。

3.1 使用 Java 的 Stack 类

import java.util.Stack;

public class StackExample {

public static void main(String[] args) {

Stack stack = new Stack<>();

// 压栈

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());

}

}

3.2 使用 Deque 接口实现栈

import java.util.ArrayDeque;

import java.util.Deque;

public class DequeAsStackExample {

public static void main(String[] args) {

Deque 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());

}

}

4. 实现自定义栈

我们可以使用数组或链表来实现自定义栈。以下是使用数组实现的简单栈:

public class ArrayStack {

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;

}

}

5. 栈的应用

栈在计算机科学和日常编程中有广泛的应用,例如:

函数调用和递归

表达式求值和语法解析

撤销操作(Undo)

深度优先搜索(DFS)算法

括号匹配问题

6. 栈的实际应用示例

6.1 括号匹配

public static boolean isBalanced(String expression) {

Stack 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();

}

6.2 逆波兰表达式求值

public static int evaluateRPN(String[] tokens) {

Stack 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();

}

7. 栈的优缺点

优点:

实现简单

后进先出的特性适用于许多算法和问题解决

函数调用和递归的基础

缺点:

只能访问最顶端的元素

不支持随机访问

大小通常是固定的(使用数组实现时)

8. 总结

栈是一种简单而强大的数据结构,在解决特定类型的问题时非常有用。理解栈的工作原理和应用场景对于编写高效的算法和程序至关重要。Java 提供了内置的 Stack 类和更现代的 Deque 接口实现,使得在实际编程中使用栈变得非常方便。

相关推荐