数据结构(笔记)——顺序栈

1.顺序栈的定义

顺序栈是 栈的一种顺序存储结构,即用 一段连续的存储空间(通常是数组)来实现栈。
栈的特点是 先进后出(LIFO, Last In First Out):

只能在一端(称为栈顶 Top)进行插入和删除。

另一端固定(称为栈底 Base)。

2.顺序栈特点

特点说明
存储方式用数组实现,存储空间连续
栈顶位置top指示当前栈顶元素下标
栈底固定数组下标0作为栈底
初始状态top = -1表示空栈
入栈规则top++→ 元素放入data[top]
出栈规则元素取出data[top]→top--
时间复杂度入栈、出栈、取栈顶均为 O(1)
缺点容量固定,不能动态扩展

3.顺序栈与链栈优缺点

对比维度顺序栈链栈
存储方式使用数组,顺序存储使用链表,动态存储
实现难度实现简单,逻辑直观实现稍复杂,需要指针操作
访问速度O(1),数组连续,缓存友好O(1),但需访问指针,速度略慢
存储开销只存数据本身,无额外开销每个节点需要额外存储指针域,占用更多内存
容量大小固定,定义时需设MaxSize动态扩展,受限于内存大小
空间利用若实际数据小于MaxSize,可能浪费空间节点数多少就分配多少,不浪费
灵活性不灵活,扩容需整体拷贝数组灵活,随时可增加或减少节点
适用场景数据规模已知且稳定,例如括号匹配、表达式求值数据规模不确定或变化较大,例如动态处理任务流

4.主要代码

初始化

void InitStack(SeqStack* s) { s->base = (ElemType*)malloc(sizeof(ElemType) * STACK_INIT_SIZE); assert(s->base != NULL); s->capacity = STACK_INIT_SIZE; s->top = 0; }

实现目的
初始化顺序栈,分配初始空间,设置容量和空栈状态。

实现步骤

malloc 分配 STACK_INIT_SIZE 个元素大小的连续内存。

assert 检查分配是否成功。

设置容量 capacity。

把栈顶指针 top 置 0,表示栈为空。

申请空间

bool Inc(SeqStack* s) { ElemType* newbase = (ElemType*)realloc(s->base, sizeof(ElemType) * (s->capacity + STACK_INC_SIZE)); if (newbase == NULL) { printf("空间已满.\n"); return false; } s->base = newbase; s->capacity += STACK_INC_SIZE; return true; }

实现目的
扩容:在栈满时,重新申请更大的空间。

实现步骤

调用 realloc 重新分配空间(在原有空间基础上 +STACK_INC_SIZE 个元素)。

如果返回 NULL,扩容失败,输出提示并返回 false。

否则更新 base 指针和 capacity,扩容成功返回 true。

判断栈满

bool IsFull(SeqStack* s) { return s->top >= s->capacity; }

判断栈空

bool IsEmpty(SeqStack* s) { return s->top == 0; }

插入

