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 = -1,top1 = 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统考中栈的相关题目。

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

相关推荐
zyl76512 小时前
FlashAttention 详解:从 GPU 硬件、普通 Attention 到分块计算与 Online Softmax
算法
爱读书的小胖16 小时前
LeetCode 122:买卖股票的最佳时机 II(C)解题分析
算法
结局无敌16 小时前
React Native for OpenHarmony 实战:三方库 react-native-modal-dialog 的鸿蒙化适配指南
深度学习·算法·react native·react.js·harmonyos
OPEN-F17 小时前
ROS2系列教程:上位机建图与导航(原理综合)
算法·机器人
weixin_3077791317 小时前
C++代码实现MATLAB中的fitrtree函数功能
开发语言·c++·算法·matlab
tomwang032217 小时前
路径优化建模、优化算法分类及工程化小结
算法·数学建模·分类
小羊没烦恼!17 小时前
Ajax与JSON的一些总结
android·java·前端·数据库·mysql·算法·okhttp
by2099917 小时前
哈希表——快速找到数据:冲突、删除与扩容的实现
数据结构·c++·哈希算法·散列表
2501_9269783317 小时前
人机通信协议--人和机器之间的交互想象
人工智能·经验分享·算法·ai写作
行者全栈架构师17 小时前
【鸿蒙心迹】互动卡片全链路——把核心功能放到桌面(FormKit 实战)(HarmonyOS 7.x)
前端·算法·架构