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

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关键字 来看一段代码&#xff1a; #include <stdio.h> int main() {int a 10;a 20;printf("%d\n", a);return 0; }运行结果如下&#xff1a; 接下来我们在上面的代码做小小的修改&#xff1a; #include <stdio.h> int main() {const int a 1…...

python之事务

事务&#xff08;Transaction&#xff09;是数据库管理系统&#xff08;DBMS&#xff09;中的一个重要概念&#xff0c;用于确保一组数据库操作要么全部成功&#xff0c;要么全部失败&#xff0c;从而保证数据的一致性和完整性。 事务ACID 特性 事务具有以下四个特性&#xf…...

文件加密软件都有哪些?推荐6款文件加密工具

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

Docker中的容器内部无法使用vi命令怎么办?

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

【Linux系统编程】TCP实现--socket

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

企业微信hook协议接口,聚合群聊客户管理工具开发

服务提供了丰富的API和SDK&#xff0c;可以在企微的功能之上进行应用开发和功能扩展 自建应用可以调用企微hook或协议提供的接口来实现数据交互&#xff0c;可以直接调用hook或协议接口提供的功能来进行消息的发送与接收、用户管理、应用管理等操作&#xff0c;通过接口可以实…...

Selenium集成Sikuli基于图像识别的自动化测试

看起来您提供了一个链接,但目前我并没有从该链接获取到具体的信息内容。不过,如果您希望了解如何将Sikuli集成到Selenium中,我可以为您提供一些基本的指南。 什么是Sikuli? Sikuli是一款开源工具,用于基于图像识别的自动化测试。它可以识别屏幕上的图像,并模拟用户的交…...

【STM32实物】基于STM32设计的智能仓储管理系统(程序代码电路原理图实物图讲解视频设计文档等)——文末资料下载

基于STM32设计的智能仓储管理系统 演示视频: 基于STM32设计的智能仓储管理系统 摘要 近年来,随着我国仓储发展的和药品需求的不断增多,许多医院都采用药物仓储管理系统。我国的药物仓储产业已经有了长足的发展,仓库的规模不断变大,对仓储的要求也不断增高,药物的存储,…...

libtool 中的 .la 文件说明

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

NLP-transformer学习:(6)dataset 加载与调用

NLP-transformer学习&#xff1a;&#xff08;6&#xff09;dataset 加载与调用 平常其实也经常进行trainning等等&#xff0c;但是觉得还是觉得要补补基础&#xff0c;所以静下心&#xff0c;搞搞基础联系 本章节基于 NLP-transformer学习&#xff1a;&#xff08;5&#xff0…...

数据库系统 第43节 数据库复制

数据库复制是一种重要的技术&#xff0c;用于在多个数据库系统之间同步数据。这在分布式系统中尤其重要&#xff0c;因为它可以提高数据的可用性、可扩展性和容错性。以下是几种常见的数据库复制类型&#xff1a; 主从复制 (Master-Slave Replication): 在这种模式下&#xff0…...

LabVIEW FIFO详解

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

如何验证VMWare WorkStation的安装?

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

论文阅读:AutoDIR Automatic All-in-One Image Restoration with Latent Diffusion

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

C++ | Leetcode C++题解之第392题判断子序列

题目&#xff1a; 题解&#xff1a; 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. 从系统启动到第一个进程系统调用&#xff1a;fork(), 创建进程execv()PATH环境变量销毁进程 十二、进程的地址空间**查看进程的地址空间**进程地址空间管理进程地址空间隔离 十三、系统调用和 shell十四、C标准…...

基于ARM芯片与OpenCV的工业分拣机器人项目设计与实现流程详解

一、项目概述 项目目标和用途 本项目旨在设计和实现一套工业分拣机器人系统&#xff0c;能够高效、准确地对不同类型的物品进行自动分拣。该系统广泛应用于物流、仓储和制造业&#xff0c;能够显著提高工作效率&#xff0c;降低人工成本。 技术栈关键词 ARM芯片 步进电机控…...

UNITY UI简易反向遮罩

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

6款靠谱降AI率平台 改写实力出众

写论文时总担心AI生成痕迹太重影响成绩&#xff1f;别慌&#xff0c;这里整理了6款超实用的论文降AI率工具&#xff0c;堪称应对AI痕迹问题的"得力助手"。它们能有效识别并去除AI生成特征&#xff0c;改写能力出色&#xff0c;帮你轻松降低查重率&#xff0c;顺利通过…...

