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

数据结构——顺序栈

一、顺序栈的定义

栈是限定仅在表尾进行插入和删除操作的线性表,我们允许将插入和删除的一端叫做栈顶,另一端称为栈底,任何数据元素的栈称为空栈,栈又称为后进先出的线性表

栈顶指针:指向的是最后一个元素的下一个位置

注意:首先他是一个线性表,也就是说,栈元素具有线性关系,即前驱后继关系,只不过他是一种特殊的线性表而已。

(1)进栈(入栈,入栈):栈的插入。

(2)出栈(弹栈):栈的删除操作。

二、顺序栈的主要代码实现

1、顺序栈的结构体设计:

(1)与顺序表一样,我们需要一个数组,用来保存后续可能会保存的值,需一个可放入的最大空间,以及此时的数据元素个数

(2)顺序栈一样他也需要一个数组,用来保存后续可能会保存的值,需一个可放入数组元素的最大空间,以及数组的数据元素个数

注:我们不需要单独定义数组元素个数,因为此时栈顶指针做的事情就是指向现有元素的下一个元素的位置,因为数组是元素下标是以0开始所以此时栈顶指向的就是栈的元素的个数,可以把他想象成数组

#define STACK_INIT_SIZE 10//顺序表实现的栈 的初始大小 typedef int ElemType; //顺序栈的结构体设计 typedef struct SeqStack { ElemType* base;//1.指针类型,用来接收malloc的返回值 int top;//2.栈顶指针,用来指向栈顶元素的的下一个存储位置(也能表示当前有效元素个数 int stacksize;//3.当前总的空间大小(用来扩容 }SeqStack;

2、初始化栈

//1.初始化 void Init_SeqStack(SeqStack* psq) { assert(psq != NULL); psq->base = (ElemType*)malloc(STACK_INIT_SIZE * sizeof(ElemType)); if (psq->base == NULL) exit(EXIT_FAILURE); psq->top = 0; psq->stacksize = STACK_INIT_SIZE; }

3、入栈(雷同头插)

思路:

(1)顺序栈可以将其想象为数组,与链表不同他的内存是连续的,所以我们不需要有指针域来保存地址。

(2)判断传入的指针是否有效

(3)因为顺序栈相当于是数组,所以此时如果栈元素所占的字节数已经达到栈的最大内存,那么此时就没有空间可以插入元素,所以需要扩容

(4)因为栈顶指针指向的就是最后元素的下一个元素的位置,因为栈是一个特殊的线性表,他只可以在栈顶插入也只能在栈顶删除。此时栈顶指针指向的位置就是我们即将头插的位置。

(5)将要插入的值给到栈顶指针指向的位置并将栈顶指针+1;

//2.入栈 bool Push(SeqStack* psq, ElemType val) { //0.assert asser(psq!=NULL); //1.判满 (如果满了就扩容) if (Full(psq)) { Increase(psq); } //2.直接给top指向的下标格子进行插入值 val psq->base[psq->top] = val; //3.更新一下top栈顶指针的指向 psq->top++; return true; }

4、出栈(雷同头删)

思路:

(1)因为顺序栈是受到限制的线性表,他只能从栈顶插入栈顶删除。所以具有先进后出的特点。

(2)判断传入指针是否有效

(3)判断顺序表是否是空表如果是空表则删不了

(4)找到合适的删除位置也就是头删,利用栈顶指针(因为栈顶指针指向最后一个有效元素的下一个位置,此时直接让栈顶指针-1,就意味着将原本的栈的最后有效元素给抛弃掉,让原倒数第二个元素变成栈的新的最后一个有效元素)

