【数据结构】栈

article/2025/8/16 9:07:50

栈的概念及结构

在学习栈前,我们先看一下栈的正式解释:

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

栈底就是我们栈的开头位置,我们放数据进去,就是以一种往上叠的感觉, 现在栈底已经有a1、a2两个数据,我们现在放a3进去,它就应该在a2的上面。

现在a3已经进栈,我们现在要拿出数据,就从栈顶开始拿,也就是说a3回先被我们拿出来

 

然后出栈的顺序就是:a3、a2、a1 

这就是栈的后进先出,但是我们没必要全部放进去了再一起拿出来,我们也可以放一个数据拿一个数据出来,比方说;

现在有a3、a4要进栈,我们让a3先进栈:

但是我们又要用到a3这个数据,我们就直接把a3拿出去,然后把a4压进去:

那我们出数据的时候,就变成了:

a3、a4、a2、a1

 ------------

我们来看两道题加深理解:

1.一个栈的初始状态为空。现将元素12345ABCDE依次入栈,然后再依次出栈,则元素出 栈的顺序是( )。
A 12345ABCDE
B EDCBA54321
C ABCDE12345
D 54321EDCBA
------------
想到答案了吗?
B,题目里面说依次进栈,那它出栈的时候也就是以此出栈,我们把放进去的数据反一遍就好。
下一题:
2. 若进栈序列为 1,2,3,4 ,进栈过程中可以出栈,则下列不可能的一个出栈序列是()
A 1,4,3,2
B 2,3,4,1
C 3,1,4,2
D 3,4,2,1
-------------
我们一个一个看,依次分析;
A,如果是1、4、3、2,那它的进栈顺序就是:
先放1,再把1拿出来,然后依次放进2、3、4,最后出栈的时候反着出
--
B、2、3、4、1
先压一个1,然后2、3、4直接拿出来,最后拿1
--
C,我们看这里最先出来的是3,也就是说底下压着的是 2 1,如果是出栈的话那2后进栈应该显出,但这里3后面是1,很明显错误
--
D就不分析了,有兴趣可以自己分析一下。
-----------

栈的实现

我们之前学过数组、链表,这两种都可以用在栈上,栈只需要在栈顶进行操作,我们来看看两种分别怎么实现:

数组:可以把数组首元素地址看作栈底,而数组之后的位置看作栈顶,这样数组的栈压栈即是在尾补插入数据,也就是top的位置

链表:

我们如果把数组第一个节点认为是栈底,那压栈就是在它后面尾插,尾插不难,但是我们要如何出栈呢?

如果是双向的链表就可以解决这个问题,但未免有些麻烦

如果是单链表,我们首插就简单一点。

这里我们就来实现一下数组的栈:

// 初始化栈
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);

在实现之前,我们要做几件事:

头文件,就不多说了

类型最好定义一下,用typedef,这样我们之后修改存储类型直接在这里修改就好

定义一个结构体

声明我们要实现的函数

#include<stdio.h>
#include<assert.h>
#include<stdlib.h>typedef int STDataType;typedef struct Stack
{STDataType* arr;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* ps)
{assert(ps);ps->arr = NULL;ps->capacity = 0;ps->top = 0;
}

很简单,我们让指针指向NULL,然后数据为0即可,这里要注意的是:

top位置,如果top的位置是0开始的话,也就是说以下标位置为栈顶

当放 1 2 3 4 5数据的时候,top的下标就是5,也就是下一个数据的位置

当top为-1开始的时候,放1 2 3 4 5的时候,top的下标为4,也就是当前数据的位置

 入栈

入栈也就是我们数组top的位置放上要存储的数据,看代码实现:

void StackPush(Stack* ps, STDataType data)
{assert(ps);if (ps->top == ps->capacity){int newcapacity = ps->capacity == 0 ? 4 : (ps->capacity) * 2;ps->arr = (Stack*)realloc(ps->arr, sizeof(Stack)* newcapacity);if (ps->arr == NULL){printf("realloc fail\n");exit(-1);}ps->capacity = newcapacity;}ps->arr[ps->top++] = data;
}

一进函数,先判断ps是否空指针,其次判断是否还有空间,如果没有空间我们就开辟一个新空间,开辟失败就退出并打印错误信息,如果开辟成功并有空间,我们就放数据进去。

出栈

就跟顺序表一样,如果出栈,我们就直接将top--即可,不需要销毁什么空间

void StackPop(Stack* ps)
{assert(ps);assert(ps->top > 0);ps->top--;
}

获取栈顶元素

STDataType StackTop(Stack* ps)
{assert(ps);return ps->arr[ps->top-1];
}

我们直接返回即可,不过要注意这里top,top是0和top是-1的返回值课不一样,别搞错了。

获取栈的有效数据个数

int StackSize(Stack* ps)
{assert(ps);return ps->top;
}

直接返回top即可。

