当前位置: 首页 > 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.zskr.cn/news/1458743.html

相关文章:

  • 微信AI助手本地生活推荐系统架构设计:从问答入口到小程序转化的技术链路
  • 长沙市2026年最新黄金回收白银回收铂金回收门店排行榜+联系方式电话推荐 - 大熊猫898989
  • 2026年留学生必备:英文论文降AI保姆级SOP,实测5款工具从95%降至0% - 降AI实验室
  • 010、YOLO Python API 深度编程:自定义训练循环、回调函数与结果解析
  • 深入ZYNQ7000存储测试:对比EMMC裸机读写与SD卡文件系统(FATFS)性能差异
  • 从防御者视角复盘:我是如何用upload-labs靶场,一步步加固我的PHP文件上传功能的
  • 云浮市2026年最新黄金回收白银回收铂金回收门店排行榜+联系方式电话推荐 - 大熊猫898989
  • 告别SuperSU,2024年用Magisk Root安卓手机保姆级教程(附TWRP刷入指南)
  • Bokeh:Python 交互式可视化的老牌选择
  • GPT-5.5智能体与AI芯片协同进化:从提示工程到硬件栈重构
  • 别让浮点数坑了你:游戏开发、金融计算中必须懂的精度陷阱与应对策略
  • 2026毕业季必备指南:亲测4款降AI工具,助你AIGC查重一稿过关无需改二稿 - 降AI实验室
  • 肇庆市2026年最新黄金回收白银回收铂金回收门店排行榜+联系方式电话推荐 - 大熊猫898989
  • KimiClaw:3分钟上手的AI智能体SaaS平台
  • 2026意大利艺术涂料品牌厂家,梳理进口艺术漆:汇总意大利艺术漆十大品牌推荐与产品选购要点 - 栗子测评
  • 深入FX3U软元件内存:停电保持、M8032/M8033标志位,以及如何规划你的数据存储区
  • Grok 4与o3模型能力对比:MoE架构与Dense推理的工程权衡
  • 镇江市2026年最新黄金回收白银回收铂金回收门店排行榜+联系方式电话推荐 - 大熊猫898989
  • 乌鲁木齐市2026年最新黄金回收白银回收铂金回收门店排行榜及联系方式电话推荐 - 盛世金银回收
  • 单HTML体素场景生成:Deepseek V4 Pro + Opencode 实战指南
  • 告别云平台依赖:手把手教你用TTL和Putty给极路由2 HC5761永久开启SSH后台
  • 无锡市2026年最新黄金回收白银回收铂金回收门店排行榜及联系方式电话推荐 - 盛世金银回收
  • HMARK水印算法:LoRA微调与BCH编码的AIGC版权保护方案
  • 芜湖市2026年最新黄金回收白银回收铂金回收门店排行榜及联系方式电话推荐 - 盛世金银回收
  • 中卫市2026年最新黄金回收白银回收铂金回收门店排行榜+联系方式电话推荐 - 大熊猫898989
  • 安装部署k8s高可用集群(Stacked etcd)
  • 南宁市2026年最新黄金回收白银回收铂金回收门店排行榜+联系方式电话推荐 - 大熊猫898989
  • 新余市2026年最新黄金回收白银回收铂金回收门店排行榜及联系方式电话推荐 - 盛世金银回收
  • 别再让空压机‘抽风’了!手把手教你设置SMC继电器的迟滞模式(附参数避坑指南)
  • NIPAP开源IPAM系统:高效管理海量IP地址的终极解决方案