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

数据结构——栈的讲解(超详细)

前言:

  小编已经在前面讲完了链表和顺序表的内容,下面我们继续乘胜追击,开始另一个数据结构:栈的详解,下面跟上小编的脚步,开启今天的学习之路!

目录

 1.栈的概念和结构

 1.1.栈的概念

 1.2.栈的结构

  

2.栈的实现 (此实现是基于顺序表实现的)

 2.1.栈的初始化

 2.2.栈的销毁

 2.3.入栈

 2.4.出栈

 2.5.取出栈顶的元素

 2.6.判断栈中有效的数据个数

 2.7.栈元素的打印

3.代码展示

 3.1.Stack.h

  3.2.Stack.c

总结 


正文:

 1.栈的概念和结构

 1.1.栈的概念

  栈是一种特殊的线性表,它只允许一端进一端出,只允许在固定的一端去删除数据和插入数据,对于进行插入和删除操作的地方叫做栈顶,另一端叫做栈底,栈中的数据元素遵从后进先出LIFO的原则,简单来说就是最后一个进的最先出来,这和它的结构有关,下面我们来看一下栈的结构

 1.2.栈的结构

  

  上图就是栈的结构图,小编在概念也说过,栈是有栈顶和栈底的,栈顶就是一个出入口,所以我们可以把栈看做成一个罐子,数据只可以从栈顶进行进入和出去,以上就是关于栈的概念和结构了,光知道栈的结构是概念是不够的,下面小编讲带领大家去实现一个栈!

2.栈的实现 (此实现是基于顺序表实现的)

  在讲一些栈的功能之前,由于栈是一种线性表,所以我们实现栈的可以有顺序表,链表两种方式来实现,由于时间复杂度等的原因,小编在这里选择用顺序表实现,但这并不代表着我们不可以用链表实现,小编曾经做过题,那个题就让我们用链表来实现栈,可千万不要以为栈只能用顺序表实现,这是重点!下面小编先给各位栈结构体的内容:

typedef int STDataType;
typedef struct stack {STDataType* arr;   //数组,类型可能不是一定的所以用typedef替换一下int capacity;  //总空间大小int top;      //栈顶表示
}ST;

 2.1.栈的初始化

  我们在每次写一个线性表之前,初始化是必备的操作,因为栈是基于顺序表实现的,所以初始化也顺序表类似,首先我们需要把数组指针先设置为空,对于总空间大小和栈元素个数(栈顶)都得设置为0,由于难度不大,小编就不给各位图演示了,直接上代码:

void STInit(ST* ps)
{ps->arr = NULL;ps->capacity = ps->top = 0;  //总空间个数和有用空间个数都初始化为0
}

 2.2.栈的销毁

  有了初始化操作,自然而然就有着销毁操作,毕竟“有始有终” ,栈的销毁同样也是不难的,我们对于arr,需要判断它是否开辟了空间,如果开辟了就free掉,没有开辟就直接把栈的空间大小和栈顶都置为空就好,下面直接上代码图:

void STDestroy(ST* ps)
{if (ps -> arr)   //先判断是否进行动态内存开辟了{free(ps -> arr);}ps->capacity = ps->top = 0;
}

 2.3.入栈

  在进行完初始化操作以后,就要进行一些正式操作了,看着入栈这个名字很高大尚,以小编的话来说这其实就是栈的尾插(栈也只能尾插,因为只能从栈顶插入),就类似下图:

  上面这个图就展示了入栈操作,其实就是我们在顺序表阶段写的尾插操作,首先我们需要先设置一个函数,来判断一下栈的总空间大小和栈顶是否是相等,如果相等了那就扩容,这个和顺序表的扩容是一样的,详情可以看小编之前写的那一篇,由于栈的插入只有入栈这一种,所以扩容操作直接写到函数内部就好,我们在进行完插入以后,直接往栈顶插入数据,然后让栈顶在想后走一步就好了,下面直接展示代码:

