【数据结构初阶】第四话 —— 动态栈的基本操作

news/2024/5/18 1:38:36/文章来源:https://blog.csdn.net/m0_63325890/article/details/127150162

在这里插入图片描述

文章目录

  • 什么是栈
  • 栈的结构
  • 1. 初始化栈
  • 2. 入栈
  • 3. 出栈
  • 4. 获取栈顶元素
  • 5. 获取栈中有效元素个数
  • 6. 检测栈是否为空
  • 7. 销毁栈
  • 8. 总结
  • 接口函数贴图


什么是栈

假如有⼀个⼜细⼜⻓的圆筒,圆筒⼀端封闭,另⼀端开⼝。往圆筒⾥放⼊乒乓球,先放⼊的靠近圆筒底部,后放⼊的靠近圆筒⼊⼝。
在这里插入图片描述

那么,要想取出这些乒乓球,则只能按照和放⼊顺序相反的顺序来取,先取出后放⼊的,再取出先放⼊的,⽽不可能把最⾥⾯最先放⼊的乒乓球优先取出。
在这里插入图片描述

stack)是⼀种线性数据结构,它就像⼀个上图所⽰的放⼊乒乓球的圆筒容器,栈中的元素只能先⼊后出 (First In Last Out,简称 FILO )。

最早进⼊的元素存放的位置叫作 栈底 (bottom),最后进⼊的元素存放的位置叫作 栈顶 (top)。

栈的结构

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

压栈: 栈的插入操作叫做进栈/压栈/入栈,入数据在栈顶(如图所示👇)。
在这里插入图片描述

出栈: 栈的删除操作叫做出栈。出数据也在栈顶(如图所示👇)。
在这里插入图片描述

栈这种数据结构既可以⽤ 数组 来实现,也可以⽤ 链表 来实现。

栈的数组实现如下👇
在这里插入图片描述

栈的链表实现如下👇
在这里插入图片描述

1. 初始化栈

栈可以使用数组或者链表实现,相对而言 数组的结构实现更优一些。因为数组在尾上插入数据的代价比较小。

首先,我们需要用 结构体 创建一个 ,这个结构体需要包括栈的基本内容(栈顶栈的容量)。
在这里插入图片描述

📝 代码示例

// 支持动态增长的栈
typedef struct Stack
{STDataType* a; //栈int top; //栈顶int capacity; //容量
}ST;

然后,我们对创建好的 进行初始化。

📝 代码示例

//初始化栈
void StackInit(ST* ps) {assert(ps);ps->a = NULL;ps->top = 0; // 如果top初始化的时候为0,那么它表示栈顶元素的最后一个位置ps->capacity = 0;
}

注意: 这里对栈顶的初始化其实有 2 种定义;

(1)如果把 top 初始化为 0,那么它表示 栈顶元素的最后一个位置。(先放数据再加加)
在这里插入图片描述
(2)如果把 top 初始化为 -1,那么它表示 栈顶元素。(先加加再放数据)

2. 入栈

⼊栈操作(push)就是把新元素放⼊栈中,只允许从栈顶⼀侧放⼊元素,新元素的位置将会成为新的栈顶(如图所示👇)。
在这里插入图片描述

动图演示👇
在这里插入图片描述

📝 代码示例

//入栈
void StackPush(ST* ps, STDataType x) {assert(ps);//满了扩容if (ps->top == ps->capacity) { // 当top等于capacity的时候,就需要扩容/*capacity第一次等于0,然后直接扩到4;第二次进来,直接扩2倍*/int newCapacity = ps->capacity == (0) ? (4) : (ps->capacity * 2);/*realloc是要给总空间的大小*/ps->a = (STDataType*)realloc(ps->a, newCapacity * sizeof(STDataType));/*检查是否扩容成功*/if (ps->a == NULL) {printf("realloc fail\n");exit(-1);}ps->capacity = newCapacity;}ps->a[ps->top] = x; // 栈顶位置存放元素xps->top++; // 然后top再指向下一个位置/*简化*///ps->a[ps->top++];
}

3. 出栈

出栈操作(pop)就是把元素从栈中弹出,只有栈顶元素才允许出栈,出栈元素的前⼀个元素将会成为新的栈顶。
在这里插入图片描述

动图演示👇
在这里插入图片描述

📝 代码示例

//出栈
void StackPop(ST* ps) {assert(ps);assert(ps->top > 0); //出栈之前,要确保top不为空--ps->top; // 栈顶向前移
}

4. 获取栈顶元素

栈顶元素,即获取栈的最上方的元素。若栈为空,则不能获取。
在这里插入图片描述

动图演示👇
在这里插入图片描述

📝 代码示例

//获取栈顶元素
STDataType StackTop(ST* ps) {assert(ps);assert(ps->top > 0); //如果top为0,那么栈就为空了,所以top不能为0/*top是指向栈顶元素的后一个位置,top-1才是栈顶元素*/return ps->a[ps->top - 1];
}

5. 获取栈中有效元素个数

