链栈的基本操作(c语言实现)

栈的概念

栈:一种特殊的线性表,其只允许在固定的一端进行插入和删除元素操作。进行数据插入和删除操作的一端称为栈顶,另一端称为栈底。栈中的数据元素遵守后进先出LIFO(Last In First Out)的原则。

栈的结构

定义栈

栈有两种常见的定义方式:基于数组(或动态数组)的实现和基于链表的实现。

1. 基于数组(或动态数组)的栈定义

基于数组的实现是最常见的栈定义方式。这种实现方式使用一个固定大小或动态调整大小的数组来存储栈中的元素。数组的一个端点被视作栈底(通常不直接操作),而另一端点被视作栈顶,用于执行压栈和弹栈操作。

  • 压栈(push):将新元素添加到数组的栈顶位置,并更新栈顶指针。
  • 弹栈(pop):移除数组的栈顶元素,并更新栈顶指针。
  • 查看栈顶元素(peek):返回数组的栈顶元素但不移除它。
  • 判断栈是否为空(isEmpty):检查栈顶指针是否指向栈底位置。

基于数组的实现简单且效率高,但存在一个问题:当栈满时,需要预先分配更大的数组空间,这可能导致空间浪费。为了解决这个问题,可以使用动态数组,它在需要时自动扩展大小。

2. 基于链表的栈定义

基于链表的实现使用链表数据结构来存储栈中的元素。链表的头部(或尾部)被视作栈顶,用于执行压栈和弹栈操作。

  • 压栈(push):创建一个新节点,将新元素存储在该节点中,然后将该节点添加到链表的头部(或尾部)。
  • 弹栈(pop):移除链表的头部(或尾部)节点,并返回该节点中存储的元素。
  • 查看栈顶元素(peek):返回链表的头部(或尾部)节点中存储的元素但不移除该节点。
  • 判断栈是否为空(isEmpty):检查链表是否为空。

基于链表的实现不需要预先分配固定大小的空间,因此更加灵活。然而,由于链表中每个节点都需要额外的存储空间来存储指针,因此这种实现方式在内存使用上可能不如基于数组的实现高效。

在实际应用中,根据具体需求和场景选择合适的栈定义方式是很重要的。例如,在需要频繁扩容且内存空间充足的情况下,基于动态数组的栈可能是一个好选择;而在内存使用受限或需要高度灵活性的情况下,基于链表的栈可能更合适。

链栈的定义

typedef int STDataType;//栈中存储的元素类型(这里用整型举例)typedef struct Stack
{STDataType* a;//栈int top;//栈顶int capacity;//容量,方便增容
}Stack;

这里定义了一个结构体,并给它起了一个别名Stack。结构体中包含三个成员:

  • a:这是一个指向STDataType类型的指针,用于存储栈中的元素。它实际上是一个数组,用来存放栈中的各个元素。
  • top:这是一个整数,表示栈顶的位置。在栈中,通常使用top来追踪栈顶元素的位置。当栈为空时,top的值可能是-1或其他表示空栈的值;当栈不为空时,top的值是栈顶元素的索引。
  • capacity:这也是一个整数,表示栈的容量。这通常用于动态数组实现的栈,以便在栈满时知道何时需要扩容。

 栈的基本操作

// 支持动态增长的栈
typedef int STDataType;
typedef struct Stack
{STDataType* _a;int _top; // 栈顶int _capacity; // 容量
}Stack;
// 初始化栈
void StackInit(Stack* ps); 
// 入栈
void StackPush(Stack* ps, STDataType data); 
// 出栈
void StackPop(Stack* ps); 
// 获取栈顶元素
STDataType StackTop(Stack* ps); 
// 获取栈中有效元素个数
int StackSize(Stack* ps); 
// 检测栈是否为空,如果为空返回非零结果,如果不为空返回0 
int StackEmpty(Stack* ps); 
// 销毁栈
void StackDestroy(Stack* ps);

初始化栈

//初始化栈
void StackInit(Stack* pst)
{assert(pst);pst->a = (STDataType*)malloc(sizeof(STDataType)* 4);//初始化栈可存储4个元素pst->top = 0;//初始时栈中无元素,栈顶为0pst->capacity = 4;//容量为4
}

通过这个函数,我们实现了对栈的初始化

销毁栈

因为栈的内存空间是动态开辟出来的,当我们使用完后必须释放其内存空间,避免内存泄漏。

//销毁栈
void StackDestroy(Stack* pst)
{assert(pst);free(pst->a);//释放栈pst->a = NULL;//及时置空pst->top = 0;//栈顶置0pst->capacity = 0;//容量置0
}

