前提必须是数组总容量固定且各栈最大容量已知;采用等长三分法,栈0、1、2分别占据[0,n/3)、[n/3,2n/3)、[2n/3,n),对应栈顶指针初值为0、n/3、2n/3,表示各自下一个可写位置。

用一个数组模拟三个栈需要什么前提?
必须预先知道每个栈的最大容量,或者三者总容量固定——因为数组大小不可变,无法动态伸缩。如果任意一个栈可能无限增长,这种方案就不适用,该换用链表或 vector。
核心思路是把数组切成三段,每段独立管理自己的栈顶指针。常见做法是让栈 0 从下标 0 向上增长,栈 1 从中部开始向上,栈 2 从末尾向下增长;但更简洁、无冲突的做法是:三个栈都从各自起点向上增长,用三个整型变量分别记录栈顶位置(即下一个空闲位置),并提前约定各栈的起始索引和长度。
怎么分配数组空间并初始化三个栈顶指针?
假设数组大小为 N,按等长划分(也可不等):每个栈最多存 N/3 个元素。设栈 0 占 [0, N/3),栈 1 占 [N/3, 2*N/3),栈 2 占 [2*N/3, N)。对应栈顶指针初值为:
top0 = 0top1 = N/3top2 = 2*N/3
注意:这些是“下一个可写位置”,不是当前栈顶下标。入栈时先检查是否越界,再赋值并自增;出栈则先自减,再取值。
push 和 pop 操作如何避免越界和覆盖?
每次 push 前必须检查目标栈是否已满:
- 对栈 0:检查 top0 == N/3
- 对栈 1:检查 top1 == 2*N/3
- 对栈 2:检查 top2 == N
每次 pop 前必须检查是否为空:
- 栈 0 空当 top0 == 0
- 栈 1 空当 top1 == N/3
- 栈 2 空当 top2 == 2*N/3
错误示例:忘记检查就 arr[top0++] = x,会导致越界写入或读取脏数据;或者把栈 1 的 top1 初始值设成 0,直接和栈 0 冲突。
为什么不用“两头向中间”那种经典双栈扩展方式?
双栈可以一头一尾相向增长,靠判断 top1 + 1 == top2 检测满,但三个栈无法自然定义“相邻边界”。若强行让栈 0 从左往右、栈 2 从右往左、栈 1 在中间浮动,会极大增加逻辑复杂度:要动态调整中间栈的区间,还要处理三者互相挤压的边界情况。实际项目中几乎没人这么干——维护成本高,调试困难,且没有明显内存优势。
真正容易被忽略的是:所有栈操作必须是 O(1),不能在 push 时遍历找空位,也不能用额外容器记哪些位置空闲。只要坚持“分区+独立 top 指针”,就能干净满足要求。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











