【数据结构】【学习笔记】队列
队列
队列:先进先出
定义和内置方法
实现思路
方法一:链表实现 (Linked List)
使用链表结构。
双指针记录头和尾: head 和 tail 。
入队:尾部插入节点 \(O(1)\);
出队:头部删除节点 \(O(1)\)。
方法二:数组 + 双指针实现 (Array with Pointers)
使用数组结构,
同样双指针记录头和尾: head 和 tail 。
为了防止数组空间无限膨胀,衍生出循环队列。
具体实现
C#
Queue<T>
// 1. 初始化(需要指定装什么类型)
Queue<int> q = new Queue<int>();
// 2. 入队(塞入尾部)
q.Enqueue(10);
q.Enqueue(20);
// 3. 出队(弹出队头并返回)
int head = q.Dequeue(); // 拿到 10
// 4. 查看队头(不弹出)
int next = q.Peek(); // 拿到 20
// 5. 拿长度
int size = q.Count;
TypeScript
1. 极简使用数组(有坑)
const q: number[] = [];
// 2. 入队:利用 push 塞入尾部
q.push(10);
q.push(20);
// 3. 出队:利用 shift 弹出头部
const head = q.shift(); // 拿到 10
// 4.查看队头
const next = q[0];
// 5. 拿长度
const size = q.length;
但是.shift()的时间复杂度是 \(O(n)\),每次弹出头部都是很昂贵的。
2. 使用拓展库
使用第三方的标准队列库(来自 @datastructures-js/queue)。
const q = new Queue<number>();
q.enqueue(10); // 入队
const head = q.dequeue(); // 出队 (真正 O(1) 性能,不超时)
const next = q.front(); // 看一眼队头
const size = q.size(); // 拿长度
const isEmpty = q.isEmpty(); // 是否为空
重要变体
1. 双端队列 (Deque - Double Ended Queue)
双端队列是一种将栈的原则和队列的原则混合在一起的数据结构。
特点:头部和尾部都可以进行 \(O(1)\) 的入队和出队。
语言支持:C# 的 LinkedList<T> 或 TypeScript 的第三方 Deque 库。
应用:检查一个词组是否构成回文等。
2. 优先队列 (Priority Queue / Heap)
特点:出队顺序由元素优先级决定,而非“先来后到”(通常用堆 Heap 实现,\(O(\log n)\) 插入与弹出)。
应用:Top K 问题、Dijkstra 最短路径算法。
语言支持:.NET 6+ (C# 10+) 已内置 PriorityQueue<TElement, TPriority>。
3. 单调队列 (Monotonic Queue)
特点:队列内元素始终保持单调递增或递减。
应用:解决“滑动窗口最大值/最小值”问题。
4. 循环队列 (Circular Queue)
特点:基于固定大小数组实现,通过 head、tail 指针与模运算 (index + 1) % capacity 复用已释放空间。
应用:
- 在底层开发中被称为 Ring Buffer(环形缓冲区),常用于高并发日志系统(如 LMAX Disruptor)、音频流缓冲区、操作系统进程通信等。
- 游戏开发中如公屏聊天信息的缓冲。
引用
[1] 洛伊安妮·格罗纳.学习JavaScript数据结构与算法(第3版)[M].微信读书版

浙公网安备 33010602011771号