void STPush(ST* ps, STDataType x)   //类似顺序表的尾插
{if (ps->capacity == ps->top){int newcaopacity = ps->capacity == 0 ? 4 : 2 * ps -> capacity;STDataType* arr1 = (STDataType*)realloc(ps->arr, newcaopacity * sizeof(STDataType));assert(arr1);ps->arr = arr1;ps->capacity = newcaopacity;}  //扩容完成ps->arr[ps->top++] = x;
}

 2.4.出栈

  有入栈肯定就会有出栈,对于栈的出栈,其实就是顺序表的尾删操作,因为栈的元素只能从栈顶出,栈底是不可以出元素的,可以类比下图进行记忆:

  通过上图我们就可以知道出栈到底是什么东西,对于出栈,我们首先需要判断栈是不是空的,不然拿什么来出栈?所以此时我们得写一个布尔类型函数来判断一下此时的栈是否是空的,如果是空的返回true,不是真的返回false,此时我们进需要判断栈顶是否为0就好,下面小编直接给代码图:

bool panduan(ST * ps)
{assert(ps);return ps -> top == 0;   //这个是来判断栈是不是空了
}

  对于上面的代码,小编其实写的很简略,其实如果写麻烦一点我们需要使用选择语句来判断一下是否为空,这里小编直接使用一句话来跳过选择语句了,这个代码的含义就是如果右边是对的那么直接返回true,如果栈顶不为0直接返回false。当我们判断完以后,可以直接进行尾删操作,很简单,我们只需呀让栈顶减一就好了,此时我们就实现了出栈操作,下面给出代码图:

void STPop(ST* ps)
{assert(ps);assert(!panduan(ps));ps->top--;
}

 2.5.取出栈顶的元素

  这个也是很轻松的,对于取出栈顶的元素,其实就是取顺序表(或者可以直接理解为数组)最后一个有效数据,此时我们还是需要判断栈顶是否还有元素,如果有的话我们直接取出来就好了,可是如果那我们就取出了个寂寞,所以这一步是必须的,之后我们就直接返回栈的最后一个有效数据就好了,下面是代码展示:

STDataType STTop(ST* ps)
{return ps->arr[ps->top - 1];
}

 2.6.判断栈中有效的数据个数

  这个其实说白了,就是返回栈顶的元素就好了,此时我们也不需要在判断栈是否有数据了,如果没有数据,那就直接返回0就好,下面小编就直接展示代码了:

int STSize(ST* ps)
{return ps->top;
}

 2.7.栈元素的打印

  对于栈中元素的打印,其实也是有点要求的,可能有些读者朋友会说,我们直接从头打印不就好了,那当然是不行的,这样就违背了我们栈的结构,我们只能从栈顶进入和出去,所以我们打印数据其实就是从栈顶开始进行打印的,我们每进行完一次打印后就让栈顶元素出栈,直到栈中的元素为空就好了,如下图所示:

   正如上图所示,打印操作也是这么实现,下面进入代码展示:

void print(ST * ps)
{while (ps.top){printf("%d ", STTop(&ps));STPop(&ps);}
}

  以上就是栈结构的实现,其实这么看去,栈是一种比较简单实现的数据结构了(前提学完了顺序表),可能有一些读者朋友想要知道完整的代码,不要着急,下面进入代码展示环节!

3.代码展示

  对于栈的实现,小编也是分成了两个文件来进行书写,一个用来声明函数,一个用来实现函数:

 3.1.Stack.h

#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include<stdbool.h>   //存放布尔类型的头文件//下面来复习一下栈的创建  
//它的底层代码是数组(也可以理解为顺序表)
typedef int STDataType;
typedef struct stack {STDataType* arr;   //数组,类型可能不是一定的所以用typedef替换一下int capacity;  //总空间大小int top;      //栈顶表示
}ST;//初始化栈
void STInit(ST* ps);//销毁栈
void STDestroy(ST* ps);//入栈
void STPush(ST* ps, STDataType x);//出栈
void STPop(ST* ps);//取出栈顶的元素
STDataType STTop(ST* ps);//获取栈中有效的个数
int STSize(ST* ps);

  3.2.Stack.c

#include"Stack.h"
void STInit(ST* ps)
{ps->arr = NULL;ps->capacity = ps->top = 0;  //总空间个数和有用空间个数都初始化为0
}void STDestroy(ST* ps)
{if (ps -> arr)   //先判断是否进行动态内存开辟了{free(ps -> arr);}ps->capacity = ps->top = 0;
}void STPush(ST* ps, STDataType x)   //类似顺序表的尾插
{if (ps->capacity == ps->top){int newcaopacity = ps->capacity == 0 ? 4 : 2 * ps -> capacity;STDataType* arr1 = (STDataType*)realloc(ps->arr, newcaopacity * sizeof(STDataType));assert(arr1);ps->arr = arr1;ps->capacity = newcaopacity;}  //扩容完成ps->arr[ps->top++] = x;
}bool panduan(ST * ps)
{assert(ps);return ps -> top == 0;   //这个是来判断栈是不是空了
}void STPop(ST* ps)
{assert(ps);assert(!panduan(ps));ps->top--;
}STDataType STTop(ST* ps)
{return ps->arr[ps->top - 1];
}int STSize(ST* ps)
{return ps->top;
}

