算法札记:模拟栈、模拟队列

我以前都直接用的STL,直到我看到某位大神的发言:

在算法竞赛中,绝大多数情况下‌用数组模拟栈更好‌,这是竞赛圈里比较公认的实践。

主要原因有这几点:

1. 速度更快,避免超时

这是最致命也最现实的原因。很多在线评测系统和竞赛环境默认不开 O2 优化,导致 STL 的 stack 容器速度偏慢,在数据量大的题目中容易造成 TLE(超时)。而数组模拟栈是纯数组操作,内存连续,缓存命中率高,速度优势明显。

2. 操作更灵活

数组模拟栈可以很方便地实现一些 STL 栈不支持的操作,比如:

  • 清空栈:tt = 0 一行搞定,而 STL 栈没有直接的 clear() 方法
  • 遍历栈内元素:数组可以直接用下标访问,STL 栈不支持迭代器
  • 查看栈中任意位置的元素:数组可以直接 stk[i],STL 栈只能看栈顶

3. 代码其实也很简洁

数组模拟栈的核心代码就几行,并不比 STL 复杂:

复制代码
cpp 复制代码
const int N = 100010;
int stk[N], tt = 0;      // tt 指向栈顶

stk[++tt] = x;           // 入栈 push
tt--;                    // 出栈 pop
int top = stk[tt];       // 取栈顶 top
bool empty = (tt == 0);  // 判空 empty

‌**那什么时候用 STL 栈呢?**‌

如果题目数据量很小,或者你参加的比赛明确开启了 O2 优化,用 STL 栈完全没问题,代码可读性更高,也更不容易因为手误写出 bug。另外,在一些需要快速验证思路、不追求极致性能的场合,STL 栈也是省心之选。


‌**总结一下:**‌

  • 追求稳定通过、避免玄学超时 → ‌数组模拟栈
  • 数据量小、想偷懒、比赛开 O2 → ‌STL 栈

在 CSP-S、NOIP 这类级别的竞赛中,养成用数组模拟栈的习惯,基本不会吃亏。

我突发奇想,那队列呢?其他STL呢?又去问了Deepseek

他说queue手写,priority_queue、deque、set、map、unordered_map用STL

queue的手写:

cpp 复制代码
const int N = 100010;
int q[N], hh = 0, tt = -1;  // hh 队头,tt 队尾

q[++tt] = x;                // 入队 push
hh++;                       // 出队 pop
int front = q[hh];          // 取队头 front
bool empty = (hh > tt);     // 判空 empty

PS:这个大神是豆包