队列(Queue)
队列(Queue)数据结构
队列是一种先进先出(FIFO, First In First Out)的线性数据结构,类似于现实生活中的排队场景,先到的人先获得服务。
核心特性
- FIFO原则:最先入队的元素最先出队
- 受限访问:
- 只能从队尾(rear)插入元素(入队,enqueue)
- 只能从队首(front)删除元素(出队,dequeue)
- 基本操作:
enqueue:在队尾添加元素dequeue:移除并返回队首元素peek/front:查看队首元素但不移除isEmpty:检查队列是否为空size:获取队列中元素数量
代码实现
1. 基于数组的实现
public class SimpleArrayQueue {
private final int[] queue;
private final int front; // 队首指针
private int rear; // 队尾指针
private int size; // 当前元素数量
private final int capacity; // 队列容量
public SimpleArrayQueue(int capacity) {
this.capacity = capacity;
this.queue = new int[capacity];
this.front = 0;
this.rear = -1;
this.size = 0;
}
// 入队操作,元素放在队尾(所以队尾下标+1)
public void enqueue(int item) {
if (isFull()) {
throw new RuntimeException("Queue is full");
}
rear++;
queue[rear] = item;
size++;
}
// 出队操作,元素顶部弹出(所有元素向前移动,队尾下标要-1)
public int dequeue() {
if (isEmpty()) {
throw new RuntimeException("Queue is empty");
}
int item = queue[front];
// 所有元素向前移动一位
for (int i = 0; i < size - 1; i++) {
queue[i] = queue[i + 1];
}
rear--;
size--;
return item;
}
// 查看队首元素(直接访问队首元素)
public int peek() {
if (isEmpty()) {
throw new RuntimeException("Queue is empty");
}
return queue[front];
}
public boolean isEmpty() {
return size == 0;
}
public boolean isFull() {
return size == capacity;
}
public int size() {
return size;
}
public static void main(String[] args) {
SimpleArrayQueue queue = new SimpleArrayQueue(5);
queue.enqueue(10);
queue.enqueue(20);
queue.enqueue(30);
System.out.println(queue.dequeue()); // 输出: 10
queue.enqueue(40);
queue.enqueue(50);
System.out.println(queue.peek()); // 输出: 20
System.out.println(queue.size()); // 输出: 3
}
}
2. 基于链表的实现
public class LinkedListQueue {
// 定义链表节点
private static class Node {
int data;
Node next;
Node(int data) {
this.data = data;
this.next = null;
}
}
private Node front; // 队首节点
private Node rear; // 队尾节点
private int size; // 队列大小
// 构造函数(初始队首队尾都是空,size 也是 0)
public LinkedListQueue() {
front = null;
rear = null;
size = 0;
}
// 入队操作(链表如果为空:队首队尾都是新元素;链表不为空:队尾是新元素,原队尾的下一个元素是新的队尾元素)
public void enqueue(int item) {
Node newNode = new Node(item);
if (isEmpty()) {
front = newNode;
} else {
rear.next = newNode;
}
rear = newNode;
size++;
}
// 出队操作(队首的下一个元素作为新的队首)
public int dequeue() {
if (isEmpty()) {
throw new RuntimeException("Queue is empty");
}
int item = front.data;
front = front.next;
if (front == null) {
rear = null; // 如果队列已空,重置rear
}
size--;
return item;
}
// 查看队首元素
public int peek() {
if (isEmpty()) {
throw new RuntimeException("Queue is empty");
}
return front.data;
}
// 判断队列是否为空
public boolean isEmpty() {
return front == null;
}
// 获取队列大小
public int size() {
return size;
}
public static void main(String[] args) {
LinkedListQueue queue = new LinkedListQueue();
queue.enqueue(10);
queue.enqueue(20);
queue.enqueue(30);
System.out.println("Dequeued: " + queue.dequeue()); // 输出: Dequeued: 10。弹出队首
System.out.println("Front element: " + queue.peek()); // 输出: Front element: 20。查看队首
System.out.println("Queue size: " + queue.size()); // 输出: Queue size: 2。队列数量
}
}
时间复杂度分析
数组实现
| 操作 | 时间复杂度 | 说明 |
|---|---|---|
| enqueue() | O(1) | 在rear位置插入元素 |
| dequeue() | O(n) | 需要移动所有剩余元素前移 |
| peek() | O(1) | 访问front位置的元素 |
| isEmpty() | O(1) | 检查front和rear位置 |
| size() | O(1) | rear - front + 1 |
链表实现
| 操作 | 时间复杂度 | 说明 |
|---|---|---|
| enqueue() | O(1) | 直接在rear节点后添加新节点 |
| dequeue() | O(1) | 直接移除front节点 |
| peek() | O(1) | 访问front节点的数据 |
| isEmpty() | O(1) | 检查front是否为null |
| size() | O(1) | 如果维护size变量 |
JDK 中的队列
-
双端队列(Deque):两端都可插入删除。分成两组,每一组一端进一端出
ArrayDeque数组实现,线程不安全(既具有队列的特性也具有栈的特性)
LinkedList链表实现,线程不安全
LinkedBlockingDeque链表实现,线程安全 -
优先队列(Priority Queue):按优先级出队。树实现(平衡树或二叉堆),入队要维护树,出队也要维护树,时间复杂度是 O(log n)。
因为是树,已经有顺序了,出队时能比较高效的找出哪个元素要优先出队PriorityQueue小顶堆实现(根节点最小,根节点就是最优先的),线程不安全
PriorityBlockingQueue小顶堆实现(根节点最小,根节点就是最优先的),线程安全 -
循环队列:JDK 中没有已实现好循环队列
-
阻塞队列:加锁实现。一把锁方案:出队和入队使用同一把锁;两把锁方案:出队和入队使用不同的锁
ArrayBlockingQueue单锁,数组实现,线程安全
LinkedBlockingQueue双锁,链表实现,线程安全
队列与栈的对比
| 特性 | 队列(Queue) | 栈(Stack) |
|---|---|---|
| 原则 | FIFO (先进先出) | LIFO (后进先出) |
| 插入位置 | 队尾(rear) | 栈顶(top) |
| 删除位置 | 队首(front) | 栈顶(top) |
| 典型应用 | BFS、任务调度 | DFS、函数调用栈 |
队列是计算机科学中最重要的基础数据结构之一,广泛应用于各种需要公平性、顺序处理的场景。

浙公网安备 33010602011771号