入栈

压栈:栈的插入操作叫做进栈 / 压栈 / 入栈。(入数据在栈顶)

进行入栈操作前,我们需要检测栈的当前状态,若已满,则需要先对其进行增容,然后才能进行入栈操作。

//入栈
void StackPush(Stack* pst, STDataType x)
{assert(pst);if (pst->top == pst->capacity)//栈已满,需扩容{STDataType* tmp = (STDataType*)realloc(pst->a, sizeof(STDataType)*pst->capacity *2);if (tmp == NULL){printf("realloc fail\n");exit(-1);}pst->a = tmp;pst->capacity *= 2;//栈容量扩大为原来的两倍}pst->a[pst->top] = x;//栈顶位置存放元素xpst->top++;//栈顶上移
}

出栈

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

出栈操作比较简单,即让栈顶的位置向下移动一位即可。但需检测栈是否为空,若为空,则不能进行出栈操作。

//出栈
void StackPop(Stack* pst)
{assert(pst);assert(!StackEmpty(pst));//检测栈是否为空pst->top--;//栈顶下移
}

获取栈顶元素

获取栈顶元素,即获取栈的最上方的元素。若栈为空,则不能获取。

//获取栈顶元素
STDataType StackTop(Stack* pst)
{assert(pst);assert(!StackEmpty(pst));//检测栈是否为空return pst->a[pst->top - 1];//返回栈顶元素
}

检测栈是否为空

检测栈是否为空,即判断栈顶的位置是否是0即可。若栈顶是0,则栈为空。

//检测栈是否为空
bool StackEmpty(Stack* pst)
{assert(pst);return pst->top == 0;
}

获取栈中有效元素个数

因为top记录的是栈顶,使用top的值便代表栈中有效元素的个数。

//获取栈中有效元素个数
int StackSize(Stack* pst)
{assert(pst);return pst->top;//top的值便是栈中有效元素的个数
}

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

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

相关文章

JVM虚拟机监控及性能调优实战

目录 jvisualvm介绍 1. jvisualvm是JDK自带的可以远程监控内存,跟踪垃圾回收,执行时内存,CPU/线程分析,生成堆快照等的工具。 2. jvisualvm是从JDK1.6开始被继承到JDK中的。jvisualvm使用 jvisualvm监控远程服务器 开启远程监控…

智能家居—ESP32开发环境搭建

