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

【数据结构】线性数据结构-顺序栈

栈(Stack)是一种基本的数据结构,具有以下特点:
后进先出(LIFO, Last In First Out):栈内的数据项遵循后进先出的原则,即最后存入的项最先被取出。
操作限制:栈通常只允许在一端进行插入和删除操作,这一端称为栈顶(Top),相对的另一端称为栈底(Bottom)。
应用场景:栈常用于解决函数调用、表达式求值、括号匹配等问题。
栈可以通过多种方式实现,常见的有基于数组的实现和基于链表的实现。无论哪种实现方式,都需要支持基本的栈操作如 push(入栈)、pop(出栈)、peek(查看栈顶元素)等。

①SqStack.h

#pragma once//预处理指令,防止头文件被重复包含
typedef int ElemType;
typedef struct {ElemType* elem;     // 存储空间的基址int top;    // 栈顶元素的下一个位置,简称栈顶位标int size;    // 当前分配的存储容量int increment;    // 扩容时,增加的存储容量
} SqStack;         // 顺序栈#define OVERFLOW -1
#define OK 1
#define ERROR 0
#define TRUE 2
#define FALSE -2#define MAXSIZE 20
#define INCREMENT 5typedef int Status;Status InitStack_Sq(SqStack& S, int size, int inc);//初始化空顺序栈S
Status StackEmpty_Sq(SqStack S);//判断栈是否为空
Status Push_Sq(SqStack& S, ElemType e);//入栈操作
Status Pop_Sq(SqStack& S, ElemType& e);//出栈操作

②SqStack.cpp

实现栈的重要的四种基本操作

Status InitStack_Sq(SqStack& S, int size, int inc);//初始化空顺序栈S
Status StackEmpty_Sq(SqStack S);//判断栈是否为空
Status Push_Sq(SqStack& S, ElemType e);//入栈操作
Status Pop_Sq(SqStack& S, ElemType& e);//出栈操作

初始化顺序栈

首先为栈申请一块空间,如果申请失败,即没有足够的内存,返回OVERFLOW

申请成功,注意这里的S.top指向栈顶元素的下一个位置,S.top最先指向0号位置

同时,初始化栈的初始容量和可扩展的容量

Status InitStack_Sq(SqStack& S, int size, int inc) { // 初始化空顺序栈SS.elem = (ElemType*)malloc(size * sizeof(ElemType)); // 分配存储空间if (NULL == S.elem) return OVERFLOW;//分配失败S.top = 0;       // 置S为空栈S.size = size;  // 初始容量值S.increment = inc; // 初始增量值return OK;
}

栈的判空

没有任何元素的时候,栈顶指针指向0号位置,S.top==0

Status StackEmpty_Sq(SqStack S) { // 判断栈S是否空,若空则返回TRUE,否则FALSEif (0 == S.top)return TRUE;elsereturn FALSE;
}

入栈操作

首先,入栈后元素越来越多,有栈满的风险,因此第一步检查栈是否已满

栈的容量是S.size,从0号位置开始,因此存储到S.size-1的位置时栈已经满了,因为S.top指向栈顶元素的位置,即S.top==S.size时栈满。

栈满需要为栈分配空间,使用realloc函数分配更多的空间,同样要判断一下分配失败的情况

分配更大的内存后,要更新基址,同时容量增加了S.increment

入栈时,元素先入栈然后指针向后移,即先使用再加1,对应S.top++这种操作

Status Push_Sq(SqStack& S, ElemType e) { // 元素e压入栈SElemType* newbase;if (S.top >= S.size) { // 若栈顶位标已到达所分配的容量,则栈满,扩容newbase = (ElemType*)realloc(S.elem, (S.size + S.increment) * sizeof(ElemType));if (NULL == newbase) return OVERFLOW;//Add your code here: 调整S.elem和S.sizeS.elem = newbase;S.size += S.increment;}//Add your code here: e入栈,并将S.top加1S.elem[S.top++] = e;return OK;
}

出栈操作

首先,出栈后,元素越来越少,有栈空的风险,因此要先判断是否栈空

调用前面的 Status StackEmpty_Sq(SqStack S) 函数进行判断,栈空不能进行出栈,返回ERROR

出栈时,先取出里面的元素,然后指针向前移,先使用,后减的操作,对应S.top--

