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

news2024/11/24 12:25:44

栈的基本概念与基本操作

  • 导言
  • 一、栈的基本概念
    • 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.coloradmin.cn/o/1366827.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

STM32MP157D-DK1 STM32CubeID使用与M核开发

STM32MP157具有A7内核核M4内核,前面介绍的一些文章,都是在A7内核上进行的,本篇来介绍M4内核的开发,以及开发时要用到的STM32 CubeIDE软件的使用。 1 STM32 CubeIDE创建LED工程 STM32CubeIDE是一体式多操作系统开发工具&#xff…

Hyperledger Fabric Java App Demo

编写一个应用程序来连接到 fabrc 网络中,通过调用智能合约来访问账本. fabric gateway fabric gateway 有两个项目,一个是 fabric-gateway-java , 一个是 fabric-gateway。 fabric-gateway-java 是比较早的项目,使用起来较为麻烦需要提供一…

数据结构—排序—选择排序

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言 一、选择排序 1、基本思想 2、直接选择排序 3、选择排序的代码实现 二、堆排序 2.1算法讲解 2.2堆排序的代码实现 总结 前言 世上有两种耀眼的光芒&#xff0…

Spring AOP概念

什么是 AOP ? AOP 为 Aspect Oriented Programming 的缩写,意为:面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术。AOP 是 OOP 的延续,是软件开发中的一个热点,也是 Spring …

thinkphp学习02-目录结构、控制器、路由、配置文件

目录结构 www WEB部署目录(或者子目录) ├─app 应用目录 │ ├─controller 控制器目录 │ ├─model 模型目录 │ ├─ ... 更多类库目录 │ │ │ ├─common.php 公共函数文件 │ └─event.ph…

批量生成datax同步JSON(postgresql到doris)

1.问题描述 使用datax同步psql数据到doris,表的数量过多,写datax的配置文件很麻烦。鉴于此,编写了一个datax的配置文件生成脚本,可以灵活的实现一键生成配置文件,提高生产效率。 废话不多说,脚本如下 2.问…

Vue入门二(列表渲染|数据的双向绑定|事件处理)

文章目录 一、列表渲染小案例补充es6对象写法v-for可以循环的类型补充js可循环类型key值的解释 二、数据的双向绑定三、事件处理基本使用过滤案例事件修饰符 一、列表渲染 小案例 <!DOCTYPE html><html lang"en"><head><meta charset"UTF…

跨平台的传输协议@WebDav协议@windows系统配置WedDav服务器@局域网内的WebDav传输系统

文章目录 WebDav协议基本信息启用必要的windows功能启动站点管理器IIS站点根目录访问权限设置站点的功能设置端口通行防火墙IMME文件类型(文件后缀)其他设备登录和访问本机的WebDav服务站点 小结优点缺点 refs WebDav 协议基本信息 来自wikipedia:基于Web的分布式编写和版本控…

数字IC芯片设计实现 | 时序Timing Signoff check_timing检查解析

今天分享在数字IC芯片设计实现做timing signoff阶段必须要看的report。check_timing的报告必须是clean的&#xff0c;否则芯片回来大概率是废片&#xff01;&#xff01;&#xff01;实际上一堆公司的芯片败在不看这个report了。 我们知道primetime(简称PT)做时序检查是基于我…

RT-Thread: 基于STM32CubeMX配置驱STM32驱动的USB虚拟串口调试

关键词&#xff1a;USB 虚拟串口 USB虚拟串口&#xff0c;RT-Thread Studio&#xff0c;STM32 说明&#xff1a; 1&#xff1a;文档记录 STM32F103系列基于 RT-Thread 系统的 USB虚拟串口的开启及数据收发应用流程介绍。 2&#xff1a;本文以STM32F103C8T6型号做测试&#x…

Java-伪共享