相关文章 毕业设计——基于ESP32的智能家居系统(语音识别、APP控制) 智能家居—ESP32开发环境搭建 一、下载安装二、验证三、资料获取 一、下载安装 下载安装 vscode 安装插件 创建工程 二、验证 写一个简单的函数来验证一下功能 void setup() {// put your setup c…

SpringMVC笔记——SpringMVC基础Tomcat环境配置

Tomcat安装配置 下载Apache Tomcat 进入官网https://tomcat.apache.org/,选择tomcat 9 这边使用idea开发,建议直接下载压缩包 无法访问下载的可以直接用我的下载链接:https://cloudreve.zxbdwy.online/s/6nSA 提取码:w1pwk3将压…

【Java并发知识总结 | 第七篇】Java并发相关概念总结(程序/进程/线程、并行/并发、同步/异步、死锁/避免、线程安全/三大特性)

文章目录 7.并发相关概念总结(程序/进程/线程、并行/并发、同步/异步、死锁/避免、线程安全/三大特性)7.1程序、进程与线程7.2并行和并发7.3同步和异步7.4什么是死锁?如何避免?7.5何为线程安全?以及三大特性 7.并发相关…

java多线程-并发和并行

进程 并发 进程中的线程是由CPU进行调度的,但是CPU能够处理的进程数量有限为了保证所有的线程都在运行,CPU会快速切换,给外界的感觉就是所有的线程都在运行,这就是并发。 并行

C语言入门课程学习记录4

C语言入门课程学习记录4 第18课 - signed 与 unsigned第19课 - 再论数据类型第20课 - 经典问题剖析第21课 - 程序中的辅助语句(上)第22课 - 程序中的辅助语句(下) 本文学习自狄泰软件学院 唐佐林老师的 C语言入门课程,…

pytest教程-30-测试数据管理插件-pytest-datadir

领取资料,咨询答疑,请➕wei: June__Go 上一小节我们学习了pytest重复执行用例插件pytest-repeat,本小节我们讲解一下测试数据管理插件-pytest-datadir。 在软件测试中,有效管理测试数据对于编写全面的测试用例至关重要。Pytest…

vue基础教程(7)——构建项目级首页

同学们可以私信我加入学习群! 正文开始 前言一、页面结构二、侧边栏三、主体部分总结 前言 前面我们学习了vue的路由和登录页搭建,本文将和大家共同学习首页的搭建。 首页示例如图: 很多项目经验比较少的同学,一般都是对某些语…

浅谈操作系统中的重要概念——进程

文章目录 一、什么是程序?二、什么是进程?三、进程与程序有什么区别?四、OS是如何管理进程的4.1、使用 结构体 进行描述进程4.2 、使用数据结构组织众多进程4.3、PCB4.3.1、PCB 里有哪些属性4.3.1.1 pid4.3.1.2 内存指针4.3.1.3 文件描述符表…

2024年如何保存微信小程序里的音频文件#下载高手

今年是2024年,仍然有很多人不知道如何下载,本文就带你们学会如何下载微信小程序里面的音频素材 这里要用到一个工具,下载高手 下载高手链接:https://pan.baidu.com/s/1JUWmNXozWSS3xgmvpdyf0g?pwd1234 提取码:1234…

后端程序员利用 AI 给网站制作专业 favicon

看看你的 Chrome 浏览器顶部的标签页,每个标签页前面有一个小小的图标,这个就是 favicon,如果你将网页保存到收藏夹,前面也会是这个小图标。这个图标有时候就是网站的 Logo,有时候也不太一样。 上面截图中&#xff0c…

PHP7 +nginx Docker 部署

一、php docker 1、创建php Docker, Dockerfile文件如下 FROM php:7.3.7-fpmRUN mkdir -p /php/myphp 2、启动脚本start.sh,其中会安装php mysql驱动 #!/bin/bash rm -rf myphp unzip myphp.zip cp .env.pro ./myphp cp .env ./myphpdocker rm -f m…

Apifox接口调试工具

1、Apifox简介 Apifox 是集 API 文档、API 调试、API Mock、API 自动化测试多项实用功能为一体的 API 管理平台,定位为 Postman Swagger Mock JMeter。旨在通过一套系统、一份数据,解决多个工具之间的数据同步问题。只需在 Apifox 中定义 API 文档&a…

leetcode-合并二叉树-90

题目要求 思路 1.如果两个结点都存在,就把对应的val加起来创建一个新的结点 2.如果有一个结点不存在,就用村在的那个结点 3.最后返回创建的头结点 代码实现 /*** struct TreeNode {* int val;* struct TreeNode *left;* struct TreeNode *right;* Tre…

【鸿蒙应用】理财App

目录 第一节项目讲解项目介绍 第二节:项目创建登录静态框架编写登录页面设稿新建项目控制台添加项目Login页面封装标题组件 第三节:登录页静态表单编写第四节—内容页架构分析底部栏组件第五节—底部栏组件切换第六节:首页静态页编写第七节&a…

第十、十一章、十二章 折线图 + 地图 + 柱状图的绘制

第十章 折线图的绘制 官网:pyecharts - A Python Echarts Plotting Library built with love. 画廊官网:Document 懒人工具:懒人工具-手机APP工具下载-手机软件下载大全 - 173软件站 (ab173.com) 导学 json 定义 (1&#xff…

js的算法-交换排序(冒泡)

交换排序 所谓交换排序,是指根据序列中两个元素关键字的比较结果来对换这两个记录在序列中的位置。基于交换的排序算法很多,本次介绍冒泡排序和快速排序。 冒泡 基本思想 从后往前(或从前往后)两两比较相邻元素的值&#xff0…

开启医疗数据新纪元:山海鲸可视化智慧医疗解决方案

在数字化浪潮席卷而来的今天,智慧医疗作为医疗行业的创新力量,正以其独特的技术优势,推动着医疗服务的升级和变革。而在这场变革中,山海鲸可视化以其出色的数据可视化能力,为智慧医疗提供了强大的技术支持,…

PMP®考试的形式、题型、考试内容和趋势

PMP考试形式: 国内的PMP考试是由中国国际人才交流基金会和PMI共同组织举办,统一采取的都是线下笔试。一年考4次,今年的考试安排在3月、6月、8月、11月。3月10日的PMP考试已结束,接下来是6月份的考试,考试时间预计在6月…

qt tcp 连接 秒断连

问题: tcp连接总是秒成功后断连 debug会出现下面这些 onecore\net\netprofiles\service\src\nsp\dll\namespaceserviceprovider.cpp(550)\nlansp_c.dll!00007FFDA2A1D93D: (caller: 00007FFDD8BEACF6) LogHr(1) tid(336c) 8007277C ¡£¡£ one…