因为 top 是从 0 开始的,而 栈顶元素 又在 top 的前一个位置,所以 top 的值便是栈中有效元素的个数。
在这里插入图片描述

📝 代码示例

// 获取栈中有效元素个数
int StackSize(ST* ps) {assert(ps);/*因为top是指向栈顶元素的最后一个位置假设元素为:1,2,3,4,5,那么top肯定是指向5的后一个位置又因为top是从0开始累加的,所以此时top肯定为5,刚好就是元素个数	*/return ps->top;
}

6. 检测栈是否为空

检测栈是否为空,即判断栈顶的位置是否是 0 即可。若栈顶是 0,则栈为空。
在这里插入图片描述

📝 代码示例

//检测栈是否为空
bool StackEmpty(ST* ps) {assert(ps);return ps->top == 0; 
}

7. 销毁栈

因为栈的内存空间是 动态开辟 出来的,当我们使用完后必须释放其内存空间,避免内存泄漏。

📝 代码示例

//销毁栈
void StackDestroy(ST* ps) {assert(ps);free(ps->a); // 释放栈ps->a = NULL; // 把栈置为空ps->top = 0; // 栈顶置0ps->capacity = 0; // 容量置0
}

8. 总结

栈的实现代码总体来说比较简单。

⼊栈和出栈只会影响到最后⼀个元素,不涉及其他元素的整体移动,所以⽆论是以数组还是以链表实现,⼊栈、出栈的时间复杂度都是 O(1)O(1)O(1)

栈的应用:

栈的输出顺序和输⼊顺序相反,所以栈通常⽤于对 “历史” 的回溯,也就是逆流⽽上追溯 “历史”。
 
例如实现递归的逻辑,就可以⽤栈来代替,因为栈可以回溯⽅法的调⽤链。
 
在这里插入图片描述
 
栈还有⼀个著名的应⽤场景是⾯包屑导航,使⽤户在浏览⻚⾯时可以轻松地回溯到上⼀级或更上⼀级⻚⾯。
 
在这里插入图片描述

接口函数贴图

最后附上一张完整的 双向链表接口函数图

在这里插入图片描述

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

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

相关文章

U盘插入自动读写/U盘插入自动复制/pythhttps://www.cnblogs.com/wawawa888/p/16749476.htmlon检测U盘的插入,以及进行自动复制文件并写入文件

