V

算法可视化

ZHEN
分享到微博分享到 XGitHub 仓库个人主页
学习工具算法复杂度速查算法学习路径
数据结构数组链表栈队列树堆哈希表图字典树并查集LRU 缓存跳表线段树B+ 树布隆过滤器树状数组
经典排序算法冒泡排序鸡尾酒排序双调排序选择排序插入排序二分插入排序希尔排序归并排序自顶向下归并快速排序三路快排双轴快排堆排序计数排序基数排序桶排序
图算法Dijkstra 最短路Kruskal 最小生成树Prim 最小生成树Bellman-Ford 最短路拓扑排序Floyd 多源最短路强连通分量2-SAT最大流二分图匹配LCA 倍增欧拉路径
动态规划编辑距离0-1 背包完全背包最长公共子序列最长递增子序列硬币找零方案数石子合并旅行商 TSP树形 DP数位 DP换根 DP
回溯与搜索N 皇后子集生成全排列组合总和迷宫寻路岛屿数量单词搜索数独A* 寻路
字符串KMP 字符串匹配Rabin-KarpBoyer-MooreManacher后缀数组LCP / height 数组AC 自动机Z 函数
数学与数论埃氏筛线性筛欧几里得算法快速幂扩展欧几里得中国剩余定理欧拉函数米勒-拉宾FFTPollard's Rho
计算几何凸包旋转卡壳最近点对线段相交扫描线求交
查找二分查找二分边界旋转数组搜索二分答案三分查找

队列 Queue

数据结构 · 先进先出的线性表

什么是队列

队列和栈一样是线性表,但它两端各管一件事:一端只进(队尾),另一端只出(队首)。就像排队买票——新来的排到队尾,叫号的总是队首那位。

从队尾加入一个元素叫 enqueue(入队),从队首拿走一个叫 dequeue(出队),只看队首而不拿走叫 peek。先排进来的先被服务——这就是先进先出(FIFO,First In First Out),正好和栈的后进先出相反。

亲手试试
队列为空

点 enqueue 从队尾加入一个元素试试

试试连入 1、2、3,再连出两次——最先出来的是 1,谁先排队谁先走。和栈对比:同样压/入 1、2、3,栈先吐 3、队列先吐 1。enqueue 和 dequeue 都只动一端,复杂度都是 O(1)。

双端队列 Deque:两端都能进出

普通队列死守 FIFO——只能尾进头出。双端队列(deque,double-ended queue)放宽了这条限制:队头、队尾两端都能进、都能出,于是有四个操作——头部入 pushFront、尾部入 pushBack、头部出 popFront、尾部出 popBack。

正因为两端自由,它是栈和队列的共同推广:只用一端进出,就退化成栈(后进先出);一端进、另一端出,就是普通队列(先进先出)。四个方向都点点看。

亲手试试
1
↑ 队头
↑ 队尾
2
↑ 队头
↑ 队尾
3
↑ 队头
↑ 队尾

双端队列:头、尾两端都能进出。点四个方向试试。

deque 的经典用途是滑动窗口最值——用一个「单调队列」在两端维护候选,进出都 O(1);定长 deque 还能存「最近 N 条」历史 / 撤销记录,挤满了就从另一端丢掉最旧的。另外还有一种带优先级的队列——优先队列,它总让「最小/最大」的先出,本质是一个堆(见堆那篇),和这里按位置进出的 deque 是两回事。

队列在哪里用

队列天然适合「按到达顺序处理」的场景:

消息队列 / 任务调度:先到的请求先处理,削峰填谷。
BFS 广度优先搜索:用队列按层扩展节点。
打印机 / 缓冲区:先发的文档先打印,数据先进先出。

栈和队列是最基础的两种受限线性表。线性表家族里还有更通用的数组和链表,再往后才是有层次的非线性结构——树。