3.C_数据结构_栈
概述
什么是栈:
栈又称堆栈,是限定在一段进行插入和删除操作的线性表。具有后进先出(LIFO)的特点。
相关名词:
- 栈顶:允许操作的一端
- 栈底:不允许操作的一端
- 空栈:没有元素的栈
栈的作用:
- 可以检测逻辑图中是否有回路
- 可以将非线性问题线性化
入栈与出栈示意图:
入栈:先指针+1,再入栈数据。出栈:先出栈数据,再指针+1
顺序栈
1、基本内容
顺序栈就是以数组形式进行存储的栈数据结构。
顺序栈结构体如下:
typedef int data_t;
typedef struct{data_t* pData;//数据int max_len; //最大数据长度int top; //栈顶位置
}sqstack,*stacklink;
顺序栈代码的文件构成:
- sqstack.h:数据结构的定义、运算函数接口
- sqstack.c:运算函数接口的实现
- test.c:使用数据结构实现的应用功能代码
顺序栈相关函数:
1、整个栈的创建和删除
- 创建:stacklink stack_create(int len);
- 删除:int stack_delete(stacklink pStack);
2、入栈、出栈
- 入栈:int stack_push(stacklink pStack,data_t data);
- 出栈:int stack_pop(stacklink pStack,data_t* data);
3、其他
- 栈清空:int stack_clean(stacklink pStack);
- 判断栈是否为空:int stack_isempty(stacklink pStack);
2、功能实现
2.1 创建/删除栈
2.1.1 创建
创建栈与创建线性表一样,都是先申请空间,之后赋值初始值
注意:在申请栈成功后,如果申请数据空间失败,需要释放申请的栈空间
具体代码实现如下:
/** stack_create:创建一个栈* param len:栈的长度* @ret NULL--err other--栈的地址* */
stacklink stack_create(int len){stacklink pStack = NULL;//1.申请空间//1.1 栈的空间pStack = (stacklink)malloc(sizeof(sqstack));if(pStack == NULL){printf("stack malloc err\n");return NULL;}//1.2 数据的空间pStack->pData = (data_t*)malloc(sizeof(data_t)*len);if(pStack->pData == NULL){printf("data malloc err\n");free(pStack);//此时pStack已经申请成功,应该释放空间return NULL;}//2.初始化memset(pStack->pData,0,sizeof(data_t)*len);pStack->max_len = len;pStack->top = -1;//-1代表空栈return pStack;
}
2.1.2 删除
删除栈就是释放所申请的空间。
注意:这里申请的空间是栈空间和数据空间,所以要释放两次
具体代码实现如下:
/** stack_delete:栈的释放* param pStack:要进行释放的栈* @ret -1--err 0--success* */
int stack_delete(stacklink pStack){//1.判断栈空间是否为空if(pStack == NULL){printf("pStack is NULL\n");return -1;}//2.释放空间free(pStack->pData);//释放数据空间free(pStack); //释放栈空间pStack = NULL;return 0;
}
2.2 入栈与出栈
2.2.1 入栈
入栈就是先将指针+1,再将数据入栈。
具体代码实现如下:
/** stack_push:入栈* param pStack:所需入栈的栈的位置* param data:所需入栈的数据* @ret -1--err 0--success* */
int stack_push(stacklink pStack,data_t data){//1.判断栈空间是否为空if(pStack == NULL){printf("pStack is NULL\n");return -1;}//2.判断栈空间是否已满if(pStack->top == (pStack->max_len-1)){printf("stack is full\n");return -1;}//3.入栈pStack->top++; //栈顶移动*(pStack->pData + pStack->top) = data; //数据入栈return 0;
}
2.2.2 出栈
入栈就是先将数据出栈,再将指针-1。
具体代码实现如下:
/** stack_pop:出栈* param pStack:要进行出战的栈的位置* param data:出栈数据存储的位置* @ret -1--err 0--success* */
int stack_pop(stacklink pStack,data_t* data){//1.判断栈空间是否为空if(pStack == NULL || data == NULL){printf("pStack is NULL\n");return -1;}//2.判断栈是否为空栈if(pStack->top == -1){printf("stack is empty\n");return -1;}//3.出栈*data = *(pStack->pData + pStack->top);//数据出栈pStack->top--; //顶部移动return 0;
}
2.3 其他
2.3.1 栈清空
栈清空就是让栈的指针指向-1。
栈情况并不需要清空数组中的数据,因为之后写入新数据会自动覆盖旧数据
具体代码实现如下:
/** stack_clean:清空栈* param pStack:要进行清空的栈* @ret -1--err 0--success* */
int stack_clean(stacklink pStack){//1.判断栈空间是否为空if(pStack == NULL){printf("pStack is NULL\n");return -1;}//2.清空栈pStack->top = -1;//设为空栈不需要清空return 0;
}
2.3.2 判断栈是否为空
空栈就是指针指向-1。
具体代码实现如下:
/** stack_isempty:判断栈是否为空栈* param pStack:需要进行判断的栈* @ret -1--err 1--空栈 0--非空栈* */
int stack_isempty(stacklink pStack){//1.判断栈空间是否为空if(pStack == NULL){printf("pStack is NULL\n");return -1;}if(pStack->top == -1){return 1;}else{return 0;}
}
链式栈
1、基本内容
链式栈就是以链表形式进行存储的栈数据结构。
链式栈结构体如下:
typedef int data_t;
typedef struct node{data_t data; //数据struct node* pNext; //链表指针
}listnode,*stacklink;
链式栈代码的文件构成:
- linkstack.h:数据结构的定义、运算函数接口
- linkstack.c:运算函数接口的实现
- test.c:使用数据结构实现的应用功能代码
链式栈相关函数:
1、整个栈的创建和删除
- 栈结点创建:stacklink stacknode_create(void);
- 删除:int stack_delete(stacklink* pStack);
2、入栈、出栈
- 入栈:int stack_push(stacklink* pStack,data_t data);
- 出栈:int stack_pop(stacklink* pStack,data_t* data);
2、功能实现
2.1 创建/删除栈
2.1.1 栈结点创建
使用链式栈时,不是一次性创建一整个栈,而是有一个数据入栈就创建一个栈的结点。
具体代码实现如下:
/** stacknode_create:创建栈结点* @ret NULL--err other--栈的地址* */
stacklink stacknode_create(void){stacklink pStack = NULL;//1.申请空间pStack = (stacklink)malloc(sizeof(listnode));if(pStack == NULL){printf("malloc err\n");return NULL;}//2.初始化memset(pStack,0,sizeof(listnode));pStack->pNext = NULL;return pStack;
}
2.1.1 删除整个栈
删除整个栈就是释放全部的申请空间。
具体代码实现如下:
/** stack_delete:释放整个栈* param pStack:要进行删除的栈* @ret -1--err 0--success* */
int stack_delete(stacklink* pStack){stacklink point = *pStack;//1.栈空间判断if(*pStack == NULL){printf("pStack is NULL\n");return -1;}//2.释放空间while(point != NULL){point = point->pNext;free(*pStack);*pStack = point;}*pStack = NULL;return 0;
}
2.2 入栈与出栈
2.2.1 入栈
链式栈的入栈就是创建一个新结点,并把这个结点进行头插,这样出栈时每次访问头就可以实现后进先出的特点。
具体代码实现如下:
/** stack_push:入栈,头插法* param pStack:要进行插入的栈* param data:要入栈的数据* @ret -1--err 0--success* */
int stack_push(stacklink* pStack,data_t data){stacklink pTmp = NULL;//1. 开辟新的结点pTmp = stacknode_create();if(pTmp == NULL){return -1;}pTmp->data = data;//2.开始入栈,//2.1 有栈空间,进行头插if(*pStack != NULL){pTmp->pNext = *pStack;}//2.2 没有栈空间,当前结点就是头*pStack = pTmp;//最终都要把头指向最新的结点return 0;
}
2.2.2 出栈
链式栈的出栈就访问链表的头,访问之后将头部结点进行删除。
具体代码实现如下:
/** stack_pop:出栈,取出链表头并释放空间* param pStack:要进行出栈的栈* param data:出栈的数据存放的位置* @ret -1--err 0--success* */
int stack_pop(stacklink* pStack,data_t* data){stacklink pTmp = NULL;//1.栈空间判断if(*pStack == NULL){printf("pStack is NULL\n");return -1;}//2.开始出栈*data = (*pStack)->data;//出栈数据pTmp = (*pStack)->pNext;free(*pStack);//释放空间*pStack = pTmp;//改变链表头return 0;
}
相关文章:

