3.1 栈

栈(Stack)是数据结构中的重要概念,也是计算机考研(如408统考)的常考点。本文结合王道考研资料和常见知识点,整理栈的基本概念、实现方式、操作细节及常考题型,帮助考生高效复习。


一、栈的基本概念

栈是一种操作受限的线性表,​​只允许在一端进行插入或删除操作​ ​。其核心特性是​​后进先出(LIFO, Last In First Out)​​。

  • ​栈顶​​:允许插入和删除的一端。

  • ​栈底​​:不允许操作的一端。

  • ​空栈​​:没有元素的栈。

栈的逻辑结构与普通线性表相同,但运算受限,仅支持栈顶操作。基本操作包括:

  • InitStack(&S):初始化栈。

  • DestroyStack(&S):销毁栈。

  • Push(&S, x):进栈(插入元素)。

  • Pop(&S, &x):出栈(删除并返回元素)。

  • GetTop(S, &x):读栈顶元素(不删除)。

  • StackEmpty(S):判空。

栈的典型应用包括函数调用、表达式求值、括号匹配等,考研中常考察其特性和操作细节。


二、顺序栈的实现

顺序栈使用​​数组​​实现栈的存储,分配连续内存空间。

1. 顺序栈的定义

复制代码
#define MaxSize 10 // 定义栈的最大容量
typedef struct {
    ElemType data[MaxSize]; // 静态数组存放元素
    int top;                // 栈顶指针,指向栈顶元素
} SqStack;
  • top通常初始化为 -1(表示空栈),指向当前栈顶元素的位置。

  • 内存分配大小为 MaxSize * sizeof(ElemType)

2. 基本操作

  • ​进栈操作(Push)​​:

    先移动指针,再存入元素。

    复制代码
    bool Push(SqStack &S, ElemType x) {
        if (S.top == MaxSize - 1) return false; // 栈满报错
        S.top++;                 // 指针先加1
        S.data[S.top] = x;       // 再存入元素
        return true;
    }
  • ​出栈操作(Pop)​​:

    先返回元素,再移动指针。

    复制代码
    bool Pop(SqStack &S, ElemType &x) {
        if (S.top == -1) return false; // 栈空报错
        x = S.data[S.top]; // 先返回栈顶元素
        S.top--;           // 指针再减1
        return true;
    }
  • ​读栈顶元素(GetTop)​​:

    与出栈类似,但不移动指针。

    复制代码
    bool GetTop(SqStack S, ElemType &x) {
        if (S.top == -1) return false;
        x = S.data[S.top];
        return true;
    }

3. 共享栈

为节省空间,可让两个栈共享同一数组:

复制代码
typedef struct {
    ElemType data[MaxSize];
    int top0; // 0号栈指针(初始为-1)
    int top1; // 1号栈指针(初始为MaxSize)
} ShStack;
  • ​栈满条件​ ​:top0 + 1 == top1

  • 初始化时,top0 = -1top1 = MaxSize


三、链栈的实现

链栈使用​​链表​​实现栈的存储,无需预设大小,动态分配内存。

1. 链栈的定义

复制代码
typedef struct Linknode {
    ElemType data;          // 数据域
    struct Linknode *next;  // 指针域
} *LiStack;                 // 栈类型定义
  • 通常用​​头插法​​模拟进栈操作,类似单链表的插入。

2. 基本操作

  • ​进栈(Push)​​:

    对应单链表的​​头插法​​,在头部插入新节点。

    复制代码
    // 类似后插操作
    bool Push(LiStack &S, ElemType e) {
        Linknode *s = (Linknode *)malloc(sizeof(Linknode));
        if (!s) return false;
        s->data = e;
        s->next = S;  // S为头指针
        S = s;        // 更新头指针
        return true;
    }
  • ​出栈(Pop)​​:

    对应单链表的​​头删操作​​,删除头节点并返回元素。

    复制代码
    bool Pop(LiStack &S, ElemType &x) {
        if (S == NULL) return false; // 栈空
        Linknode *p = S;
        x = p->data;
        S = p->next;
        free(p);
        return true;
    }
  • ​其他操作​​:

    • GetTop:读取头节点数据。

    • StackEmpty:判断头指针是否为空。

链栈的优点是无栈满问题(除非内存耗尽),但需额外空间存储指针。


四、栈的常考题型与应用

1. 出栈顺序问题

  • ​问题​​:给定进栈顺序(如 a→b→c→d→e),求合法出栈顺序。

  • ​考点​​:卡特兰数(Catalan数)公式:

    复制代码

    表示 n个不同元素的出栈排列数。例如,3个元素有5种合法出栈顺序。

  • ​解题技巧​​:使用栈模拟过程,避免非法顺序(如中间元素先出)。

2. 应用场景

  • ​递归函数调用​​:系统栈管理调用记录。

  • ​表达式求值​​:中缀转后缀,利用栈处理运算符优先级。

  • ​括号匹配​​:遇左括号进栈,遇右括号出栈检查。

  • ​考研高频考点​​:操作序列合法性、栈的初始状态分析等。


五、总结与复习建议

知识回顾

  • ​逻辑结构​​:线性表的特例,LIFO特性。

  • ​存储结构​​:

    • 顺序栈:数组实现,需预设大小,操作高效。

    • 链栈:链表实现,动态扩容,灵活但开销大。

  • ​重要考点​​:基本操作实现、共享栈、出栈序列、应用场景。

复习建议

  1. ​动手练习​​:编写顺序栈和链栈的代码,模拟进栈出栈过程。

  2. ​题型突破​​:重点练习出栈顺序题,结合卡特兰数理解。

  3. ​知识输出​​:尝试向他人讲解栈的操作,巩固记忆(如王道考研提到的"知识输出"理念)。

  4. ​模拟考试​​:定期刷考研真题,关注408统考中栈的相关题目。

本文基于王道考研资料整理,结合常见考研重点,助你高效备考。栈是基础数据结构,掌握其实现和应用对后续学习(如队列、树)至关重要。

相关推荐
1白天的黑夜13 小时前
递归-206.反转链表-力扣(LeetCode)
数据结构·c++·leetcode·链表·递归
sulikey4 小时前
一文彻底理解:如何判断单链表是否成环(含原理推导与环入口推算)
c++·算法·leetcode·链表·floyd·快慢指针·floyd判圈算法
Swift社区4 小时前
LeetCode 402 - 移掉 K 位数字
算法·leetcode·职场和发展
_码力全开_4 小时前
P1005 [NOIP 2007 提高组] 矩阵取数游戏
java·c语言·c++·python·算法·矩阵·go
墨染点香4 小时前
LeetCode 刷题【124. 二叉树中的最大路径和、125. 验证回文串】
算法·leetcode·职场和发展
Camel卡蒙4 小时前
红黑树详细介绍(五大规则、保持平衡操作、Java实现)
java·开发语言·算法
AhriProGramming5 小时前
Flask-SQLAlchemy精读-双语精选文章
python·算法·flask