【数据结构】栈的基本知识详解

栈的基本概念与基本操作

  • 导言
  • 一、栈的基本概念
    • 1.1 栈的定义
    • 1.2 栈的重要术语
    • 1.3 栈的数学性质
  • 二、栈的基本操作
  • 结语

封面

导言

大家好,很高兴又和大家见面了!!!
今天开始,咱们将正式进入【数据结构】第三章的内容介绍。在第三章的内容中,我们需要掌握栈和队列的操作及其特征,以及数组与特殊矩阵的压缩存储等知识点。为了更好的掌握这些知识点,我们将对这些知识点进行一一介绍。
今天要介绍的是咱们的第一位新朋友——栈。我们在今天的篇章中需要搞清楚以下几个问题:

  1. 什么是栈?
  2. 栈有哪些重要术语?
  3. 栈的操作特性是什么?
  4. 栈有哪些基本操作?

下面我们就开始今天的内容吧!

一、栈的基本概念

1.1 栈的定义

栈(Stack)是只允许在一端进行插入或者删除操作的线性表

在前面的学习中,我们知道了线性表就是具有相同数据类型的n(n>=0)个数据元素的有限序列。从栈的定义中我们可以看到,栈也是一个线性表,也就是说存放在栈中的数据元素是有限的,且数据元素的数据类型相同。我们需要注意的是栈的定义中强调了一个点——只允许在一端进行插入或者删除操作

为什么要强调只允许在一端进行插入或者删除呢?下面我们来回忆一下线性表。

  • 在顺序表中,我们在进行插入或删除操作时可以通过元素的位序进行随机存取,从而完成插入或者删除的操作;
  • 在链表中,我们同样可以通过元素对应的位序来完成插入或者删除操作;
  • 也就是说不管是顺序表还是链表,在进行插入或者删除操作时我们只需要得到数据元素对应的位序就能实现,因此,这两种线性表都是可以在表中的任意位置进行插入或者删除操作的。

在结合这里的只允许在一端,我们就能得到结论,对于栈这种线性表它在进行插入或者删除操作时是有局限性的

1.2 栈的重要术语

栈顶(Top)——线性表允许进行插入删除的一端
栈底(Bottom)——线性表不允许进行插入删除的一端
空栈——不含任何元素的空表
接下来我们根据图像来更进一步理解这些术语:
栈的重要术语

  • 我们可以把栈想象成一个水杯,我们在倒水时只能从杯口往杯里加水,喝水时只能从杯口将杯中的水倒出来;杯子的杯底是固定的,我们不能通过从杯底进行加水和倒水;当杯子中没有任何东西时,这个杯子为空杯。
  • 因此,水杯的杯口就是栈的栈顶水杯的杯底就是栈的栈底;水杯中没有任何东西时,对应的就是栈中没有任何数据元素,此时的空杯对应的栈为空栈

下面我们假设某个栈S中有 a 1 , a 2 , a 3 , a 4 , a 5 a_1,a_2,a_3,a_4,a_5 a1,a2,a3,a4,a5这五个元素,如下图所示:
栈的重要术语2
由于只能从栈顶进行插入和删除操作,因此我们在将这个五个元素依次放入栈中时,它们放入的顺序应该是:
a 1 − > a 2 − > a 3 − > a 4 − > a 5 a_1->a_2->a_3->a_4->a_5 a1>a2>a3>a4>a5,而它们的存放从上到下依次是: a 5 − > a 4 − > a 3 − > a 2 − > a 1 a_5->a_4->a_3->a_2->a_1 a5>a4>a3>a2>a1。在这个栈中 a 1 a_1 a1是离栈底最近的元素,因此它也被称为栈底元素,而 a 5 a_5 a5是离栈顶最近的元素,因此它也被称为栈顶元素。如果我们需要删除这些元素时,我们也应该按照它们的存放顺序进行删除也就是: a 5 − > a 4 − > a 3 − > a 2 − > a 1 a_5->a_4->a_3->a_2->a_1 a5>a4>a3>a2>a1

由此可见,对于栈这种线性表而言他的操作特性可以概括为——后进先出(Last In First Out,LIFO)