3.C_数据结构_栈
概述 什么是栈: 栈又称堆栈,是限定在一段进行插入和删除操作的线性表。具有后进先出(LIFO)的特点。 相关名词: 栈顶:允许操作的一端栈底:不允许操作的一端空栈:没有元素的栈 栈的作用: 可…...
Debian11安装DolphinScheduler
安装地址 前置准备工作 JDK安装 下载JDK (1.8),安装并配置 JAVA_HOME 环境变量,并将其下的 bin 目录追加到 PATH 环境变量中。如果你的环境中已存在,可以跳过这步 二进制包安装DolphinScheduler 依赖 apt-get install psmisc 二进制安…...

C语言深度剖析--不定期更新的第五弹
const关键字 来看一段代码: #include <stdio.h> int main() {int a 10;a 20;printf("%d\n", a);return 0; }运行结果如下: 接下来我们在上面的代码做小小的修改: #include <stdio.h> int main() {const int a 1…...
python之事务
事务(Transaction)是数据库管理系统(DBMS)中的一个重要概念,用于确保一组数据库操作要么全部成功,要么全部失败,从而保证数据的一致性和完整性。 事务ACID 特性 事务具有以下四个特性…...

文件加密软件都有哪些?推荐6款文件加密工具
不久前,一家知名科技公司的内部文件在未经授权的情况下被泄露到了网络上,其中包括了公司的核心技术蓝图、客户名单及未来战略规划。这一事件不仅给公司带来了巨大的经济损失,还严重损害了企业的声誉。 如何防止以上事件的发生呢,文…...

