栈 --- stack

  • 前言
  • 一、栈结构
  • 二、相关方法
    • 1.初始化
    • 2.入栈
    • 3.出栈
    • 4.判空
    • 5.获取栈顶元素
    • 6.获取栈大小
    • 7.销毁

前言

栈是一个特殊的线性表,遵循一个先进后出的特性,即操作数据(入栈,出栈)只能从栈顶操作,栈底是一个封口的结构。既然是线性表从逻辑结构上是线性的,物理结构上取决于底层实现的结构,若是顺序栈(底层为数组),则是线性的,若是链栈,则是非线性的,本次实现的栈为顺序栈,对比链栈空间更小:
在这里插入图片描述
对比上述两种栈的实现结构,进行入栈出栈操作时,两种结构的时间复杂度都为O(1),但是在进行入栈操作时,假设type是int类型,那么数组结构就只增加4个字节,而链表结构会增加8个或者12个字节,对比而得顺序栈更好,当然也不是一定不能使用链表实现。
同时本次实现栈使用C语言实现

一、栈结构

经由前文使用数组定义栈结构,有三个属性,一个指向栈的指针arr,一个标记栈顶位置和栈实际大小的top(其实也就是顺序表的size)是有效数据的下一个位置,以及一个空间容量capacity。

//定义栈结构
typedef int STDataType;   // 方便更改栈存储数据的类型
typedef struct Stack
{STDataType* arr; //指向栈的指针int top;         //栈顶位置和栈实际大小int capacity;    //空间容量
}ST;

二、相关方法

1.初始化

初始化是将栈初始化成一个空栈,即栈底层数组置为NULL,将top和capacity等于0。

//初始化
void StackInit(ST* ps)
{ps->arr = NULL;ps->top = ps->capacity = 0;
}

2.入栈

入栈操作四步,首先判断传递过来的参数栈是否不为空,不为空才能进行入栈操作,第二步,判断是否需要扩容,当top == capacity时进行扩容操作(两种情况,一为空栈,二为栈满),使用realloc进行扩容操作,第三步,更新数据,当扩容完成后,需要将扩容后的数组和空间大小更新回arr和capacity,最后再在top栈顶位置插入数据,top再加加;
当空间充足时直接进行最后的插入操作。

//入栈
void StackPush(ST* ps, STDataType x)
{assert(ps);   //ps不能传空//首先判断栈空间是否需要增容 --- 没有空间或者空间已满if (ps->top == ps->capacity){// 增容int newcapacity = ps->capacity == 0 ? 4 : 2 * ps->capacity;STDataType* temp = (STDataType*)realloc(ps->arr, newcapacity * sizeof(STDataType));if (temp == NULL){perror("realloc");exit(1);}ps->arr = temp;ps->capacity = newcapacity;}//空间充足 --- top位置入栈,入栈完成top+1ps->arr[ps->top++] = x;
}

3.出栈

出栈首先需要断言传递过来的参数栈不为空,并且栈内需存在元素方可进行出栈操作,其次直接减减top栈顶位置即可。

//出栈 --- 要改变top位置 
void StackPop(ST* ps)
{//assert(ps && ps->top);assert(ps && !StackEmpty(ps));   //ps不能传空,top==0不能再出栈--ps->top;
}

4.判空

当栈为空时,返回true,不为空时返回false。

//判定栈是否为空
bool StackEmpty(ST* ps)
{assert(ps);   //ps不能传空return ps->top == 0;
}

5.获取栈顶元素

获取栈顶元素即获取top位置的元素,并且只是读取元素而不是出栈,故top大小不会改变。

//获取栈顶元素 --- top位置不用改变
STDataType StackTop(ST* ps)
{assert(ps);   //ps不能传空return ps->arr[ps->top-1];
}

6.获取栈大小

//获取栈中有效数据个数
int StackGetSize(ST* ps)
{assert(ps);   //ps不能传空return ps->top;
}

7.销毁