bool Pop(SeqStack* psq) { //0.assert //1.判空 if (Empty(psq)) { return false; } //2.直接将top指针往后走一下,认为刚才的最后一个元素(刚才的栈顶元素)是无效值即可 psq->top--; return true; }

5、获取栈顶有效元素值(只有读的权限没有改的权限)

思路:

(1)因为顺序栈是受到限制的线性表,他只能从栈顶进行插入,栈顶进行删除,具有先进后出的特点

(2)利用栈顶指针,栈顶指针指向的前一个有效元素给获取出来

(3)如果是空栈就获取不了,直接退出

//4.获取栈顶元素值(只看栈顶元素的值 没有修改权限) ElemType Top(SeqStack* psq) { assert(psq != NULL); if (Empty(psq)) { return; } return psq->base[psq->top--]; }

6、扩容

思路:

(1)因为扩容具有可能会在原始的基础上进行申请空间,也可能新的一片空间,也可能扩容失败,所以需要另外申请一个指针来申请内存

//5.扩容 *2 void Increase(SeqStack* psq) { ElemType*tmp = (ElemType*)realloc(psq->base, psq->stacksize * sizeof(ElemType) * 2); if (tmp != NULL) psq->base = tmp; psq->stacksize *= 2; }

7、判空

思路:

(1)当栈顶指针指向栈底时,也就是0时此时说明没有有效元素

(2)直接return psq->top==0;当满足时就是true 当不满足时就是false

//6.判空 bool Empty(SeqStack* psq) { return psq->top == 0; }

8.判满

思路:

(1)判断栈顶指针指向的是否已经是栈的最大字节格子

//7.判满 bool Full(SeqStack* psq) { return psq->top == psq->stacksize; }

9、打印

//8.打印(用来测试的) void Show(SeqStack* psq) { for (int i = 0; i < psq->top; i++) printf("%d ", psq->base[i]); printf("\n"); }

10、清空

思路:

(1)直接抛弃栈里所有元素,将栈顶指针直接指向0

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

11、销毁

思路:

(1)将申请的空间全部释放掉

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

12、主函数测试

int main() { SeqStack st; Init_SeqStack(&st); Push(&st, 12); Push(&st, 23); Push(&st, 34); Show(&st); Pop(&st); Show(&st); printf("TOP=%d\n", Top(&st)); Push(&st, 12); Push(&st, 23); Push(&st, 34); Push(&st, 12); Push(&st, 23); Push(&st, 34); Push(&st, 12); Push(&st, 23); printf("TOP:%d, StackSize:%d\n", st.top, st.stacksize); Push(&st, 34); Show(&st); printf("TOP:%d, StackSize:%d\n", st.top, st.stacksize); Clear(&st); Show(&st); printf("TOP:%d, StackSize:%d\n", st.top, st.stacksize); Destroy(&st); printf("TOP:%d, StackSize:%d\n", st.top, st.stacksize); return 0; }
http://www.cnnetsun.cn/news/1893205.html

相关文章:

  • 2026 AI 创业黄金赛道:AI 短剧创作系统,低门槛优选
  • ESP32 SPIFFS挂载失败(-10025)的解决方案与分区格式化指南
  • Vite项目打包后本地file协议访问的CORS问题解析与实战解决方案
  • 汽车电子开发实战:NXP FS4505C电源芯片喂狗机制详解(附代码示例)
  • 手把手教你正确配置Anaconda清华镜像源(附.condarc文件完整示例)
  • M2LOrder模型企业级内网穿透部署方案:安全访问GPU算力
  • 噪声整形与过采样实战:从N-bit ADC到DSM的SQNR优化指南
  • 【2026奇点大会核心技术解密】:全球首套商用多模态翻译系统架构、延迟压测数据与跨语种实时对齐算法全披露
  • Qt QPlainTextEdit实战:如何快速实现多行文本编辑与逐行处理(附完整代码)
  • 玩机必备---高通与MTK芯片分区备份实战:从工具选择到操作避坑指南
  • 动手学深度学习——语言模型
  • 基于PointNet++的3D点云分割与体积计算实战指南
  • OpenCore Legacy Patcher深度解析:让旧款Mac重获新生的终极指南
  • LPDDR5 Training:从ZQ校准到命令总线调优的完整流程解析
  • 告别微信群消息手动转发:wechat-forwarding助你实现智能消息同步
  • 3步快速上手:让Unity游戏模组加载变得简单高效的MelonLoader完全指南
  • Vulnhub hack_me_please
  • 南北阁Nanbeige 4.1-3B在卷积神经网络优化中的应用:模型压缩实战
  • Windows系统QT下载(保姆级教程,一步一步手把手教程!都能学会)
  • 手把手教你用MATLAB/Simulink搭建VSG多机并联小信号模型(附源码)
  • 如何永久保存微信聊天记录:留痕工具终极指南
  • Linux 麒麟 源
  • 告别复杂界面!「THE LEATHER ARCHIVE」时尚杂志风UI,小白也能玩转AI绘画
  • 从零到一:手把手教你搭建dSpace HIL仿真环境(基于ConfigurationDesk 6.7)
  • 热喷涂粉末的分类、制备及与3D打印粉末的核心差异
  • 别只看价格!用PCIe转U.2卡给超微X10/X11主板扩容前,先搞懂这3个BIOS关键设置
  • 别再为PT100接线发愁了!用STM32CubeMX+MAX31865三线制测温,从原理图到代码避坑全记录
  • Battery Toolkit:终极Apple Silicon Mac电池健康管理指南,让电池寿命延长50%
  • SystemVerilog三大专用always块:如何避免RTL设计中的常见陷阱
  • Omni-Vision Sanctuary 辅助网络协议教学:可视化生成 TCP/IP 握手过程示意图