Skip to content

顺序栈

核心思想

顺序栈的核心特点:

  • 后进先出(LIFO):最后入栈的元素最先出栈
  • 操作受限:只能在栈顶进行插入(入栈/Push)和删除(出栈/Pop)
  • 栈顶指针 top:指示当前栈顶元素的位置

存储结构定义

c
#define MaxSize 50          // 栈的最大容量
typedef struct {
    int data[MaxSize];      // 存放栈中元素
    int top;                // 栈顶指针
} SqStack;

栈顶指针的两种约定

约定初始值栈顶元素栈空条件栈满条件入栈操作出栈操作
top 指向栈顶元素top = -1data[top]top == -1top == MaxSize - 1++top,再赋值先取值,再 top--
top 指向栈顶元素的下一个位置top = 0data[top - 1]top == 0top == MaxSize先赋值,再 ++toptop--,再取值

408 考研默认采用 top = -1 的约定,做题时务必看清题目条件。两种约定下入栈/出栈的操作顺序恰好相反,这是选择题常见陷阱。

入栈与出栈操作流程图

top = -1 约定为例:

交互可视化

通过下方的交互动画,你可以逐步观察顺序栈的执行过程:

加载可视化中...

操作详解

入栈操作

将新元素压入栈顶。入栈前必须判断栈是否已满(栈满上溢)。

关键步骤(top = -1 约定):

  1. 判断栈是否已满(top == MaxSize - 1
  2. 栈顶指针加 1(++top
  3. 将新元素放入栈顶位置
c
// 入栈操作(top = -1 约定)
bool Push(SqStack *S, int x) {
    if (S->top == MaxSize - 1)  // 栈满,上溢
        return false;
    S->data[++S->top] = x;     // 先移指针,再赋值
    return true;
}

出栈操作

弹出栈顶元素。出栈前必须判断栈是否为空(栈空下溢)。

关键步骤(top = -1 约定):

  1. 判断栈是否为空(top == -1
  2. 取出栈顶元素
  3. 栈顶指针减 1(top--
c
// 出栈操作(top = -1 约定)
bool Pop(SqStack *S, int *x) {
    if (S->top == -1)           // 栈空,下溢
        return false;
    *x = S->data[S->top--];    // 先取值,再移指针
    return true;
}

获取栈顶元素(Peek)

仅读取栈顶元素,不修改栈顶指针,栈的状态不变。

c
// 获取栈顶元素
bool GetTop(SqStack S, int *x) {
    if (S.top == -1)
        return false;
    *x = S.data[S.top];        // 只读取,不移动指针
    return true;
}

复杂度分析

操作时间复杂度说明
入栈(Push)O(1)直接在栈顶插入,无需移动元素
出栈(Pop)O(1)直接删除栈顶元素,无需移动元素
获取栈顶(GetTop)O(1)直接通过 top 访问
判空/判满O(1)只需比较 top 的值

空间复杂度:O(1),所有操作只需常数级辅助空间。

与顺序表对比:顺序表的插入/删除需要 O(n) 时间移动元素,而栈由于只在一端操作,所有操作均为 O(1)。

易错:栈顶指针 top 的初始值有两种约定:top = -1(指向栈顶元素)和 top = 0(指向栈顶元素的下一位)。两种约定下入栈出栈操作的顺序不同:前者先 ++top 再赋值,后者先赋值再 top++。408 必须看清题目用的是哪种。

易错:判断栈满的条件是 top == MaxSize - 1(top=-1 约定),不是 top == MaxSize

考研高频考点

  • ⭐ 出栈序列的合法性判断(给定入栈顺序 1,2,3,...,n,判断某个出栈序列是否合法,选择题超高频)
  • top 初始值不同时入栈/出栈代码的区别(top=-1 vs top=0,选择题常见陷阱)
  • ⭐ 栈的应用:括号匹配、表达式求值(中缀转后缀)、递归调用栈(综合题/选择题)
  • n 个不同元素的合法出栈序列总数 = 卡特兰数 C(2n,n)/(n+1)(填空题)
  • 共享栈:两个栈共享一个数组,栈底分别在两端,栈满条件为 top1 + 1 == top2
  • 顺序栈 vs 链栈对比:顺序栈需预分配空间,可能上溢;链栈动态分配,不会上溢但每个节点有指针开销

相关知识

  • 共享栈是顺序栈的空间优化方案——两个栈共享一个数组,避免单独预分配导致的空间浪费
  • 链栈是栈的链式实现,不存在栈满问题,适合元素个数不可预估的场景
  • 括号匹配表达式求值是栈的两大经典应用,408 必考

真题练习

相关真题(11题)

2026Q42综合题10分

栈的出入栈序列:合法性判断、卡特兰数推导、不可能序列的充要条件

2025Q2选择题2分

栈的容量限制:栈容量为 3 时,哪个括号序列的嵌套深度超过 3 而无法匹配

2022Q2选择题2分

栈的出入栈序列:所有元素先入后出则 in 和 out 互为倒序

2020Q2选择题2分

栈的应用:模拟入栈出栈操作验证出栈序列的合法性

2018Q2选择题2分

队列与栈结合:给定入栈序列判断出栈序列的可行性

2017Q2选择题2分

栈的性质与应用:斐波那契递归和出入栈序列的判断

2015Q1选择题2分

栈的递归调用:函数调用时系统栈的入栈顺序(先进后出)

2013Q2选择题2分

栈的出入栈序列:判断合法出栈序列的规律

2011Q2选择题2分

栈的出入栈序列:计算合法出栈序列的个数

2010Q1选择题2分

栈的操作限制:不允许连续三次退栈时的合法出栈序列判断

2009Q2选择题2分

栈的容量计算:追踪入栈出栈过程求栈内最大深度为 3