销毁栈空间即将数组置为空,top和capacity等于0,也就是恢复至空栈状态,当然数组若已为NULL了,则无需置空。

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/web/88043.shtml
繁体地址,请注明出处:http://hk.pswp.cn/web/88043.shtml
英文地址,请注明出处:http://en.pswp.cn/web/88043.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【uniapp】---- 在 HBuilderX 中使用 tailwindcss

1. 前言 接手了一个uniapp的微信小程序项目,因为在上一个 taro 的项目中使用的 tailwindcss,感觉比较方便,又不想动项目中原来的代码,因此就配置 tailwindcss,在新创建的子包中使用。 2. 分析 vue2 版本的 uni-app 内置的 webpack 版本为 4 , postcss 版本为 7, 所以还是…

Spring Boot + Easy Excel 自定义复杂样式导入导出

tips&#xff1a;能用模板就用模板&#xff0c;当模板不适用的情况下&#xff0c;再选择自定义生成 Excel。官网&#xff1a;https://easyexcel.opensource.alibaba.com安装<dependency><groupId>com.alibaba</groupId><artifactId>easyexcel</arti…

Spark从入门到实战:安装与使用全攻略

目录一、Spark 简介1.1 Spark 的概念1.2 Spark 的优势1.3 Spark 的应用场景二、安装前准备2.1 硬件要求2.2 软件要求2.3 下载 Spark三、Spark 安装步骤3.1 解压安装包3.2 配置环境变量3.3 配置 spark-env.sh3.4 配置 slaves 文件&#xff08;分布式模式&#xff09;3.5 启动 Sp…

Python 进程间的通信:原理剖析与项目实战

在 Python 编程中,当涉及多进程编程时,进程间的通信(Inter-Process Communication,简称 IPC)是一个重要的课题。多个进程在运行过程中,常常需要交换数据、传递状态或协同工作,这就离不开进程间通信机制。本文将深入讲解 Python 进程间通信的原理,并结合实际项目案例,展…

神经网络之BP算法

一、正向传播正向传播&#xff08;Forward Propagation&#xff09;是神经网络中数据从输入层流向输出层的过程。输入数据通过各层的权重和激活函数逐层计算&#xff0c;最终得到预测输出。数学表示&#xff1a; 对于第 ( l ) 层的神经元&#xff0c;其输出计算如下&#xff1a…

Ubuntu 版本号与别名对照表(部分精选)

Ubuntu 的别名遵循 形容词 动物名 的命名规则&#xff0c;且两个单词首字母相同&#xff0c;按字母表顺序循环使用&#xff08;从 Ubuntu 6.06 开始&#xff09;。 &#x1f4c5; Ubuntu 版本号与别名对照表&#xff08;部分精选&#xff09; 版本号别名 (开发代号)发布时间…

实验03-Spark批处理开发

使用Spark Shell探索RDD 启动并使用Scala Spark Shell 在终端窗口&#xff0c;启动Scala Spark shell&#xff1a; spark-shell --master local查看对象&#xff1a; scala> sc scala> spark输入spark.[TAB]然后可以看到所有可用的方法。 读并显示文本文件 查看文本…

【R语言】Can‘t subset elements that don‘t exist.

Error in select(): ℹ In argument: all_of(label_col). Caused by error in all_of(): ! Cant subset elements that dont exist. ✖ Element Label doesnt exist. Run rlang::last_trace() to see where the error occurred.原文中文解释涉及关键词Error in select()报错发生…

Spring的依赖注入(xml)

引入 首先先明白&#xff0c;依赖注入描述的是在容器中建立bean与bean之间的依赖关系&#xff0c;本质就是将一个类中和别的类解耦的方式&#xff0c;就是把别的类&#xff0c;写在成员变量位置&#xff0c;再对外提供可以给成员变量赋值的方法&#xff0c;外界就直接调用来给…

docker运行的一些常用命令

docker images 显示可以加载的镜像docker ps 显示运行的docker容器 加-a显示所有的容器docker run --name 容器名字 -d 镜像名字docker start 容器名/ID 开启容器docker stop 容器名/ID 关闭容器docker exec -it dock…

Django跨域