Tips:

  1. 我们在介绍【函数栈帧的创建与销毁】时,就有提到过函数的栈帧空间。在创建一个新的函数栈帧时,就有进行压栈和出栈等操作,进行压栈和出栈时就是从栈顶实现的。
  2. 我们在存放数据时,会根据数据存放的空间的起始地址来标记该元素的所在位置,如果将对应的空间想象成栈的话,那指向该空间的指针,指向的就是这个空间的栈顶。

1.3 栈的数学性质

由于栈的操作性质,那我们在对其进行入栈和出栈操作时就可能会出现以下的几种情况:

  • 按元素顺序进行入栈,全部入栈后再依次出栈;
  • 按元素顺序进行入栈,入栈的过程中穿插出栈;

对于第一种情况我们可以很好的理解它的元素出栈顺序——与入栈顺序相反;
但是在第二种情况下,如果有n个元素进行入栈与出栈操作,出栈元素不同的排列个数为 1 / ( n + 1 ) C 2 n n 1/(n+1)C^{n}_{2n} 1/(n+1)C2nn。这个公式被称为卡特兰数(Catalan),这个公式也是栈的数学性质。

二、栈的基本操作

在介绍线性表时,我们有介绍过线性表的基本操作概括一下就是——创建、销毁、增删改查。当然我们在修改元素前也是需要先查找到对应元素才行。对于栈这种线性表而言,我们可以对其进行的基本操作同样可以总结为以下几点:

1.创建销毁

  • InitStack(&S):初始化一个空栈S;
  • DestroyStack(&S):销毁栈,并释放栈S占用的存储空间;

对于栈的创建与销毁操作,它和线性表一样都是对整个对象进行修改,所以这里需要使用引用符号,通过C语言实现的话就是需要借助指针,如下所示:

//初始化
bool InitStack(StackType* S);
//销毁
bool DestroyStack(StackType* S);
//StackType——栈的数据类型
//StackType*——指针数据类型
void test() {
	StackType S;//定义数据类型为StackType类型的栈S
	InitStack(&S);//对栈进行初始化
	DestroyStack(&S);//销毁栈
}

对于栈的数据类型今天我们就不再展开,在下一篇栈的基本操作的C语言实现中,我们会再详细介绍;


  1. 增加删除
  • Push(&S,x):进栈,若栈S未满,则将x加入使之称为新的栈顶;
  • Pop(&S,&x):出栈,若栈S非空,则弹出栈顶元素,并用x返回;

对于栈的增加与删除操作,可以看到都是对栈顶元素进行的,但是有一点不同的是,我们在进行增加即进栈操作时,并未对数据x进行引用操作,但是在出栈时需要对x进行引用。
这是因为我们在进栈时是对明确的元素进行进栈操作,这时我们需要修改的只有栈空间,但是在出栈操作时,我可能并不知道此时的栈顶元素存储的是什么内容,我只需要删除栈顶元素,所以我需要将删除的元素给带回到主函数中来告诉大家我们现在删除的是什么元素,因此需要对x进行引用,通过C语言来实现的话则是:

//进栈
bool Push(StackType* S, ElemType x);
//出栈
bool Pop(StackType* S, ElemType* x);
//StackType——栈的数据类型
//StackType*——指针数据类型
//ElemType——数据元素的数据类型
//ElemType*——指针数据类型
void test() {
	StackType S;//定义数据类型为StackType类型的栈S
	ElemType x = 0;
	Push(&S, x);//进栈
	Pop(&S, &x);//出栈
}

与线性表一样,在具体的实现中我们对于进栈和出栈的函数返回类型可以根据要求进行变化,不一定是布尔类型;


  1. 查找
  • GetTop(S,&x):读栈顶元素,若栈S非空,则用x返回栈顶元素;

在对栈进行查找操作时,我们查找的是栈顶元素,并且需要将查找到的栈顶元素进行带回,因此这里需要对x进行引用,通过C语言实现的话则是:

//查找
bool GetTop(StackType S, ElemType* x);
//StackType——栈的数据类型
//ElemType——数据元素的数据类型
//ElemType*——指针数据类型
void test() {
	StackType S;//定义数据类型为StackType类型的栈S
	ElemType x = 0;
	GetTop(S, &x);//查找栈顶元素
}

具体的返回类型我们也可以根据需求进行修改,因为这里是通过传址的方式进行传参,所以只要在函数中对x存储的数值有进行修改,那回到主函数后实参也会跟着被修改;