Pikachu暴力破解实战:Burp Suite爆破思维训练全解析

1. 这不是“练手”&#xff0c;是真实世界暴力破解的完整沙盘推演很多人第一次点开Pikachu漏洞练习平台的“暴力破解”模块时&#xff0c;下意识觉得&#xff1a;“不就是写个脚本跑密码字典嘛&#xff1f;Python requests for循环&#xff0c;十分钟搞定。”我当年也是这么想…...

信创中间件深度解析:东方通TongWeb vs 金蝶天燕 vs 宝兰德,企业级选型指南

&#x1f4da; 信创中间件 &#x1f527; 企业级部署 &#x1f680; 国产化替代 ⏱️ 阅读约15分钟开篇导读&#xff1a;你是否在信创改造中不知道用什么替代WebLogic或WebSphere&#xff1f;网上搜到的中间件资料要么只讲产品功能不讲迁移方案&#xff0c;要么直接给配置却不解…...

徒手撸极简前后端分离Demo!吃透原生JS动态渲染底层

之前一直觉得前后端分离是个特别高大上的工程化概念&#xff0c;总以为得学一堆框架、接口规范、部署流程才能上手。 直到昨天我没用Vue、没用React&#xff0c;纯靠原生JSHTMLCSSjson-server&#xff0c;手写了一套最朴素的前后端分离小案例&#xff0c;瞬间把底层逻辑彻底打通…...

企业如何利用 Taotoken 为内部知识问答系统集成大模型

&#x1f680; 告别海外账号与网络限制&#xff01;稳定直连全球优质大模型&#xff0c;限时半价接入中。 &#x1f449; 点击领取海量免费额度 企业如何利用 Taotoken 为内部知识问答系统集成大模型 构建一个高效、可靠的内部知识问答系统&#xff0c;是企业提升信息流转效率…...

融合模糊决策与ECSA优化的软件项目智能风险评估框架

1. 项目概述与核心价值在软件工程这个行当里摸爬滚打十几年&#xff0c;我见过太多项目因为对风险的“视而不见”或“束手无策”而走向失败。项目延期、预算超支、质量滑坡&#xff0c;这些问题的根源往往不是技术本身&#xff0c;而是对潜在威胁的评估和应对失当。传统的风险管…...

App爬虫实战:突破SSL Pinning、动态签名与设备指纹的五层反爬

1. 这不是写个 requests 就能跑通的“爬虫”&#xff0c;而是一场持续数月的攻防拉锯战“App 父亲”这个词在移动互联网圈里没人真叫&#xff0c;但所有做过 App 数据采集的人心里都清楚——你面对的从来不是一串 API 接口&#xff0c;而是一个被精心加固、层层设防、会主动识别…...

体验Taotoken聚合端点带来的高稳定性与低延迟模型调用

&#x1f680; 告别海外账号与网络限制&#xff01;稳定直连全球优质大模型&#xff0c;限时半价接入中。 &#x1f449; 点击领取海量免费额度 体验Taotoken聚合端点带来的高稳定性与低延迟模型调用 作为一名需要频繁调用大模型API的开发者&#xff0c;我曾管理着多个项目&am…...

机器学习研究代码可复现性:从依赖管理到工程化实践

1. 项目概述&#xff1a;为什么机器学习研究需要“工程化”&#xff1f;如果你在机器学习领域摸爬滚打过几年&#xff0c;大概率经历过这样的场景&#xff1a;兴冲冲地打开一篇顶会论文的GitHub仓库&#xff0c;准备复现其惊艳的实验结果&#xff0c;却发现README里只有一句“运…...

客制化键盘党必看:在Ubuntu 22.04上让F1-F12键失灵的HS75T/珂芝K75恢复正常(附一键脚本)

客制化键盘在Ubuntu下的F键修复指南&#xff1a;从原理到一键解决方案作为一名长期使用客制化机械键盘的Linux开发者&#xff0c;我深知那种当F5调试键突然失灵时的崩溃感。特别是当你刚入手一款颜值与手感俱佳的HS75T或珂芝K75&#xff0c;却发现在Ubuntu下连接蓝牙或2.4G接收…...