步骤 1&#xff1a;安装 django-cors-headerspip install django-cors-headers步骤 2&#xff1a;修改 Django 配置 在 settings.py 中添加&#xff1a;INSTALLED_APPS [...,"corsheaders", # 新增 ]MIDDLEWARE [...,"corsheaders.middleware.CorsMiddleware…

20250706-10-Docker快速入门(下)-Harbor镜像仓库_笔记

一、Harbor镜像仓库搭建与使用1. Harbor概述&#xfeff;&#xfeff;定义: 由VMWare公司开源的容器镜像仓库系统技术基础: 在Docker Registry基础上进行企业级扩展核心特性:提供管理用户界面(GUI)基于角色的访问控制(RBAC)支持&#xfeff;AD/LDAP\mathrm{AD}/\mathrm{LDAP}AD…

JavaScript之数组方法详解

JavaScript之数组方法详解一、数组的创建与基础特性1.1 数组的创建方式1.2 数组的核心特性二、修改原数组的方法2.1 添加/删除元素2.1.1 push()&#xff1a;尾部添加元素2.1.2 pop()&#xff1a;尾部删除元素2.1.3 unshift()&#xff1a;头部添加元素2.1.4 shift()&#xff1a;…

品牌增长困局突围:大模型时代,AI 如何帮我的品牌少走弯路?

AI时代对企业战略的冲击与机遇 在当今瞬息万变的商业环境中&#xff0c;大模型的崛起正以前所未有的力量重塑着各行各业的竞争格局。传统的市场营销、品牌传播模式正在被颠覆&#xff0c;消费者获取信息、认知品牌的方式发生了根本性变化。如果说过去十年是“互联网”的时代&am…

从单体到微服务:Spring Cloud 开篇与微服务设计

一、单体架构的核心痛点与微服务化目标 1. 单体架构的致命缺陷问题表现后果可维护性差百万行代码耦合&#xff0c;修改一处需全量测试迭代周期长&#xff0c;创新停滞扩展性受限无法按模块独立扩缩容&#xff08;如订单模块需扩容时&#xff0c;用户模块被迫一起扩容&#xff0…

篇二 OSI七层模型,TCP/IP四层模型,路由器与交换机原理

一 前言 本章节主要介绍OSI七层模型&#xff0c;TCP/IP四层模型划分&#xff0c;以及日常使用的路由器&#xff0c;交换机的一些基础知识 二 OSI 七层 OSI&#xff08;Open Systems Interconnection Model&#xff09;即开放式系统互联模型&#xff0c;是国际标准化组织提出的&…

【JavaSE面试篇】Java集合部分高频八股汇总

目录 概念 1. 说说Java中的集合&#xff1f; 2. Java中的线程安全的集合有什么&#xff1f; 3. Collections和Collection的区别&#xff1f; 4. 集合遍历的方法有哪些&#xff1f; List 5. 讲一下java里面list的几种实现&#xff0c;几种实现有什么不同&#xff1f; 6.…

利用低空无人机影像进行树种实例分割

在本项先导研究中,我们开发了一个基于低空无人机影像的本地树种机器学习实例分割模型,用于生态调查。该实例分割包括单株树冠的描绘和树种的分类。我们利用无人机影像对20个树种及其对应的学名进行了训练,并收集了这些树种的学名用于机器学习。为了评估该机器学习模型的准确…

二、Flutter基础

目录1. 什么是Widget&#xff1f;Flutter中的Widget分为哪几类&#xff1f;2. StatelessWidget和StatefulWidget的区别3. StatefulWidget生命周期4. 什么是BuildContext&#xff1f;5. 如何优化Widget重建&#xff1f;6. Flutter布局机制7. Row/Column的主轴和交叉轴8. Expande…

设计模式笔记_创建型_建造者模式

1. 建造者模式介绍 建造者模式是一种创建型设计模式&#xff0c;旨在通过将复杂对象的构建过程与其表示分离&#xff0c;使得同样的构建过程可以创建不同的表示。它通常用于构造步骤固定但具体实现可能变化的对象。 1.1 功能&#xff1a; 封装复杂对象的创建过程&#xff1a;适…