242. Java 集合 - 在堆栈和队列中存储元素
在 Java 中,堆栈(Stack)和队列(Queue)是经典的数据结构,广泛应用于计算机科学的不同领域。它们有各自独特的操作方式和适用场景。以下是对这两种数据结构的概述及其操作的详细说明。
🔹 队列(Queue)接口层次结构
Java SE 5 引入了 Queue 接口,而 Java SE 6 又扩展了这个接口,增加了 Deque 接口。Queue 接口是 Collection 接口的一个扩展,专门用于处理队列数据结构。
队列接口层次结构
Collection
|
Queue
|
Deque
Queue:代表一个先进先出的数据结构(FIFO)。常见操作包括:add()、remove()、peek()。Deque:双端队列(Double Ended Queue),允许你从队列两端插入和删除元素。它继承自Queue接口,可以用来实现栈和队列的组合。
🏗️ 堆栈(Stack)与队列(Queue)的基本操作
堆栈和队列是经典的线性数据结构,分别遵循 LIFO(后进先出)和 FIFO(先进先出)的原则。
- 堆栈(
LIFO):最后进入的元素最先被移除。 - 队列(
FIFO):最先进入的元素最先被移除。
栈的常见操作:
- push(element):将元素压入栈中。
- pop():移除栈顶元素,即最先被加入的元素。
- peek():查看栈顶元素,但不移除它。
队列的常见操作:
- offer(element):将元素加入队列。
- poll():移除队列头部元素,即最早进入队列的元素。
- peek():查看队列头部元素,但不移除它。
📊 示例代码
1. 堆栈操作(LIFO)
使用 Stack 类来实现堆栈操作:
import java.util.Stack;
public class StackExample {
public static void main(String[] args) {
Stack<String> stack = new Stack<>();
// 压入元素
stack.push("A");
stack.push("B");
stack.push("C");
System.out.println("Stack after push: " + stack);
// 查看栈顶元素但不移除
System.out.println("Peek top element: " + stack.peek());
// 弹出栈顶元素
System.out.println("Pop top element: " + stack.pop());
System.out.println("Stack after pop: " + stack);
}
}
输出:
Stack after push: [A, B, C]
Peek top element: C
Pop top element: C
Stack after pop: [A, B]
2. 队列操作(FIFO)
使用 Queue 接口和 LinkedList 实现队列操作:
import java.util.Queue;
import java.util.LinkedList;
public class QueueExample {
public static void main(String[] args) {
Queue<String> queue = new LinkedList<>();
// 入队元素
queue.offer("A");
queue.offer("B");
queue.offer("C");
System.out.println("Queue after offer: " + queue);
// 查看队列头部元素但不移除
System.out.println("Peek front element: " + queue.peek());
// 出队元素
System.out.println("Poll front element: " + queue.poll());
System.out.println("Queue after poll: " + queue);
}
}
输出:
Queue after offer: [A, B, C]
Peek front element: A
Poll front element: A
Queue after poll: [B, C]
🌟 堆栈与队列的应用场景
堆栈和队列作为经典的数据结构,在很多算法中都有应用,特别是在处理树、图和递归操作时。
堆栈(Stack)的常见应用:
- 表达式求值:使用堆栈来处理数学表达式的求值,特别是在中缀表达式转后缀表达式的过程中。
- 递归调用:程序的调用栈就是堆栈的一个应用,保存了函数调用的上下文信息。
队列(Queue)的常见应用:
- 任务调度:操作系统中的任务调度通常使用队列来实现。
- 广度优先搜索(BFS):图算法中的 BFS 使用队列来遍历节点。
🧠 进一步思考
Queue与Deque的区别:Queue:只允许从队列的一端插入元素(尾部),从另一端删除元素(头部)。Deque:双端队列,允许从队列的两端插入和删除元素,适用于更复杂的操作,如实现栈和队列的组合。
Java 8和更高版本的流式处理:- 通过流(
Streams)操作堆栈和队列可以更高效地处理数据,尤其在并发和复杂数据处理中。
- 通过流(
📜 小结
- 堆栈(
Stack) 遵循 LIFO(后进先出)原则,主要操作包括push()、pop()和peek()。 - 队列(
Queue) 遵循 FIFO(先进先出)原则,主要操作包括offer()、poll()和peek()。 Deque是Queue的扩展,提供双端操作,可以从两端插入和删除元素。- 堆栈和队列在多种计算机科学算法中扮演重要角色,特别是在任务调度、图遍历等场景中。
问题:如果你希望从队列的两端插入和删除元素,你应该选择使用哪个接口?
答案:你应该使用 Deque 接口,它支持双端队列操作。