4.其它

  • StackEmpty(S):判断一个栈是否为空,若栈S为空则返回true,否则返回false

对于判空操作而言,就是简单的判断一下栈中有没有元素,因此并未对栈的内容有任何更改,所以这里我们不需要使用引用操作,用C语言表示则是:

//判空
bool StackEmpty(StackType S);
//StackType——栈的数据类型
void test() {
	StackType S;//定义数据类型为StackType类型的栈S
	StackEmpty(S);//判空
}

在不需要对实参进行修改的函数调用中,我们只需要通过传值传参即可。


以上就是栈的基本操作的C语言格式,对于具体的参数类型、函数的返回类型以及函数的具体实现,我们会在后面的篇章中详细介绍,大家记得关注哦!

结语

今天的内容比较简单在今天的内容中,我们主要介绍了在导言部分提出的几个问题:

  1. 什么是栈?
    栈(Stack)是只允许在一端进行插入或者删除操作的线性表

  1. 栈有哪些重要术语?
    栈顶、栈底、空栈、栈顶元素、栈底元素

  1. 栈的操作特性是什么?
    后进先出——Last In First Out,LIFO

  1. 栈有哪些基本操作?
    创建销毁、增加删除、查找、判空

咱们还简单介绍了一下栈的数学性质——卡特兰数(Catalan),在后面的篇章中我会进行详细的介绍,大家记得关注哦!

今天的内容到这里就结束了,希望这篇内容能帮助大家更好的理解栈的基础知识点,在接下来的内容中咱们将继续介绍如何通过C语言实现栈的基本操作。最后感谢大家翻阅,咱们下一篇再见!!!

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

第二证券:主力为什么要砸盘?

砸盘就是在股票的某个阶段有许多卖出单,这些许多的卖出单不断的成交使股票价格出现快速下跌。一般是受到主力资金洗盘或者出货所影响形成的。 1、洗盘 个股通过长时间上涨之后,盘中的散户较多,主力为了洗掉盘中的散户,在低位吸筹…

nodejs+vue+ElementUi音乐分享社交网站77l8j

本文介绍的系统主要分为两个部分:一是前台界面:用户通过注册登录可以实现音乐播放、新闻浏览、留言评论等功能;另一个是后台界面:音乐网站管理员对用户信息进行管理,上传更新音乐资源,发布最新音乐资讯等功…

SpringBoot 中 @Transactional 注解的使用

一、基本介绍 事务管理是应用系统开发中必不可少的一部分。Spring 为事务管理提供了丰富的功能支持。Spring 事务管理分为编程式和声明式的两种方式。本篇只说明声明式注解。 1、在 spring 项目中, Transactional 注解默认会回滚运行时异常及其子类,其它范…

目标检测再升级!YOLOv8模型训练和部署

YOLOv8 是 Ultralytics 开发的 YOLO(You Only Look Once)物体检测和图像分割模型的最新版本。YOLOv8是一种尖端的、最先进的SOTA模型,它建立在先前YOLO成功基础上,并引入了新功能和改进,以进一步提升性能和灵活性。它可…

揭秘阿里自研搜索引擎 Havenask 在线检索服务

作者:谷深 Havenask 是阿里巴巴智能引擎事业部自研的开源高性能搜索引擎,深度支持了包括淘宝、天猫、菜鸟、高德、饿了么在内几乎整个阿里的搜索业务。本文针对性介绍了 Havenask 的在线服务,它具备高可用、高时效、低成本的优势,…

【软考中级-软件设计师】day4:数据结构-线性表、单链表、栈和队列、串

大纲 线性结构 顺序存储和链式存储区别 单链表的插入和删除 真题 栈和队列 真题 串

微创新与稳定性的权衡

之前做过一个项目,业务最高峰CPU使用率也才50%,是一个IO密集型的应用。里面涉及一些业务编排,所以为了提高CPU使用率,我有两个方案:一个是简单的梳理将任务可并行的采用并行流、额外线程池等方式做并行;另外…

2019年认证杯SPSSPRO杯数学建模A题(第一阶段)好风凭借力,送我上青云全过程文档及程序

2019年认证杯SPSSPRO杯数学建模 纸飞机在飞行状态下的运动模型 A题 好风凭借力,送我上青云 原题再现: 纸飞机有许多种折法。世界上有若干具有一定影响力的纸飞机比赛,通常的参赛规定是使用一张特定规格的纸,例如 A4 大小的纸张…