Status Pop_Sq(SqStack& S, ElemType& e) { // 栈顶元素出栈,赋给元素e//Add your code here:判断栈空if(StackEmpty_Sq(S)==TRUE)return ERROR;//Add your code here: e出栈,并将S.top减1e = S.elem[S.top-1];S.top--;return OK;
}

③Main.cpp

简单测试前面的接口是否有问题,没有问题的接口封装好就可以用于各种需要栈的场景里了

这里用于进制转换,我们手算进制转换,我们每次取余,直到该数变为0,我们发现先取的余数后被使用,符合栈“先进后出”的特点

#include <stdio.h>
#include "SqStack.h"void Conversion(int N) {SqStack S;ElemType e;InitStack_Sq(S, MAXSIZE, INCREMENT); // 栈S的初始容量为MAXSIZEwhile (N != 0){Push_Sq(S, N % 8);  // 将N除以8的余数入栈N /= 8;             // N取值为其除以8的商}while (TRUE != StackEmpty_Sq(S)){ // 依次输出栈中的余数Pop_Sq(S, e);printf("%d", e);}
}int main() {Conversion(1348);return 0;
}

 

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • ChromaDB教程_2024最新版(上)
  • 《华为交换机堆叠配置》
  • Unity3D入门(一) : 第一个Unity3D项目,实现矩形自动旋转,并导出到Android运行
  • 软考高级:逻辑地址和物理地址转换 AI解读
  • LeetCode[中等] 155. 最小栈
  • React组件如何暴露自身的方法
  • Python | Leetcode Python题解之第415题字符串相加
  • Navicate 链接Oracle 提示 Oracle Library is not loaded ,账号密码都正确地址端口也对
  • Ubuntu LLaMA-Factory实战
  • 【鸿蒙】HarmonyOS NEXT星河入门到实战8-自定义组件-组件通信
  • 机器学习_神经网络_深度学习
  • [OpenGL]使用OpenGL绘制带纹理三角形
  • 【深度学习|可视化】如何以图形化的方式展示神经网络的结构、训练过程、模型的中间状态或模型决策的结果??
  • Compiler Explorer 开源项目-在线编译器网站
  • 9.3Otsu阈值分割
  • Docker 笔记(2):Dockerfile
  • flask接收请求并推入栈
  • jQuery(一)
  • js面向对象
  • js写一个简单的选项卡
  • mysql外键的使用
  • Nginx 通过 Lua + Redis 实现动态封禁 IP
  • node 版本过低
  • Python 使用 Tornado 框架实现 WebHook 自动部署 Git 项目
  • quasar-framework cnodejs社区
  • React Transition Group -- Transition 组件
  • vue2.0一起在懵逼的海洋里越陷越深(四)
  • 从伪并行的 Python 多线程说起
  • 对超线程几个不同角度的解释
  • 欢迎参加第二届中国游戏开发者大会
  • 前端攻城师
  • 体验javascript之美-第五课 匿名函数自执行和闭包是一回事儿吗?
  • 通过获取异步加载JS文件进度实现一个canvas环形loading图
  • 想写好前端,先练好内功
  • No resource identifier found for attribute,RxJava之zip操作符
  • 蚂蚁金服CTO程立:真正的技术革命才刚刚开始
  • ​直流电和交流电有什么区别为什么这个时候又要变成直流电呢?交流转换到直流(整流器)直流变交流(逆变器)​
  • !!【OpenCV学习】计算两幅图像的重叠区域
  • #单片机(TB6600驱动42步进电机)
  • (1)(1.11) SiK Radio v2(一)
  • (2)STL算法之元素计数
  • (2)STM32单片机上位机
  • (30)数组元素和与数字和的绝对差
  • (a /b)*c的值
  • (env: Windows,mp,1.06.2308310; lib: 3.2.4) uniapp微信小程序
  • (ISPRS,2023)深度语义-视觉对齐用于zero-shot遥感图像场景分类
  • (MTK)java文件添加简单接口并配置相应的SELinux avc 权限笔记2
  • (ZT)出版业改革:该死的死,该生的生
  • (翻译)Quartz官方教程——第一课:Quartz入门
  • (附源码)spring boot校园拼车微信小程序 毕业设计 091617
  • (三) diretfbrc详解
  • (三分钟了解debug)SLAM研究方向-Debug总结
  • (四)Controller接口控制器详解(三)
  • (转)IIS6 ASP 0251超过响应缓冲区限制错误的解决方法
  • (转)视频码率,帧率和分辨率的联系与区别