看看栈是否为空

int StackEmpty(Stack* ps)
{assert(ps);return ps->top == 0;
}

直接在返回里面判断即可

销毁栈

void StackDestroy(Stack* ps)
{assert(ps);free(ps->arr);ps->arr = NULL;ps->top = 0;ps->capacity = 0;
}

跟初始化一样,主要是注销里面的指针,然后将其他置零。

-----------

栈的练习

我们知道并了解了栈,做一道题看看:

20. 有效的括号 - 力扣(LeetCode) (leetcode-cn.com) 

这里就可以用到我们刚刚学会的栈。

先说思路:

我们将得到的字符进行判断,如果是左半边,就压栈,如果就右半边就取出来然后配对,配对错就返回false。

看代码实现:

我们先把上面的函数都拿过来用,先复制过来,下面的是主程序

bool isValid(char * s)
{Stack arr;StackInit(&arr);while(*s){//压栈if(*s == '('||*s == '['||*s == '{'){StackPush(&arr,*s);++s;}//*s是右半边,我们开始配对else{//如果取不出来直接就返回falseif(StackEmpty(&arr)){return false;}//取出来开始判断char data = StackTop(&arr);//取出来顶上一个我们就删一个,方便下一次配对StackPop(&arr);if((*s =='}'  && data != '{')|| (*s == ')' && data != '(')|| (*s == ']' && data != '[')){StackDestroy(&arr);return false;}//配对成功继续走else{++s;}}}//看栈里面还有没有括号int ret = StackEmpty(&arr);StackDestroy(&arr);return ret;
}

感谢您的观看,我们下次再见


http://chatgpt.dhexx.cn/article/hSRY5ZWV.shtml

相关文章

什么是栈?

本文将介绍一个重要的数据结构—栈&#xff0c;和之前讲到的链表、数组一样也是一种数据呈线性排列的数据结构&#xff0c;不过在这种结构中&#xff0c;我们只能访问最新添加的数据。栈就像是一摞书&#xff0c;拿到新书时我们会把它放在书堆的最上面&#xff0c;取书时也只能…

【图解数据结构】栈全面总结

目录 一、前言 二、基本概念 三、栈的表示和实现 1.顺序栈 2.链栈 四、栈的常见算法实现 1.初始化 2.判空 3.判满 4.顺序栈取栈顶元素 5.顺序栈入栈 6.顺序栈出栈 五、双栈 1.双端顺序栈进栈操作 2.双端顺序栈出栈操作 六、栈的应用举例 1.回文游戏 2.多进制…

数据结构——栈

栈和队列 栈和队列介绍特点栈、队列与一般线性表的区别栈——stack栈的基本运算栈的存储结构顺序栈链栈 栈的应用 栈和队列 介绍 栈和队列是在软件设计中常用的两种数据结构&#xff0c;它们的逻辑结构和线性表相同 特点 栈和队列在运算上受到了限制&#xff1a;栈是按照“…

遥感影像百分比线性拉伸

AI Earth地球科学云平台开发者模式提供了丰富的遥感数据和函数计算能力&#xff0c;下面介绍结合AIE Notebook&#xff0c;实现遥感数据的百分比线性灰度拉伸。 本期开发者实践案例——遥感影像百分比线性拉伸 灰度拉伸 (GrayScale Stretch) 是遥感影像处理过程中的重要步骤&…

遥感影像分类方法

最初的遥感影像分类是通过目视解译(濮静娟, 1984)来完成的&#xff0c;对研究人员的主观意识有较强的依赖性&#xff0c;而且效率较低&#xff0c;适用于数据量较小的情况&#xff0c;通常作为其他方法对比的对象。目前的遥感图像分类主要以计算机分类为主&#xff0c;因此按照…

遥感影像配准

文章目录 前言步骤1.ENVI&#xff1a;打开Image Registration Workflow2.Image Registration Workflow(1)选择GF2为Base Image File&#xff0c;某季节Sentinel2为Warp&#xff0c;然后Next(2)修改该参数为100(3)人为选择5个左右控制点&#xff0c;然后Next(4)删除离谱点(5)在E…

遥感图像分类技术

什么是遥感图像分类技术&#xff1f; 图像分类是将土地覆盖类别分配给像素的过程。例如&#xff0c;这9个全球土地覆盖数据集将图像分为森林、城市、农业和其他类别。 https://gisgeography.com/free-global-land-cover-land-use-data/ 一般来说&#xff0c;这是遥感中的三种主…

遥感图像分类

遥感图像分类 一、背景简介 遥感图像分类就是利用计算机通过对遥感图像中各类地物的光谱信息和空间信息进行分析&#xff0c;选择特征&#xff0c;将图像中各个像元按照某种规则或算法划分不同的类别&#xff0c;然后获得遥感图像中与实际地物的对应信息&#xff0c;从而实现…

WorldView卫星遥感影像数据/米级分辨率遥感影像

数据样例&#xff1a;百度云下载链接&#xff1a;https://pan.baidu.com/s/17ofPwpDM3OCHnE-LuhvUp 提取码&#xff1a;i0m4 目前世界上最常用的高分辨率卫星影像莫过于WORLDVIEW系列了&#xff0c;在卫星遥感圈内可谓大名鼎鼎&#xff0c;不仅具有超高的分辨率还具有其他高分…

遥感数据下载平台汇总

1中国资源卫星应用中心http://www.cresda.com.cn中巴卫星、HJ星、ZY系列 、GF系列2中科院对地观测与数字地球科学中心http://ids.ceode.ac.cn/Index.aspxERS卫星&#xff0c;Enviset_1卫星&#xff0c;法国的spot4卫星&#xff0c;中巴资源卫星&#xff0c;landset-5-73地球系统…

遥感多光谱数据下载与预处理(一、数据选择 下载)

首先说明本人并非专业大牛&#xff0c;不是教程贴只是记录一下学习过程和大家交流&#xff0c;过程有不严谨不合规范不对的地方欢迎各位大神指正。 本人目前做过接触过最多的是多光谱遥感数据&#xff0c;也是与无人机、雷达、高光谱等相比最简单的一种&#xff0c;这是我自己总…

地理空间数据云下载遥感影像

目录 1、先上网址&#xff1a;www.gscloud.cn 2、介绍界面&#xff1a; 2.1 “数据资源” 2.2 “高级检索” 1、先上网址&#xff1a;www.gscloud.cn 2、介绍界面&#xff1a; 地理空间数据云&#xff0c;作为国内免费下载遥感卫星影像的一个大平台&#xff0c;随着年代发…

遥感图像入门

遥感图像入门 一、 遥感基本概念地物光谱特性3S 技术瑞利散射大气窗口 二、 遥感系统的组成三、 遥感分类四、 遥感数字图像处理图像与数字图像数字图像获取时的基本参数数字图像类型 一、 遥感基本概念 遥感(Remote Sensing)——遥远的感知&#xff0c;在未接触物体的情况下获…

遥感影像的几何校正

一、引言&#xff08;INTRODUCTION&#xff09; 图像校正主要是指辐射校正和几何校正。辐射校正包括传感器的辐射校正、大气校正、照度校正遗迹条纹和斑点的判定和消除。几何校正就是校正成像过程中造成的各种几何畸变&#xff0c;包括几何粗校正和几何精校正。几何粗校正是针对…

遥感影像数据下载网站整理

遥感影像数据下载网站整理 1 遥感影像数据1.1 综合遥感数据1.1.1 USGS EarthExplore1.1.2 LAADS DAAC1.1.3 Copernicus Open Access Hub1.1.4 GloVis1.1.5 地理空间数据云 1.2 雷达遥感数据1.2.1 ASF DAAC 1.3 夜光遥感数据1.3.1 NOAA EOG1.3.2 珞珈一号 1.4 海洋卫星数据1.4.1…

高分GF与环境HJ系列国产卫星遥感影像数据图像免费批量下载方法

本文介绍高分&#xff08;GF&#xff09;与环境&#xff08;HJ&#xff09;等主要国产卫星遥感数据的免费下载&#xff08;包括批量下载&#xff09;方法。 首先&#xff0c;进入中国资源卫星应用中心官网&#xff1a;http://www.cresda.com/CN/。选择“查询系统”。 随后登录系…

【随笔】那些免费友好的遥感影像数据下载网站

1 .影像数据 1.1 地理空间数据云 推荐指数&#xff1a;❤❤❤❤❤交互界面&#xff1a;友好传输速度&#xff1a;0.4m/s数据集&#xff1a;开源数据集较为丰富&#xff0c;Landsat系列数据及DEM数据较丰富&#xff0c;但也有一些数据无法下载。 网址&#xff1a;地理空间数据…

完全免费的在线遥感影像下载器-转载

链接&#xff1a;link 转载学习使用&#xff0c;可免费下载&#xff01;

常用遥感数据下载平台

国内常用卫星数据下载网站 1&#xff0c;AI Earth 地球科学云平台 网址&#xff1a;AI Earth 数据&#xff1a;Landsat、Sentinel、MODIS、地形数据。 2&#xff0c;地理空间数据云 网址&#xff1a;http://www.gscloud.cn/ 数据&#xff1a;多种卫星数据 3&#xff0c;中…

Landsat遥感影像下载

摘要&#xff1a;本篇文章主要介绍下载遥感卫星影像数据常用的几种的获取方法。适合刚接触遥感这个领域不久却需要下载和使用遥感影像的人群。 本文着重介绍陆地资源卫星Landsat系列卫星的遥感影像查询和下载。 目录 1、陆地资源卫星Landsat系列卫星基本介绍 1.1 Landsat-5介绍…