当前位置: 首页 > news >正文

数据结构:栈(C语言版)

前言

学习过了顺序表和链表,接下来我们学习一种新的数据结构,它就是 ‘栈’。那么,让我们来领略一下栈魅力吧。


一、概念和结构

(1)栈的概念:栈是一种特殊的线性表,它只允许固定的一端进行插入和删除元素的操作。进行操作的一端称为栈顶,另一端称为栈底

(2)特点:栈的数据元素遵循后进先出(LIFO)原则。

(3)压栈:栈的插入操作称为压栈 / 入栈 / 进栈,入数据在栈顶

(4)出栈:栈的删除操作叫出栈,出数据也在栈顶

一个简单的示意图如下:

栈底层结构选型栈的实现⼀般可以使⽤动态数组或者链表实现,相对⽽⾔动态数组的结构实现更优⼀些。因为数组在尾部的插入删除数代价⽐较小,而且数组的内存连续,缓存命中率高

二、栈的实现

1.栈的结构定义

typedef int STDataType; typedef struct Stack{ STDataType* arr; int top;//当前元素个数,即下一个入栈位置的下标 int capacity;//已分配的空间大小 }ST;

2.栈的初始化

void STInit(ST* ps){ ps->arr = NULL; ps->top = ps->capacity = 0; }

3.入栈

void StackPush(ST* ps, STDataType x){ assert(ps); if(ps->capacity == ps->top){ int newcapacity = ps->capacity == 0 ? 4 : 2 * ps->capacity; STDataType* tmp = (STDataType*) realloc(ps->arr,newcapacity * sizeof(STDataType)); if(tmp == NULL){ perror("realloc fail!"); exit(1); } ps->arr = tmp; ps->capacity = newcapacity; } ps->arr[ps->top++] = x; }

与前面不同的是,申请空间的代码,不需要将其弄成函数分离在外面,因为栈只有这一个插入操作。

4.判空

bool StackEmpty(ST* ps){ assert(ps); return ps->top == 0; }

因为出栈前要判断栈是否为空,所以要先实现栈的判空。

5.出栈

void StackPop(ST* ps){ assert(ps); assert(!StackEmpty(ps)); --ps->top; // 缩容:使用量 < 1/4 且容量 > 4 时,缩减为一半 if (ps->top > 0 && ps->top <= ps->capacity / 4 && ps->capacity > 4) { int newcapacity = ps->capacity / 2; STDataType* tmp = (STDataType*)realloc(ps->arr, newcapacity * sizeof(STDataType)); if (tmp == NULL) { // 避免缩容失败,数据丢失; perror("realloc fail!"); exit(2); } ps->arr = tmp; ps->capacity = newcapacity; } }

在这里实现的栈的缩容,避免大量入栈后又是大量出栈,导致的空间浪费。

6.取栈顶数据

STDataType StackTop(ST* ps){ assert(ps); assert(!StackEmpty(ps)); return ps->arr[ps->top-1]; }

7.取栈的数据个数

int StackSize(ST* ps){ assert(ps); return ps->top; }

8.栈的销毁

void StackDestroy(ST* ps){ assert(ps); if(ps->arr) free(ps->arr); ps->arr = NULL; ps->capacity = ps->top = 0; }

三、总结

这篇文章围绕栈(Stack)这一数据结构,从概念出发,逐步讲解了其底层实现。核心观点是:栈是一种"后进先出"(LIFO)的受限线性结构,选用动态数组而不是链表来实现,原因在于数组的尾部插入/删除代价小、缓存局部性好。

本期文章到此为止,感谢各位阅读,有问题还请指出,感谢🙏。

http://www.jsqmd.com/news/947229/

相关文章:

  • 从“亚太2R”到“星链”:卫星天线角度计算的原理、变迁与自动化未来
  • 电子厂用什么管理软件?珠三角中小电子厂主流选择:专业易特电子行业ERP深度测评
  • 告别手动画封装!用Cadence Library Builder 16.6从PDF一键生成STM32原理图库
  • 自指螺旋拓扑——认知物理学大一统几何架构研究(世毫九实验室基础理论重大原创交叉课题)
  • 长沙市2026年最新黄金回收白银回收铂金回收门店排行榜+联系方式电话推荐 - 大熊猫898989
  • 利用快马平台快速构建han1me动漫社区应用原型,验证核心功能
  • 2026年留学生必备:英文论文降AI保姆级SOP,实测5款工具从95%降至0% - 降AI实验室
  • 010、YOLO Python API 深度编程:自定义训练循环、回调函数与结果解析
  • 咸阳市2026年最新黄金回收白银回收铂金回收门店排行榜及联系方式电话推荐 - 盛世金银回收
  • 深入ZYNQ7000存储测试:对比EMMC裸机读写与SD卡文件系统(FATFS)性能差异
  • 从防御者视角复盘:我是如何用upload-labs靶场,一步步加固我的PHP文件上传功能的
  • 云浮市2026年最新黄金回收白银回收铂金回收门店排行榜+联系方式电话推荐 - 大熊猫898989
  • C# 抽象类 (abstract class) vs 接口 (interface) 选型与应用场景
  • 用快马ai十分钟打造web版xshell原型,验证服务器管理工具核心交互
  • MATLAB手写霍夫曼编码函数(无工具箱依赖,含建树与编码效率分析)
  • 长治市2026年最新黄金回收白银回收铂金回收门店排行榜+联系方式电话推荐 - 大熊猫898989
  • 游戏手柄延迟检测神器:XInputTest全面指南
  • 告别SuperSU,2024年用Magisk Root安卓手机保姆级教程(附TWRP刷入指南)
  • iPhone 取证:失窃设备保护及其对取证的影响
  • Bokeh:Python 交互式可视化的老牌选择
  • 【绝密级AI红蓝对抗报告】:首次公开AI代理绕过EDR的4种隐式执行链(含MITRE D3FEND映射图谱与反制代码)
  • 运城市2026年最新黄金回收白银回收铂金回收门店排行榜+联系方式电话推荐 - 大熊猫898989
  • 如何快速将HDRI转换为立方体贴图:免费开源工具终极指南
  • Albion Online Statistics Analysis:从游戏数据到战略优势的完整指南
  • 昭通市2026年最新黄金回收白银回收铂金回收门店排行榜+联系方式电话推荐 - 大熊猫898989
  • ECU软件迭代后,A2L文件地址飘了怎么办?ASAP2 Studio增量更新实战指南
  • 湘潭市2026年最新黄金回收白银回收铂金回收门店排行榜及联系方式电话推荐 - 盛世金银回收
  • 别让浮点数坑了你:游戏开发、金融计算中必须懂的精度陷阱与应对策略
  • 为什么你的笔记本电脑、液晶电视从不掉链子?因为藏着AMS1117
  • 肇庆市2026年最新黄金回收白银回收铂金回收门店排行榜+联系方式电话推荐 - 大熊猫898989