1.栈:后进先出的线性数据结构

一、什么是栈?

栈(Stack)是一种后进先出(LIFO, Last In First Out)的线性数据结构,它只允许在一端进行插入和删除操作,这一端被称为栈顶(top) ,另一端则称为栈底(base)

简单来说,栈就像一个 "一端封闭的容器":

  • 最后放入的元素,会最先被取出;
  • 最先放入的元素,会最后被取出。

二、栈的核心结构

视频中提到,栈的本质是一段连续内存 + 一个栈顶指针

  • 连续内存:用于存储栈中的元素,通常用数组实现;
  • 栈顶指针(top):指向栈顶元素的位置,初始值为 -1,表示栈为空。

对应的 C 语言代码定义如下:

复制代码
#define MAX_SIZE 100  // 栈的最大容量

// 栈的结构体定义
typedef struct {
    int data[MAX_SIZE];  // 连续内存,存储栈元素
    int top;             // 栈顶指针,-1表示空栈
} Stack;

三、栈的基本操作

栈的核心操作有两个:入栈(Push)出栈(Pop) ,这两个操作的时间复杂度都是 O(1)(常数时间),因为它们不需要遍历整个栈,只需要操作栈顶指针。

1. 入栈(Push):压入栈顶

入栈操作是将元素添加到栈顶,步骤如下:

  1. 判满 :如果栈顶指针等于 MAX_SIZE - 1,说明栈已满,无法再添加元素;
  2. 先自增,再写入:将栈顶指针加 1,然后将元素写入到新的栈顶位置。

代码实现:

复制代码
// 入栈操作
void push(Stack *s, int value) {
    // 判满:栈顶指针到达最大容量的前一个位置
    if (s->top == MAX_SIZE - 1) {
        printf("栈已满,无法入栈!\n");
        return;
    }
    // 先自增栈顶指针,再写入元素
    s->data[++s->top] = value;
}

2. 出栈(Pop):弹出栈顶

出栈操作是将栈顶元素取出,步骤如下:

  1. 判空 :如果栈顶指针等于 -1,说明栈为空,无法再取出元素;
  2. 先读取,再自减:先读取栈顶元素,然后将栈顶指针减 1。

代码实现:

复制代码
// 出栈操作
int pop(Stack *s) {
    // 判空:栈顶指针为-1表示空栈
    if (s->top == -1) {
        printf("栈为空,无法出栈!\n");
        return -1;  // 用-1表示错误,实际应用中可自定义错误码
    }
    // 先读取栈顶元素,再自减栈顶指针
    return s->data[s->top--];
}

四、栈的初始化与建立

在使用栈之前,需要先初始化栈,将栈顶指针设置为 -1,表示栈为空。

代码实现:

复制代码
// 初始化栈
void initStack(Stack *s) {
    s->top = -1;  // 栈顶指针归位到-1,表示空栈
}

建立栈的过程就是逐个将元素入栈的过程:

复制代码
int main() {
    Stack s;
    initStack(&s);  // 初始化栈

    // 逐个入栈,建立栈
    push(&s, 10);
    push(&s, 20);
    push(&s, 30);

    // 出栈测试
    printf("出栈元素:%d\n", pop(&s));  // 输出30(后进先出)
    printf("出栈元素:%d\n", pop(&s));  // 输出20
    printf("出栈元素:%d\n", pop(&s));  // 输出10

    return 0;
}

五、栈溢出(Stack Overflow)

栈的容量是有限的,当入栈的元素超过栈的最大容量时,就会发生栈溢出

视频中提到,当栈顶指针越过 MAX_SIZE - 1 时,栈空间就耗尽了,此时入栈操作会失败。

避免栈溢出的方法:

  1. 合理设置栈的最大容量 MAX_SIZE
  2. 在入栈前先判断栈是否已满。

六、总结

栈是一种非常基础且重要的数据结构,它的核心特点是后进先出 ,通过连续内存 + 栈顶指针 实现,基本操作的时间复杂度为 O(1)

在实际应用中,栈常用于:

  • 函数调用栈(保存函数的返回地址和局部变量);
  • 表达式求值(如后缀表达式计算);
  • 括号匹配问题;
  • 深度优先搜索(DFS)等。

希望这篇文章能帮助你理解栈的原理和实现!

相关推荐
LuminousCPP2 小时前
数据结构-时间与复杂度|时间/空间复杂度 + 两道力扣练习 + 二分查找复盘
c语言·数据结构·经验分享·算法·leetcode
Nil2082 小时前
leetcode 三数之和
数据结构·算法·leetcode
带鱼吃猫2 小时前
预处理器:宏、运算符与条件编译
c语言·开发语言
gscsded2 小时前
AUTOSAR CanTp 模块学习笔记
单片机·嵌入式硬件·汽车
Hello_Damon_Nikola3 小时前
扰流筋从原理到应用
人工智能·单片机·嵌入式硬件
某林2123 小时前
从“仿真能跑”到“真机能走”:一套轮腿机械狗强化学习系统的工程化实践
人工智能·stm32·嵌入式硬件·架构·机器人·机械狗
(Charon)3 小时前
【C++】线程安全队列(二):生产者消费者模型与 condition_variable 阻塞等待
c语言·开发语言·c++
青山木3 小时前
Hot 100 --- 最小栈
java·数据结构·算法·leetcode
疯狂打码的少年3 小时前
【数据结构】栈的应用:表达式求值(后缀表达式)
java·数据结构·笔记·算法