总结 

  小编也是完成了对于栈的讲解,总体来说,栈这个数据结构小编自己认为是不算太难的(关于栈的习题不算),本篇文章算是小编最近写的最短的一篇了,希望读者朋友可以去好好的了解,如果文章有什么错误的地方,请在评论区指出,小编一定及时更正,那么我们下篇文章见啦!

相关文章:

数据结构——栈的讲解(超详细)

前言&#xff1a; 小编已经在前面讲完了链表和顺序表的内容&#xff0c;下面我们继续乘胜追击&#xff0c;开始另一个数据结构&#xff1a;栈的详解&#xff0c;下面跟上小编的脚步&#xff0c;开启今天的学习之路&#xff01; 目录 1.栈的概念和结构 1.1.栈的概念 1.2.栈的结构…...

三防平板助力MES系统,实现工厂移动式生产报工

在当今竞争激烈的制造业环境中&#xff0c;提高生产效率、优化生产流程以及实现精准的生产管理已经成为企业生存和发展的关键。 MES系统作为连接企业计划层和控制层的桥梁&#xff0c;在实现生产过程的信息化、数字化和智能化方面发挥着重要作用。与此同时&#xff0c;三防平板…...

WEB渗透Bypass篇-常规函数绕过

常规函数绕过 <?php echo exec(whoami);?> ------------------------------------------------------ <?php echo shell_exec(whoami);?> ------------------------------------------------------ <?php system(whoami);?> ------------------------…...

C++从入门到起飞之——string类的模拟实现 全方位剖析!

&#x1f308;个人主页&#xff1a;秋风起&#xff0c;再归来~&#x1f525;系列专栏&#xff1a;C从入门到起飞 &#x1f516;克心守己&#xff0c;律己则安 目录 1、多文件之间的关系 2、模拟实现常用的构造函数 2.1 无参构造函数 2.2 有参的构造函数 2.3 析构函…...

数据库国产化大趋势下,还需要学习Oracle吗?

由于众所周知的原因&#xff0c;近两年各行各业都开始了数据库国产化替代的进程&#xff0c;从国外商业数据库替换到国产或者开源数据库&#xff0c;相信很多的数据库从业人员会把部分精力转移到其他数据库产品的学习中&#xff0c;也有一些人在大肆的宣扬Oracle已经过时了&…...

WebLogic

二、WebLogic 2.1 后台弱口令GetShell 漏洞描述 通过弱口令进入后台界面&#xff0c;上传部署war包&#xff0c;getshell 影响范围 全版本(前提后台存在弱口令) 漏洞复现 默认账号密码:weblogic/Oracle123weblogic常用弱口令: Default Passwords | CIRT.net这里注意&am…...

Aspose.Words.dll 插入模板表格,使用的是邮件合并MailMerge功能,数据源是DataTable或list对象,实例

本实例中的实例功能有: 1、 Aspose.Words.dll 插入模板指定域替换为文字或html标签,见1 2、Aspose.Words.dll 插入模板表格,使用的是邮件合并MailMerge功能,数据源是DataTable或List对象(将list转换成DataTable),见1和2 3、word转换Pdf文件,见1 4、将多个word输出文…...

同时打开多个微信

注&#xff1a; 以下方法用到的 D:\微信\WeChat\WeChat.exe是我的电脑微信路径&#xff0c;可右击桌面微信快捷方式 > 属性 > 目标查看 以下方法都需要先关掉已登录的微信后操作 <一> 找到微信路径 新建一个txt文件输入以下内容 start D:\微信\WeChat\WeChat.exe …...

MPU6050的STM32数据读取

目录 1. 概述2. STM32G030对MPU6050的读取3. STM32F1xx对MPU6050的读取 1. 概述 项目中&#xff0c;往往需要根据不同的环境使用不同的芯片处理某些数据&#xff0c;当使用不同的芯片对六轴陀螺仪芯片MPU6050进行数据处理中&#xff0c;硬件的连接、I/O口的设置往往需要根据相…...