在说这个计算机术语之前&#xff0c;我先在这里问候所有问“什么是JVM伪共享”的垃圾JAVA程序员以及一瓶不满半瓶晃荡的面试官全家 我从来没想过国内已经很卷的JAVA圈&#xff0c;已经卷到语无伦次的地步了&#xff0c;“伪共享”是java程序员应该知道的吗&#xff1f;能问出这…

【Linux Shell】5. 运算符

文章目录 【 1. expr 命令 】【 2. 算术运算符 】【 3. 关系运算符 】【 4. 布尔运算符 】【 5. 逻辑运算符 】【 6. 字符串运算符 】【 7. 文件测试运算符 】 【 1. expr 命令 】 原生 bash 不支持简单的数学运算&#xff0c;但是可以通过其他命令来实现&#xff0c;例如 awk …

基于SSM图书管理系统【源码】【最详细运行文档】

SSM图书管理系统【源码】【最详细运行文档】 系统简介系统涉及系统运行系统演示源码获取 系统简介 以往的图书馆管理事务处理主要使用的是传统的人工管理方式&#xff0c;这种管理方式存在着管理效率低、操作流程繁琐、保密性差等缺点&#xff0c;长期的人工管理模式会产生大量…

超维空间M1无人机使用说明书——52、ROS无人机二维码识别与降落

引言&#xff1a;使用二维码引导无人机实现精准降落&#xff0c;首先需要实现对二维码的识别和定位&#xff0c;可以参考博客的二维码识别和定位内容。本小节主要是通过获取拿到的二维码位置&#xff0c;控制无人机全向的移动和降落&#xff0c;分为两种&#xff0c;一种是无人…

【JAVA】final、finally、finalize 有什么区别?

&#x1f34e;个人博客&#xff1a;个人主页 &#x1f3c6;个人专栏&#xff1a; JAVA ⛳️ 功不唐捐&#xff0c;玉汝于成 目录 前言 正文 final&#xff1a; finally&#xff1a; finalize&#xff1a; 结语 我的其他博客 前言 在Java中&#xff0c;final、f…

适合培训协会搭建的培训机构管理系统开发方案

一、项目背景与目标 &#xff08;一&#xff09;项目背景 培训学校教务管理系统是培训机构数字化管理的必备系统&#xff0c;该系统功能大大提升机构办学的管理效率、提升机构在家长心中的专业度&#xff0c;市面上的培训机构管理系统收费越来越贵&#xff0c;为了给协会内培…

CMake入门教程【核心篇】静态库 (.a, .lib)

😈「CSDN主页」:传送门 😈「Bilibil首页」:传送门 😈「动动你的小手」:点赞👍收藏⭐️评论📝 文章目录 概述创建静态库添加静态库到你的项目完整代码示例实战使用技巧与注意事项总结与分析概述 静态库在C++开发中扮演着重要的角色。它们通常以.a(在Unix-like系统

django websocket实现聊天室功能

注意事项channel版本 django2.x 需要匹配安装 channels 2 django3.x 需要匹配安装 channels 3 Django3.2.4 channels3.0.3 Django3.2.* channels3.0.2 Django4.2 channles3.0.5 是因为最新版channels默认不带daphne服务器 直接用命令 python manage.py runsever 默认运行的是w…

python协程asyncio的应用,async,await,loop

关于协程&#xff0c;asyncio&#xff0c;async&#xff0c;await&#xff0c;loop的概念&#xff0c;参照上一篇文章可迭代对象&#xff0c;迭代器&#xff0c;生成器&#xff0c;协程-CSDN博客 上一章我们详细的讲解了上述各个名词的概念&#xff0c;但是这些东西实际上该怎…

Dash+Plotly | Web应用开发(1)

本文为https://github.com/CNFeffery/DataScienceStudyNotes的学习笔记&#xff0c;部分源码来源于此仓库。 本期内容主要为基础概念、web布局方法和交互回调。 文章目录 Dash的主要模块Highlightlayoutcallback 惰性交互阻止初次回调忽略回调匹配错误控制部分回调输出不更新获…