void Push(SeqStack* s, ElemType x) { if (IsFull(s) && !Inc(s)) { printf("空间已满,无法插入.\n", x); return; } s->base[s->top++] = x; //s->top++; }

实现目的
入栈:在栈顶插入新元素。

实现步骤

判断是否栈满:

如果满,尝试扩容 Inc。

如果扩容失败,提示并返回。

将新元素存入数组 base[top]。

top++,指向下一个空位置。

删除

void Pop(SeqStack* s) { if (IsEmpty(s)) { printf("栈为空,无法删除.\n"); return; } s->top--; }

实现目的
出栈:删除栈顶元素。

实现步骤

如果栈空,输出提示,返回。

否则 top--,相当于丢弃栈顶元素。

查看栈顶元素

bool GetTop(SeqStack* s, ElemType* v) { if (IsEmpty(s)) { printf("栈为空,无法得到栈头.\n"); return false; } *v = s->base[s->top - 1]; return true; }

实现目的
取栈顶元素,但不删除。

实现步骤

如果栈空,提示并返回 false。

否则,将 top-1 位置的元素赋给 *v,返回 true。

显示

void Show(SeqStack* s) { for (int i = s->top - 1; i >= 0; --i) { printf("%d\n", s->base[i]); } printf("\n"); }

实现目的
打印栈中所有元素(从栈顶到栈底)。

实现步骤

循环从 top-1 到 0,依次输出。

打印换行结束。

长度

int Length(SeqStack* s) { return s->top; }

清除

void Clear(SeqStack* s) { s->top = 0; }

销毁

void Destroy(SeqStack* s) { free(s->base); s->base = NULL; s->capacity = s->top = 0; }

5.栈的应用

应用1

// 行编辑程序,利用顺序栈实现简单的文本编辑功能 void LineEdit() { SeqStack st; // 定义一个顺序栈变量 InitStack(&st); // 初始化栈,置为空栈 char ch = getchar(); // 读入一个字符 while (ch != '$') // 以 $ 作为结束符,遇到 $ 停止输入 { while (ch != '$' && ch != '\n') // 直到遇到换行或结束符 { switch (ch) // 根据不同的输入字符进行处理 { case '#': // 输入 # 表示删除前一个字符 Pop(&st); // 出栈一个字符(删除) break; case '@': // 输入 @ 表示清空一行 Clear(&st); // 清空栈 break; default: // 普通字符 Push(&st, ch); // 入栈保存 break; } ch = getchar(); // 继续读取下一个字符 } Print(&st); // 一行输入结束后,输出当前栈内容 ch = getchar(); // 继续读下一个字符,判断是否为 $ } Destroy(&st); // 输入结束后,销毁栈,释放资源 } void main() { printf("请输入字符序列,'$'结束输入,'#'删除,'@'清空:"); LineEdit(); // 调用行编辑程序 }

应用2

// 将十进制数转换为八进制并输出 void Convert_8(int value) { SeqStack st; // 定义一个顺序栈 InitStack(&st); // 初始化栈(空栈) int v; // 用于临时存放栈顶元素 // ---- 第一步:不断取余数入栈 ---- while (value) // 当 value 还不为 0 时继续循环 { Push(&st, value % 8); // 将 value 除以 8 的余数压入栈中 value /= 8; // value 更新为 value / 8,继续处理 } // 循环结束时,余数按照“低位先入栈”的顺序存放在栈中 // ---- 第二步:出栈并输出 ---- while (!IsEmpty(&st)) // 栈不为空时继续 { GetTop(&st, &v); // 获取栈顶元素,赋值给 v Pop(&st); // 出栈,删除这个栈顶元素 printf("%d", v); // 输出该元素(按出栈顺序得到八进制高位到低位) } printf("\n"); // 换行 } void main() { int value = 47183; // 定义一个十进制整数 Convert_8(value); // 调用函数,将其转换为八进制并输出 }

47183 ÷ 8 = 5897 余 7 5897 ÷ 8 = 737 余 1 737 ÷ 8 = 92 余 1 92 ÷ 8 = 11 余 4 11 ÷ 8 = 1 余 3 1 ÷ 8 = 0 余 1

入栈顺序(从低位到高位):7, 1, 1, 4, 3, 1

出栈顺序(高位到低位):1 3 4 1 1 7

应用3

// 函数:检查字符串中的括号是否匹配 bool Cheak(char *str) { SeqStack st; // 定义一个顺序栈 InitStack(&st); // 初始化栈为空 char v; // 用于保存栈顶元素 // ---- 遍历字符串 ---- while (*str != '\0') // 遍历直到字符串结束符 { // 如果遇到左括号 '[' 或 '(' if (*str == '[' || *str == '(') { Push(&st, *str); // 入栈保存 } // 如果遇到右括号 ']' else if (*str == ']') { GetTop(&st, &v); // 取栈顶元素 if (v != '[') // 如果不是对应的 '[' return false; // 括号不匹配,直接返回错误 Pop(&st); // 匹配成功,弹出左括号 } // 如果遇到右括号 ')' else if (*str == ')') { GetTop(&st, &v); // 取栈顶元素 if (v != '(') // 如果不是对应的 '(' return false; // 括号不匹配 Pop(&st); // 匹配成功,弹出左括号 } ++str; // 指向下一个字符 } // ---- 判断最终结果 ---- return IsEmpty(&st); // 栈为空表示完全匹配,否则有多余左括号 } // 主函数:测试括号匹配 void main() { char *str = "[([(])[])]"; // 测试字符串 bool flag = Cheak(str); // 调用检查函数 if (flag) // 如果匹配成功 { printf("OK!\n"); } else // 匹配失败 { printf("Error!\n"); } }

遇到左括号 → 入栈

把 [ 或 ( 入栈,等候匹配。

遇到右括号 → 检查栈顶

如果栈顶不是对应的左括号 → 说明不匹配,返回 false。

如果匹配 → 弹出栈顶,继续检查下一个字符。

遍历结束

如果栈为空,说明左右括号完全匹配 → 返回 true。

如果栈非空,说明还有没匹配的左括号 → 返回 false。

相关新闻

用Steering Files和Kiro Hooks打造AI编程助手的项目记忆系统

用Steering Files和Kiro Hooks打造AI编程助手的项目记忆系统

你有没有这种感觉——同一个AI编程助手,在别人手里像干了十年的老兵,到了你手里,连你上礼拜刚拆分的模块都记不住。每次它都很客气地说“你好,有什么可以帮你”,然后你只能再花十分钟去解释:我们的项目分层…

2026/10/20 19:24:51 阅读更多 →
如何榨干LFM2.5-24B-A2B-Preview-mxfp8的推理能力:Chat Template与max-tokens配置指南

如何榨干LFM2.5-24B-A2B-Preview-mxfp8的推理能力:Chat Template与max-tokens配置指南

【免费下载链接】LFM2.5-24B-A2B-Preview-mxfp8 项目地址: https://ai.gitcode.com/hf_mirrors/mlx-community/LFM2.5-24B-A2B-Preview-mxfp8 点击查看 免费下载 LFM2.5-24B-A2B-Preview-mxfp8 是 Liquid AI 的 MoE 大语言模型的 MLX 量化版本,总参数 2…

2026/10/20 19:24:51 阅读更多 →
信贷风控实战:从数据清洗到风险定价的完整建模流程

信贷风控实战:从数据清洗到风险定价的完整建模流程

简介:2020年全国大学生数学建模竞赛C题“中小微企业信贷决策”实践资料包,包含可编辑Word论文与MATLAB源代码,面向参赛学生、毕业设计者及金融数据分析学习者,系统展示基于统计建模解决企业信贷风险评估的完整流程。压缩包共160个…

2026/10/20 19:24:51 阅读更多 →

最新新闻

放弃图形化工具,用Git Bash高效管理本地文档的完整指南

放弃图形化工具,用Git Bash高效管理本地文档的完整指南

1. 为什么我最终放弃了图形化工具,回归 Git Bash 管理本地文档很多人第一次接触版本管理,都是从图形化客户端开始的。点几下按钮,仓库就建好了,提交记录也看得见,似乎没什么门槛。但用得越久,我越发现一个尴…

2026/10/20 20:04:05 阅读更多 →
从三个字母到可运行系统:模糊需求下的技术推演与工具设计

从三个字母到可运行系统:模糊需求下的技术推演与工具设计

1. 当标题只剩三个字母时,我在想什么第一次看到这个项目标题的时候,我盯着屏幕愣了大概十秒钟。就三个字母,"rea"。没有正文,没有关键词,没有摘要描述,什么都没有。这种输入状态其实比给一堆杂乱…

2026/10/20 20:04:05 阅读更多 →
贝叶斯优化实战:从网格搜索到高效超参数调参

贝叶斯优化实战:从网格搜索到高效超参数调参

简介:面向机器学习与深度学习实践者的贝叶斯优化实战资源包,聚焦超参数自动化调优这一影响模型性能的关键环节,解决手动试错低效、难以找到最优组合的痛点。包内共4个文件,含两个Python脚本,分别演示贝叶斯优化在ML与D…

2026/10/20 20:04:05 阅读更多 →
C盘无损扩容实战:用DiskGenius挪空间不重装系统

C盘无损扩容实战:用DiskGenius挪空间不重装系统

简介:本资源是一份面向Windows系统用户、特别是SSD主盘空间紧张的普通用户与IT初学者的C盘无损扩容实操指南,解决不重装系统、不格式化分区、不丢失数据的前提下扩大系统盘容量的核心痛点。教程基于免费版DiskGenius(v5.4.6.1441)…

2026/10/20 20:04:05 阅读更多 →
泰山派移植OV8858驱动并添加自动聚焦功能

泰山派移植OV8858驱动并添加自动聚焦功能

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 20:04:05 阅读更多 →
百度网盘免费发放500G空间了,大家记得及时领取

百度网盘免费发放500G空间了,大家记得及时领取

话不多说,直接上图免费网盘空间500G是有30天时效性的,不过每个自然月都是可领取的,大家过期之后记得重新领取即可。比较适合短期应急使用,全程免费,官方长期活动。

2026/10/20 20:03:02 阅读更多 →

日新闻

CLRC663芯片Pin-to-Pin替代实战:从评估到量产全记录

CLRC663芯片Pin-to-Pin替代实战:从评估到量产全记录

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 1:01:30 阅读更多 →
ESP32舵机控制指南:原理、多路驱动与避坑实战

ESP32舵机控制指南:原理、多路驱动与避坑实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 1:01:30 阅读更多 →
位移法实现一阶低通滤波:单片机ADC采样降噪实战

位移法实现一阶低通滤波:单片机ADC采样降噪实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 1:01:30 阅读更多 →

周新闻

基于GMM的语音识别系统原理与MATLAB实现详解

基于GMM的语音识别系统原理与MATLAB实现详解

说到基于高斯混合模型(GMM)的语音识别系统,很多人第一反应就是一堆数学公式,觉得门槛很高。但如果你真的在MATLAB里把它落地跑通,会发现核心其实就是三件事:把声音变成特征向量,用GMM给每个类别…

2026/10/20 10:02:13 阅读更多 →
数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理这四个字听起来挺唬人,但落到具体操作上,无非就是让计算机按你的想法“摆弄”像素。我在一个模拟项目X里用了一套特别经典的基础处理流程:对图像做反白、改调色板、彩色转灰度,最后把像素数据导出成txt文件。单看每一…

2026/10/19 17:32:41 阅读更多 →
机器人大脑技术盘点:具身智能的感知、决策与数据闭环

机器人大脑技术盘点:具身智能的感知、决策与数据闭环

如果你的信息流最近也天天刷到“机器人大脑”这个词,你会发现一个很有意思的现象:每个人说的“大脑”根本不是同一个东西。有人指的是大语言模型,有人指的是运动控制系统,还有人指的是能理解物理世界的端到端模型。在2026年这个时…

2026/10/20 2:50:50 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 10:02:08 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 9:50:17 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 9:50:45 阅读更多 →