【微信小程序开发】——奶茶点餐小程序的制作(二)

&#x1f468;‍&#x1f4bb;个人主页&#xff1a;开发者-曼亿点 &#x1f468;‍&#x1f4bb; hallo 欢迎 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! &#x1f468;‍&#x1f4bb; 本文由 曼亿点 原创 &#x1f468;‍&#x1f4bb; 收录于专栏&#xff1a…...

Java 文件上传七牛云

Java系列文章目录 文章目录 Java系列文章目录一、前言二、学习内容&#xff1a;三、问题描述四、解决方案&#xff1a;4.1 新建空间4.2 查找密钥4.3 进入开发者中心查找JavaSDK文档4.4 查找文件上传方法4.5 运行测试 五、总结&#xff1a;5.1 学习总结&#xff1a; 一、前言 学…...

大语言模型生成无人系统(如机械臂、无人机等)可以执行的指令序列

大语言模型生成无人系统&#xff08;如机械臂、无人机等&#xff09;可以执行的指令序列涉及将自然语言指令转化为具体的、可执行的指令集合。以下是一个详细的流程&#xff0c;展示了如何从自然语言指令生成无人系统的执行指令序列。 1. 输入自然语言指令 用户输入自然语言指…...

尚硅谷谷粒商城项目笔记——十、调试前端项目renren-fast-vue【电脑CPU:AMD】

十、调试前端项目renren-fast-vue 如果遇到其他问题发在评论区&#xff0c;我看到后解决 1 先下载安装git git官网下载地址 2 登录gitee搜索人人开源找到renren-fast-vue复制下载链接。【网课视频中也有详细步骤】 3 下载完成后桌面会出现renren-fast-vue的文件夹 4 开始调…...

Python 的元组和列表的区别是什么?

以下是 Python 中元组&#xff08;tuple&#xff09;和列表&#xff08;list&#xff09;的主要区别&#xff1a; 1. 语法表示&#xff1a;元组使用小括号 () 来定义&#xff0c;例如 (1, 2, 3) &#xff1b;列表使用方括号 [] 来定义&#xff0c;例如 [1, 2, 3] 。 2. 可变性…...

【Impala】学习笔记

Impala学习笔记 【一】Impala介绍【1】简介&#xff08;1&#xff09;简介&#xff08;2&#xff09;优点&#xff08;3&#xff09;缺点 【2】架构&#xff08;1&#xff09;Impalad&#xff08;守护进程&#xff09;&#xff08;2&#xff09;Statestore&#xff08;存储状态…...

视频汇聚平台EasyCVR接入移动执法记录仪,视频无法播放且报错500是什么原因?

GB28181国标视频汇聚平台EasyCVR视频管理系统以其强大的拓展性、灵活的部署方式、高性能的视频能力和智能化的分析能力&#xff0c;为各行各业的视频监控需求提供了优秀的解决方案。视频智能分析平台EasyCVR支持多协议接入&#xff0c;兼容多类型的设备&#xff0c;包括IPC、NV…...

【Linux基础】Linux基本指令(二)

目录 &#x1f680;前言一&#xff0c;mv指令二&#xff0c;more & less指令2.1 more 指令2.1 less指令 三&#xff0c;重定向技术(重要)3.1 echo指令3.2 输出重定向 >3.3 追加重定向 >>3.4 输入重定向 < 四&#xff0c;head & tail指令4.1 head 指令4.2 t…...

全面介绍 Apache Doris 数据灾备恢复机制及使用示例

引言 Apache Doris 作为一款 OLAP 实时数据仓库&#xff0c;在越来越多的中大型企业中逐步占据着主数仓这样的重要位置&#xff0c;主数仓不同于 OLAP 查询引擎的场景定位&#xff0c;对于数据的灾备恢复机制有比较高的要求&#xff0c;本篇就让我们全面的介绍和示范如何利用这…...

Python pandas常见函数