U盘自动读写的小玩意 共有四种方法(我知道的方法,全是转载。转载也很不易,可望给个硬币) 方法一(vbs方法 全自动,转载自bilibili 点我跳转)文件下载链接(点我下载) 方法二(cmd方法 需手动,转载自bilibili 点我跳转)文件下载链接(点我下载) 方法三(python方法 全…

在DataFrame中根据索引值进行排序:sort_index()函数

【小白从小学Python、C、Java】 【Python-计算机等级考试二级】 【Python-数据分析】 在DataFrame中根据索引值进行排序: sort_index()函数 [太阳]选择题 对以下python代码表述有误的选项是? import numpy as np import pandas as pd data np.random.…

ElasticSearch_03_批量处理命令mget和bulk的使用

系列文章目录 文章目录系列文章目录前言一、批量处理命令mget方案1:body请求体中指定index和type方案2:url中指定index和type,body中仅指定ids方案2扩展:url中指定index和type,body中仅指定id数组二、基于bulk的增删改…

C++开发坦克大战--补充(加入传送门)--附完整代码

目录 素材整理 穿越草地 坦克穿越草地 子弹穿越草地 传送门 判定形式 生成传送门 传送坦克 关卡模式 效果展示 ​总结 完整代码 上一篇坦克大战居然意外获得了一些关注,正好最近也完善了一些功能,同时也加入了一些自己想到的新元素,主要是…

python requests cookie的获取和使用

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录前言一、cookie是什么?二、使用步骤开始代码实现会话是什么然后写入我们的账号信息使用session访问登陆账号的url获取账号的书架上的数据完整的代码补充比…

基于javaweb在线投票管理系统ssm

基于SSM的在线投票系统以XXX学院为背景,运用在校所学习的软件开发原理,采用SpringSpringMVCMyBatis技术和MySQL数据库构建一个基于B/S模式的在线投票系统。 传统的投票模式都是通过人工手动填写问卷的方式来进行,这在很大程度上会造成人力和…

1.1 Ryu 的安装部署

What is Ryu Ryu是轻量级的、开源的SDN控制器Ryu是由日本NTT公司在2012年推出其名字在日文中的意思是“Flow”和“Dragon”的意思 Ryu架构 Ryu安装 在Ubuntu上装Ryu和Mininet,CSDN上搜教程,这一部分正确做法是对着视频敲代码如果有问题去CSDN上找解决办…

滤波器基础01——滤波器的种类与特性

滤波器是一种选频装置,它能够保留某一频段的信号,将此频段之外的信号消除。以下介绍不同分类依据下滤波器的特点。 一. 模拟滤波器与数字滤波器 根据滤波器的作用对象是模拟信号还是数字信号可将滤波器分为模拟滤波器和数字滤波器。 模拟滤波器处理模…

创建并运行一个 Spring Boot 项目

创建并运行一个 Spring Boot 项目引言第一个 Spring Boot 项目1. 创建一个 spring boot 项目第一步第二步第三步第四步2. 验证第一步第二步3. 写一个 hello world第一步解析代码第二步注意事项网页创建一个 Spring Boot 项目Spring Boot 的优点引言 Spring Boot 是 Spring 框架…

升级迭代:让我的颜色控制打印工具mypycolor更聪明,参数可以任意接收颜色控制码、颜色描述英文单词的任意组合。

【点击此处跳转笔记正文】Python 官网:https://www.python.org/ Free:大咖免费“圣经”教程《 python 完全自学教程》,不仅仅是基础那么简单…… My CSDN主页、My HOT博、My Python 学习个人备忘录好文力荐、 老齐教室 自学并不是什么神秘的…

YOLOV+pytorch+win10+CPU环境配置

Step 1:下载github YOLOV3源码 链接:https://github.com/ultralytics/yolov3 Step 2:配置CPUpytorch版本环境 WinR启动cmd,在命令提示符内输入以下命令,创建一个新环境: conda create –n yolov-pytorc…

记录自学的学习路线(详细)

目录 HTML css javaScript javaScript高级 jQuery(快速过一遍) bootstrap 移动端适配 ajax ES6 Vue2vue3全家桶(vue3暂时不学,后面会解释原因) axios promise vue2结束后 Vue3 Ts 依我而言 曾经我也迷茫过,如何学习…

JWT 和 JJWT 还傻傻的分不清吗

JWTs是JSON对象的编码表示。JSON对象由零或多个名称/值对组成,其中名称为字符串,值为任意JSON值。 JWT有助于在clear(例如在URL中)发送这样的信息,可以被信任为不可读(即加密的)、不可修改的(即签名)和URL - safe(即Base64编码的)。 JSON Web Token (JWT) 作为一个开放的标准…

CPU--指令系统

1.机器的指令的一般格式:操作码字段,地址码字段; 2.数据在存储器中的存放方式:a,从任意位置开始--不浪费空间,读写控制比较复杂; :b, 从一个存储字的起始位置开始存储--读写控制简单,浪费空间;  :c,边界对准方式,按地址数字节的整数倍位置存储--结合前两者;3.寻址…

日本抢滩Web3:“樱花”如何在加密彼岸绽放

失去互联网之后,这个第三大经济体决定在Web3奋起直追。 9月22日,Astar 创始人渡边宗太在自己的博客宣布,Astar 的原生代币通过了金融厅和 JVCEA(日本加密资产交易协会)的严格审核,并将在日本本土交易所 Bit…

汉诺塔问题分治求解

汉诺塔问题 在经典汉诺塔问题中,有 3 根柱子及 n 个不同大小的穿孔圆盘,盘子可以滑入任意一根柱子。一开始,所有盘子自上而下按升序依次套在第一根柱子上(即每一个盘子只能放在更大的盘子上面)。移动圆盘时受到以下限制: (1) 每次只能移动一个盘子; (2) 盘子只能从柱子顶端滑…

Java Web 10 JSP 10.7 MVC 模式和三层架构

Java Web 【黑马程序员新版JavaWeb基础教程,Java web从入门到企业实战完整版】 10 JSP 文章目录Java Web10 JSP10.7 MVC 模式和三层架构10.7.1 MVC 模式10.7.2 三层架构10.7.3 MVC 和 三层架构10.7 MVC 模式和三层架构 MVC 模式和三层架构是一些理论的知识&#…

基于SpringBoot视频学习系统|视频点播系统的设计与实现【Java毕业设计·安装调试·代码讲解·文档报告】

🍊作者:计算机编程-吉哥 🍊简介:专业从事JavaWeb程序开发,微信小程序开发,定制化项目、源码、代码讲解、文档撰写、ppt制作。做自己喜欢的事,生活就是快乐的。 🍊心愿:点…

cnpm使用 install报错throw err;^Error: Cannot find module fs/promises

cnpm使用 install报错throw err;^Error: Cannot find module fs/promises这个问题主要是 node的版本和cnpm的版本不匹配--检查一下项目中的 node版本和cnpm版本:cnpm的版本是不是高于8.3.0 cnpm 8.30 版本,无法在 12.18.2 的node 版本下使用,使用命令将 cnpm 降低版本即可np…

燕山大学汇编语言程序设计(汇编语言源程序的输入、 数 据的建立与传送程序、分支程序设计、统计学生成绩程序、学生成绩名次表实验)

实 验 一 汇 编 语 言 源 程 序 的 输 入 一、实验目的 1.通过实验了解和熟悉微机系统的配置。2.学习在DEBUG状态下输入汇编源程序的方法。 3.初步掌握调试(在DEBUG状态下)的过程。 二、实验原理 1. 本实验要求在DEBUG状态下输入汇编源程序,并用DEBUG命令进行调…