Docker中的容器内部无法使用vi命令怎么办?
不知道你是否遇到过,在修改容器内部的配置的时候,有时候会提示vi命令不可用。尝试去安装vi插件,好像也不是很容易,有什么办法可以帮助我们修改这个配置文件呢? 解决办法 这时候,我们就需要用到docker cp 命令了,它可以帮助我们把容器内部的文件复制到宿主机上,也可以将…...

【Linux系统编程】TCP实现--socket
使用套接字socket实现服务器和客户端之间的TCP通信。 流程如下: 实现代码: /* server.c */ #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <string.h> #include <arpa/inet.h> #include <s…...

企业微信hook协议接口,聚合群聊客户管理工具开发
服务提供了丰富的API和SDK,可以在企微的功能之上进行应用开发和功能扩展 自建应用可以调用企微hook或协议提供的接口来实现数据交互,可以直接调用hook或协议接口提供的功能来进行消息的发送与接收、用户管理、应用管理等操作,通过接口可以实…...
Selenium集成Sikuli基于图像识别的自动化测试
看起来您提供了一个链接,但目前我并没有从该链接获取到具体的信息内容。不过,如果您希望了解如何将Sikuli集成到Selenium中,我可以为您提供一些基本的指南。 什么是Sikuli? Sikuli是一款开源工具,用于基于图像识别的自动化测试。它可以识别屏幕上的图像,并模拟用户的交…...
【STM32实物】基于STM32设计的智能仓储管理系统(程序代码电路原理图实物图讲解视频设计文档等)——文末资料下载
基于STM32设计的智能仓储管理系统 演示视频: 基于STM32设计的智能仓储管理系统 摘要 近年来,随着我国仓储发展的和药品需求的不断增多,许多医院都采用药物仓储管理系统。我国的药物仓储产业已经有了长足的发展,仓库的规模不断变大,对仓储的要求也不断增高,药物的存储,…...

libtool 中的 .la 文件说明
libtool 中的 .la 文件说明 1 概述 在 Linux 系统中,libtool 是一个用于自动化编译和链接复杂软件项目的工具,特别是那些使用了共享库(.so 文件在 Linux 上,.dylib 在 macOS 上)的项目。它帮助处理各种编译器和链接器…...