Pandas库 基本概念读取数据数据处理数据输出其他常用功能 pip install pandas基本概念 数据结构 Series: 一维数据结构 import pandas as pd data pd.Series([10, 20, 30, 40], index[a, b, c, d]) print(data)DataFrame: 二维数据结构 data {Name: [Alice, Bob, Charlie],Ag…...

行业落地分享:阿里云搜索RAG应用实践

最近这一两周看到不少互联网公司都已经开始秋招提前批了。 不同以往的是&#xff0c;当前职场环境已不再是那个双向奔赴时代了。求职者在变多&#xff0c;HC 在变少&#xff0c;岗位要求还更高了。 最近&#xff0c;我们又陆续整理了很多大厂的面试题&#xff0c;帮助一些球友…...

MPNet:旋转机械轻量化故障诊断模型详解python代码复现

目录 一、问题背景与挑战 二、MPNet核心架构 2.1 多分支特征融合模块(MBFM) 2.2 残差注意力金字塔模块(RAPM) 2.2.1 空间金字塔注意力(SPA) 2.2.2 金字塔残差块(PRBlock) 2.3 分类器设计 三、关键技术突破 3.1 多尺度特征融合 3.2 轻量化设计策略 3.3 抗噪声…...

React 第五十五节 Router 中 useAsyncError的使用详解

前言 useAsyncError 是 React Router v6.4 引入的一个钩子&#xff0c;用于处理异步操作&#xff08;如数据加载&#xff09;中的错误。下面我将详细解释其用途并提供代码示例。 一、useAsyncError 用途 处理异步错误&#xff1a;捕获在 loader 或 action 中发生的异步错误替…...

地震勘探——干扰波识别、井中地震时距曲线特点

目录 干扰波识别反射波地震勘探的干扰波 井中地震时距曲线特点 干扰波识别 有效波&#xff1a;可以用来解决所提出的地质任务的波&#xff1b;干扰波&#xff1a;所有妨碍辨认、追踪有效波的其他波。 地震勘探中&#xff0c;有效波和干扰波是相对的。例如&#xff0c;在反射波…...

抖音增长新引擎:品融电商,一站式全案代运营领跑者

抖音增长新引擎&#xff1a;品融电商&#xff0c;一站式全案代运营领跑者 在抖音这个日活超7亿的流量汪洋中&#xff0c;品牌如何破浪前行&#xff1f;自建团队成本高、效果难控&#xff1b;碎片化运营又难成合力——这正是许多企业面临的增长困局。品融电商以「抖音全案代运营…...

【android bluetooth 框架分析 04】【bt-framework 层详解 1】【BluetoothProperties介绍】

1. BluetoothProperties介绍 libsysprop/srcs/android/sysprop/BluetoothProperties.sysprop BluetoothProperties.sysprop 是 Android AOSP 中的一种 系统属性定义文件&#xff08;System Property Definition File&#xff09;&#xff0c;用于声明和管理 Bluetooth 模块相…...

select、poll、epoll 与 Reactor 模式

在高并发网络编程领域&#xff0c;高效处理大量连接和 I/O 事件是系统性能的关键。select、poll、epoll 作为 I/O 多路复用技术的代表&#xff0c;以及基于它们实现的 Reactor 模式&#xff0c;为开发者提供了强大的工具。本文将深入探讨这些技术的底层原理、优缺点。​ 一、I…...

JavaScript基础-API 和 Web API

在学习JavaScript的过程中&#xff0c;理解API&#xff08;应用程序接口&#xff09;和Web API的概念及其应用是非常重要的。这些工具极大地扩展了JavaScript的功能&#xff0c;使得开发者能够创建出功能丰富、交互性强的Web应用程序。本文将深入探讨JavaScript中的API与Web AP…...

go 里面的指针

指针 在 Go 中&#xff0c;指针&#xff08;pointer&#xff09;是一个变量的内存地址&#xff0c;就像 C 语言那样&#xff1a; a : 10 p : &a // p 是一个指向 a 的指针 fmt.Println(*p) // 输出 10&#xff0c;通过指针解引用• &a 表示获取变量 a 的地址 p 表示…...

鸿蒙(HarmonyOS5)实现跳一跳小游戏

下面我将介绍如何使用鸿蒙的ArkUI框架&#xff0c;实现一个简单的跳一跳小游戏。 1. 项目结构 src/main/ets/ ├── MainAbility │ ├── pages │ │ ├── Index.ets // 主页面 │ │ └── GamePage.ets // 游戏页面 │ └── model │ …...

VisualXML全新升级 | 新增数据库编辑功能

VisualXML是一个功能强大的网络总线设计工具&#xff0c;专注于简化汽车电子系统中复杂的网络数据设计操作。它支持多种主流总线网络格式的数据编辑&#xff08;如DBC、LDF、ARXML、HEX等&#xff09;&#xff0c;并能够基于Excel表格的方式生成和转换多种数据库文件。由此&…...