计操进程同步(信号量pv灵魂三问法狂练版)

文章目录 解题秘诀-灵魂三问法一 同步问题1.1 围棋问题1.2 数据采集问题1.3 三进程文件打印问题1.4 司机售票员问题 二 同步互斥问题2.1 果盘问题 三 同步资源管控问题3.1 兔子问题3.2 数据写入和读取问题3.3 图书馆问题3.4 超市问题3.4.1 解法一3.4.2 解法二 解题秘诀-灵魂三问…

(Matlab)基于CNN-Bi_LSTM的多维时序回归预测(卷积神经网络-双向长短期记忆网络)

目录 一、程序及算法内容介绍: 基本内容: 亮点与优势: 二、实际运行效果: 三、部分代码展示: 四、完整代码数据下载: 一、程序及算法内容介绍: 基本内容: 本代码基于Matlab平…

【idea】idea 开发快捷键

在Java开发中,有一些常用的快捷键和工具,可以提高开发效率。以下是一些常见的Java开发常用到的功能和快捷键: IDE快捷键: 代码大小写切换: ctrlshiftu 格式化代码:Ctrl Alt L,会让代码更整…

程序员必知!备忘录模式的实战应用与案例分析

备忘录模式允许在不破坏封装性下捕获并在外部保存对象状态,支持状态恢复,常用于撤销、历史记录等功能。例如在线文档编辑器的撤销操作,编辑器作为原发起人记录状态并提供保存与恢复方法,历史记录或撤销为管理者,保存备…

Nodejs+express后端学习笔记(1)

1 Node.js安装 1、下载安装包:进入官网(https://nodejs.org/en),下载左侧的稳定版。 2、选择安装位置,不用勾选自动安装必要工具。 其他都默认Next。 配置环境,具体参考本文章: https://blo…

Linux系统——nmap安装与使用

一、安装nmap 1、安装nmap 【操作命令】 yum install nmap 2、查看nmap版本 【操作命令】 nmap -version 【操作实例】 3、卸载nmap 【操作命令】 yum remove nmap 二、简单使用方法 1、扫描指定ip 【操作命令】 nmap 192.168.1.1 2、扫描指定端口 【操作命令】 …

数据库管理-第130期 JSON二元性(20240109)

数据库管理130期 2024-01-09 第130期 JSON二元性(20240109)1 简介2 关系型表和JSON存储的优劣3 Oracle JSON关系型二元性视图总结 第130期 JSON二元性(20240109) 上周,又双叒飞了一趟上海,也是2024年第一飞…

Java内存模型(JMM)是基于多线程的吗

Java内存模型(JMM)是基于多线程的吗 这个问题按我的思路转换了下,其实就是在问:为什么需要Java内存模型 总结起来可以由几个角度来看待「可见性」、「有序性」和「原子性」 面试官:今天想跟你聊聊Java内存模型&#…

即时设计:设计稿与PPT完美结合,让您的创意作品更具影响力

PPT助手 更多内容 在设计领域,将设计稿与PPT结合起来,可以让您的作品更具吸引力和影响力。为了满足这一需求,我们向您推荐一款强大的设计工具,它可以将设计稿导出为PPT文件,支持线上预览和编辑,让您的创意…

ADS仿真 之 容差/良率分析

之所以要进行容差分析, 是因为任何电子元器件均存在一定的误差, 如电感、电容的精度等。 例如一个标称为2.0nH0.1nH的电感,代表的意思产品有99.74%的概率落在2.0nH0.1nH范围内, 即满足6σ ,σ是标准偏差或者说方差&…

OpenHarmony沙箱文件

一.前言 1.前景提要 DevEcoStudio版本:DevEco Studio 3.1 Release SDK版本:3.2.2.5 API版本:9 2.概念 在openharmony文件管理模块中,按文件所有者分类分为应用文件和用户文件和系统文件。 1)沙箱文件。也叫做应…

C++类和动态内存分配

目录 1. C类的基本概念与使用 2. 动态内存分配与指针 3. 类与动态内存分配的结合应用 4. 注意事项与最佳实践 5.一个简单的示例代码 在C编程中,类是一种重要的概念,它允许我们将数据和操作封装在一起,以实现更加模块化和可维护的代码。而…