242. Java 集合 - 在堆栈和队列中存储元素

49 阅读3分钟

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(先进先出)的原则。

  1. 堆栈(LIFO:最后进入的元素最先被移除。
  2. 队列(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 使用队列来遍历节点。

🧠 进一步思考

  1. QueueDeque 的区别
    • Queue:只允许从队列的一端插入元素(尾部),从另一端删除元素(头部)。
    • Deque:双端队列,允许从队列的两端插入和删除元素,适用于更复杂的操作,如实现栈和队列的组合。
  2. Java 8 和更高版本的流式处理
    • 通过流(Streams)操作堆栈和队列可以更高效地处理数据,尤其在并发和复杂数据处理中。

📜 小结

  • 堆栈(Stack 遵循 LIFO(后进先出)原则,主要操作包括 push()pop()peek()
  • 队列(Queue 遵循 FIFO(先进先出)原则,主要操作包括 offer()poll()peek()
  • DequeQueue 的扩展,提供双端操作,可以从两端插入和删除元素。
  • 堆栈和队列在多种计算机科学算法中扮演重要角色,特别是在任务调度、图遍历等场景中。

问题:如果你希望从队列的两端插入和删除元素,你应该选择使用哪个接口?

答案:你应该使用 Deque 接口,它支持双端队列操作。