NLP-transformer学习:(6)dataset 加载与调用
NLP-transformer学习:(6)dataset 加载与调用 平常其实也经常进行trainning等等,但是觉得还是觉得要补补基础,所以静下心,搞搞基础联系 本章节基于 NLP-transformer学习:(5࿰…...
数据库系统 第43节 数据库复制
数据库复制是一种重要的技术,用于在多个数据库系统之间同步数据。这在分布式系统中尤其重要,因为它可以提高数据的可用性、可扩展性和容错性。以下是几种常见的数据库复制类型: 主从复制 (Master-Slave Replication): 在这种模式下࿰…...

LabVIEW FIFO详解
在LabVIEW的FPGA开发中,FIFO(先入先出队列)是常用的数据传输机制。通过配置FIFO的属性,工程师可以在FPGA和主机之间,或不同FPGA VIs之间进行高效的数据传输。根据具体需求,FIFO有多种类型与实现方式&#x…...

如何验证VMWare WorkStation的安装?
如何验证VMWare WorkStation的安装? 右击"网络",点击 打开"网络和Internet设置",点击更改适配器选项,如果出现VMNet1和VMNet8,则说明安装成功。...

论文阅读:AutoDIR Automatic All-in-One Image Restoration with Latent Diffusion
论文阅读:AutoDIR: Automatic All-in-One Image Restoration with Latent Diffusion 这是 ECCV 2024 的一篇文章,利用扩散模型实现图像恢复的任务。 Abstract 这篇文章提出了一个创新的 all-in-one 的图像恢复框架,融合了隐扩散技术&#x…...

C++ | Leetcode C++题解之第392题判断子序列
题目: 题解: class Solution { public:bool isSubsequence(string s, string t) {int n s.size(), m t.size();vector<vector<int> > f(m 1, vector<int>(26, 0));for (int i 0; i < 26; i) {f[m][i] m;}for (int i m - 1; …...

操作系统概述(三、虚拟化)
系列文章目录 文章目录 系列文章目录前言十一、操作系统上的进程1. 从系统启动到第一个进程系统调用:fork(), 创建进程execv()PATH环境变量销毁进程 十二、进程的地址空间**查看进程的地址空间**进程地址空间管理进程地址空间隔离 十三、系统调用和 shell十四、C标准…...
基于ARM芯片与OpenCV的工业分拣机器人项目设计与实现流程详解
一、项目概述 项目目标和用途 本项目旨在设计和实现一套工业分拣机器人系统,能够高效、准确地对不同类型的物品进行自动分拣。该系统广泛应用于物流、仓储和制造业,能够显著提高工作效率,降低人工成本。 技术栈关键词 ARM芯片 步进电机控…...

UNITY UI简易反向遮罩
附带示例资源文件:https://download.csdn.net/download/qq_55895529/89726994?spm1001.2014.3001.5503 大致效果: 实现思路:通过ui shader的模板测试功能实现 通过让想要被突出显示的物体优先渲染并写入模板值,而后再让黑色遮罩渲染并判断模板值进行渲…...

C++实现分布式网络通信框架RPC(3)--rpc调用端
目录 一、前言 二、UserServiceRpc_Stub 三、 CallMethod方法的重写 头文件 实现 四、rpc调用端的调用 实现 五、 google::protobuf::RpcController *controller 头文件 实现 六、总结 一、前言 在前边的文章中,我们已经大致实现了rpc服务端的各项功能代…...
论文解读:交大港大上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架(一)
宇树机器人多姿态起立控制强化学习框架论文解析 论文解读:交大&港大&上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架(一) 论文解读:交大&港大&上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化…...
高防服务器能够抵御哪些网络攻击呢?
高防服务器作为一种有着高度防御能力的服务器,可以帮助网站应对分布式拒绝服务攻击,有效识别和清理一些恶意的网络流量,为用户提供安全且稳定的网络环境,那么,高防服务器一般都可以抵御哪些网络攻击呢?下面…...

CVE-2020-17519源码分析与漏洞复现(Flink 任意文件读取)
漏洞概览 漏洞名称:Apache Flink REST API 任意文件读取漏洞CVE编号:CVE-2020-17519CVSS评分:7.5影响版本:Apache Flink 1.11.0、1.11.1、1.11.2修复版本:≥ 1.11.3 或 ≥ 1.12.0漏洞类型:路径遍历&#x…...

Netty从入门到进阶(二)
二、Netty入门 1. 概述 1.1 Netty是什么 Netty is an asynchronous event-driven network application framework for rapid development of maintainable high performance protocol servers & clients. Netty是一个异步的、基于事件驱动的网络应用框架,用于…...
MinIO Docker 部署:仅开放一个端口
MinIO Docker 部署:仅开放一个端口 在实际的服务器部署中,出于安全和管理的考虑,我们可能只能开放一个端口。MinIO 是一个高性能的对象存储服务,支持 Docker 部署,但默认情况下它需要两个端口:一个是 API 端口(用于存储和访问数据),另一个是控制台端口(用于管理界面…...
人工智能 - 在Dify、Coze、n8n、FastGPT和RAGFlow之间做出技术选型
在Dify、Coze、n8n、FastGPT和RAGFlow之间做出技术选型。这些平台各有侧重,适用场景差异显著。下面我将从核心功能定位、典型应用场景、真实体验痛点、选型决策关键点进行拆解,并提供具体场景下的推荐方案。 一、核心功能定位速览 平台核心定位技术栈亮…...

02.运算符
目录 什么是运算符 算术运算符 1.基本四则运算符 2.增量运算符 3.自增/自减运算符 关系运算符 逻辑运算符 &&:逻辑与 ||:逻辑或 !:逻辑非 短路求值 位运算符 按位与&: 按位或 | 按位取反~ …...

DAY 45 超大力王爱学Python
来自超大力王的友情提示:在用tensordoard的时候一定一定要用绝对位置,例如:tensorboard --logdir"D:\代码\archive (1)\runs\cifar10_mlp_experiment_2" 不然读取不了数据 知识点回顾: tensorboard的发展历史和原理tens…...

智警杯备赛--excel模块
数据透视与图表制作 创建步骤 创建 1.在Excel的插入或者数据标签页下找到数据透视表的按钮 2.将数据放进“请选择单元格区域“中,点击确定 这是最终结果,但是由于环境启不了,这里用的是自己的excel,真实的环境中的excel根据实训…...