【数据结构】栈的实现
💯💯💯
本篇主要利用数组来实现栈,对于栈的各种操作都作详细介绍,压栈,出栈以及获取栈中元素的操作都是学习栈的必备知识,快来学起来吧!!!
- ©Ⅰ.栈的概念及结构
- ©Ⅱ.栈的实现
- 2.1栈的初始化
- 2.2压栈
- 2.3出栈
- 2.4获取栈顶元素
- 2.5获取栈中有效元素的个数
- 2.6销毁栈
- 2.7栈的"打印"
©Ⅰ.栈的概念及结构
栈:是一种特殊的线性表,其只允许在固定的一端进行插入与删除操作。
进行数据的插入和删除的一端称为栈顶,另一端称为栈底。
栈遵循先进后出,后进先出的原则。
压栈:栈的插入操作叫做压栈/入栈/进栈,在栈顶实现
出栈:栈的删除操作叫做出栈。也在栈顶实现。
入栈
出栈

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

//下面是定长的静态栈的结构,实际中一般不用,因为不能扩大容量,所以我们主要实现下面的支持动态增长的栈
#define N 10
typedef int STData;
struct stack1
{int arr[N];//静态数组int top;//栈顶
}ST;//支持动态增长的栈结构
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
typedef int STData;//重定义栈使用的数据,如果栈使用的数据不是int类型那么可以通过修改这里从而修改栈的使用数据类型
typedef struct Stack
{int* a;//指向一个数组的指针int top;//栈顶int capicty;//数组容量
}ST;//重命名为ST
//初始化栈表
void STInit(ST*ps);
//销毁栈表
void STDestroy(ST* ps);
//压栈,在栈顶压入一个元素
void STpush(ST* ps,STData x);
//出栈,在栈顶弹出一个元素。
void STpop(ST* ps);
//访问栈顶元素
//获取栈有效数据的大小
int STSize(ST* ps);
STData STTop(ST* ps);
//检查栈是否为空,如果为空返回值为非0,如果是假则返回0;
int STSize(ST* ps);
2.1栈的初始化
因为该数组是动态数组,可以增容,一开始我们可以给数组一定的容量,当数组元素个数等于容量时再进行扩容即可。
不过要注意的是top值应该初始化为几呢?
如果初始化为0,那a[top]表示的是有元素还是没有元素呢?
如果初始化为0的化,那top就表示指向栈顶元素下一个位置的地方。
而如果初始化为-1,那才表示的是栈顶元素的位置。一开始没有元素,top为-1,当有元素压栈进来后,top++,变成0,a[top]上就存在元素了。
两中表示方法都可以,但 要注意表示一种就要一种按照该逻辑进行。
void STInit(ST* ps)//初始化栈表
{assert(ps);//判断结构体指针不为NULL;//一上来可以给栈表初始化容量ps->a = (STData*)malloc(sizeof(STData) * 4);if (ps->a == NULL)//判断是否开辟成功{perror("malloc");}//初始话容量为4ps->capicty = 4;ps->top = 0;//top=0 表示的是指向栈顶元素的下一个位置//top如果为-1,则表示栈顶元素的位置
}
2.2压栈
在元素入栈之前我们需要考虑是否栈空间已满,而需要进行扩容。
所以一开始我们就需要将扩容操作写下。
每次扩容两倍。容量的大小随之改变。
还要注意的是,当入栈后,top是要进行++,然后top就是指向栈顶元素下一个位置的地方了。
void STpush(ST* ps, STData x)//压栈,在栈顶压入一个元素--在压入之前也要考虑是否需要增容
{assert(ps);//断言判断if (ps->top == ps->capicty)//当数组元素等于容量时{//增容STData* tmp = (STData*)realloc(ps->a, sizeof(STData) * ps->capicty * 2);if (tmp == NULL){perror("realloc");}ps->a = tmp;//将扩容的空间赋给aps->capicty *= 2;//数组的容量也随之变大}ps->a[ps->top] = x;//将元素压入栈顶,一开始top是0,当元素进去后,再让top指向该栈顶元素后一个位置ps->top++;
}
2.3出栈
在删除数据之前我们需要考虑栈空间里还有没有数据可以删除,当栈空间里没有数据可删,那就立刻停止。
所以我们首先需要对栈进行检查是否为空。
当栈为空时返回非0,不为空时返回0;
int STEmpty(ST* ps)
{assert(ps);return ps->top == 0;
}
而删除数据的操作我们只要让top–即可,不需要释放空间。
void STpop(ST* ps)//出栈,在栈顶弹出一个元素。
{assert(ps);//删除元素之前要检查栈表是否还有元素可删assert(!STEmpty(ps));//当栈表为NULL是断言ps->top--;}
2.4获取栈顶元素
获取栈顶元素也就是top所指向的元素,但要注意每次压入一个数据后top都会++,所以最后top是多加了一次,要想访问最后一个元素也就是栈顶元素需要top-1;
STData STTop(ST* ps)//访问栈顶元素
{assert(ps);//断言判断return ps->a[ps->top - 1];//top-1的位置才是栈顶元素
}
2.5获取栈中有效元素的个数
其实top的数值大小就是栈中有效元素的个数,
一开始top为0,表中没有元素,当有元素时,top就进行++,有一个加一次,有一个加一次,所以最后栈中有效元素的个数就是top的数值
int STSize(ST* ps)//计算栈表长度
{assert(ps);//断言判断return ps->top;//top的长度就是栈表的长度
}
2.6销毁栈
将栈销毁掉也就是让数据都归还操作系统。
开辟的空间需要释放,定义的变量需要置0;
void STDestroy(ST* ps)//销毁栈表
{assert(ps);//断言判断free(ps->a);//释放数值空间ps->a = NULL;//并手动置NULLps->capicty = 0;//置0ps->top = 0;}
2.7栈的"打印"
栈是不能进行打印的,因为栈要求数据后入的要先出,而打印的顺序是先入先出。
想要让栈的数据展现出来,那就要按照它的特点,我们先打印栈顶元素,打印完再将栈顶元素出栈,再打印新的栈顶元素,再出栈,知道栈变成空为止。
void test()
{ST p;STInit(&p);STpush(&p, 1);STpush(&p, 2);STpush(&p, 3);STpush(&p, 4);STpush(&p, 5);printf("%d\n", STSize(&p));//获得栈中有效元素的个数while (!STEmpty(&p)){printf("%d ", STTop(&p));//将栈的数据展现出现,要求先进后出,后进先出STpop(&p);}STDestroy(&p);
}


相关文章:
【数据结构】栈的实现
💯💯💯 本篇主要利用数组来实现栈,对于栈的各种操作都作详细介绍,压栈,出栈以及获取栈中元素的操作都是学习栈的必备知识,快来学起来吧!!!©Ⅰ.栈的概念及…...
【链表OJ题(六)】链表分割
📝个人主页:Sherry的成长之路 🏠学习社区:Sherry的成长之路(个人社区) 📖专栏链接:数据结构 🎯长路漫漫浩浩,万事皆有期待 文章目录链表OJ题(六)1. 链表…...
C++类中的三大函数(构造,析构,拷贝)
下面一段话与大家共勉:每个人的一生都会遇到很多边界,有些边界可以突破,有些则不能。那些无法突破的边界就是你的极限,而划分边界的标准就是“阈值”。每次突破阈值之后,人生轨迹就会发生剧烈变化,其间需要…...
【2024考研】计算机考研,4轮复习时间安排
文章目录🎨第1轮复习(暑假前&系统课)英语1/2数学1/2专业课408🎨第2轮复习(开学前&真题)英语1/2试卷数学1/2试卷专业课408试卷🎨第3轮复习(报名前&政治)政治试…...
(十二)python网络爬虫(理论+实战)——实战:使用BeautfulSoup解析baidu热搜新闻数据
系列文章: python网络爬虫专栏 目录 序言 本节学习目标 特别申明 4.7 使用BeautfulSoup解析h...
【经验】项目管理:瀑布式、Scrum
1、瀑布式开发 流程关键词关键人员输出立项简述、周期、预算领导立项申请表、立项评审表策划计划项目经理、QA、CM各种计划书(项目、配置、测试等),评审需求功能项目经理功能列表、需求规格书、需求开发计划等,评审设计UML开发设…...
Learning C++ No.17【STL No.7】双端队列
引言: 北京时间:2023/3/17/7:18,刚刚快乐的早锻炼回来(不对 ,应该说回来有一会了),因为此时我已经吃完早饭,洗过澡了;现在回想起上学期,就算是第二天需要晨跑…...
Snackbar
1.简介 位于底部的提示View 支持侧滑消失 同一时间只有一个 不支持跨Activity展示 国内使用率很低 2.基础使用 2.1 基本展示 Snackbar.make(view, "Content", Snackbar.LENGTH_LONG).show()2.2 设置点击事件 注意不设置点击事件回调,点击按钮的文字不…...
HummerRisk 使用教程:主机检测
1. 概述 HummerRisk 是开源的云原生安全平台,以非侵入的方式解决云原生环境的安全和治理问题。核心能力包括混合云的安全治理和容器云安全检测。 本文将介绍HummerRisk中的主机检测部分功能,包括如何管理主机、管理凭证,以及使用主机检测规…...
【Arduino无线气象站项目】
【Arduino无线气象站项目】 1. 概述2. Arduino无线气象站电路图3. 定制设计电路板4. Arduino无线气象站代码5. 总结1. 概述 使用DHT22传感器测量室外温度和湿度,并使用NRF24L01收发器模块将这些数据无线发送到室内机。在室内机,还有另一个用于测量室内温度和湿度的DHT22传感…...
HTTP详解
一,什么是HTTPHTTP(全称为“超文本传输协议”),是一种应用非常广泛的应用层协议,之前在《初识网络原理》的博客(初识网络原理_徐憨憨!的博客-CSDN博客)中,有详细讲解过TCP/IP五层模型,其中应用层描述了数据…...
cpufreq--处理器功耗控制
cpu 功耗控制 参考框架: cpufreq 框架。 cpufreq 框架提供 cpu 功耗管理接口,以及功耗管理方案。 用户可以通过功耗管理接口(以文件形式提供)来选择管理方案,并设置相关参数。 管理方案的实现则由具体的驱动来完成。…...
做技术,最忌讳东张西望
又好长时间没更新,研二了,忙着做实验、写论文、发论文,再加上给我导做一些事情(都习惯了,以前很不爽的事情,现在居然能这么平静的说出来)。 但这不是我今天说的重点,而是另外一件事…...
Oracle 常见报错问题汇总
Oracle 常见报错问题汇总 报错:ORA-01017: invalid username/password; logon denied报错:ORA-01031: insufficient privileges报错:"ORA-01034: ORACLE not available" 和 "ORA-27101: shared memory realm does not exist"报错:“ORA-00119: invalid…...
单片机连接有人云上传数据
首先采用有人物联网的模块 ,连接有人云平台服务器 看云平台相关配置配置连接设备在线后 添加设备添加设备完成后 添加变量模板 变量模板的添加方式如下 :本次采用的是标准的MODbus 协议添加一个温度变量温度变量如下显示云平台 下发数据 采集01 03 00 00…...
系统集成项目管理工程师:第18章项目风险管理学习笔记
第18章项目风险管理 一、目录 18.1 风险概述 18.1.1 风险的定义 18.1.2 风险的分类 18.1.3 风险的性质 18.2 项目风险管理 18.3 规划风险管理 18.3.1 规划风险管理的输入 18.3.2 规划风险管理的工具与技术 18.3.3 规划风险管理的输出 18.4 识别风险...
【笔试强训选择题】Day3.习题(错题)解析
文章目录 前言一、Day3习题(错题)解析二、Day3习题(原题)练习总结前言 今天我们将进入到第三天的练习,希望能一直坚持下去,不断反思总结错误,得到进步; 一、Day3习题(错…...
基于GPT-4的免费代码生成工具
大家好,我是herosunly。985院校硕士毕业,现担任算法研究员一职,热衷于机器学习算法研究与应用。曾获得阿里云天池比赛第一名,CCF比赛第二名,科大讯飞比赛第三名。拥有多项发明专利。对机器学习和深度学习拥有自己独到的见解。曾经辅导过若干个非计算机专业的学生进入到算法…...
Android开发的这一年里,Jetpack的Room源码是怎么狠狠奖励我的?
简述 Android Jetpack的出现统一了Android开发生态,各种三方库逐渐被官方组件所取代。Room也同样如此,逐渐取代竞品成为最主流的数据库ORM框架。这当然不仅仅因为其官方身份,更是因为其良好的开发体验,大大降低了SQLite的使用门槛…...
推荐一款卸载软件的小工具-《UninstallToo》
目录 UninstallToo介绍 UninstallToo下载 UninstallToo使用 总结 UninstallToo介绍 Uninstall Tool 是一款可以用来替代“添加/删除程序”的工具。它允许您显示隐藏的安装程序,按名称过滤已安装程序的列表,强行写在程序,浏览注册表项目&a…...
日语AI面试高效通关秘籍:专业解读与青柚面试智能助攻
在如今就业市场竞争日益激烈的背景下,越来越多的求职者将目光投向了日本及中日双语岗位。但是,一场日语面试往往让许多人感到步履维艰。你是否也曾因为面试官抛出的“刁钻问题”而心生畏惧?面对生疏的日语交流环境,即便提前恶补了…...
前端导出带有合并单元格的列表
// 导出async function exportExcel(fileName "共识调整.xlsx") {// 所有数据const exportData await getAllMainData();// 表头内容let fitstTitleList [];const secondTitleList [];allColumns.value.forEach(column > {if (!column.children) {fitstTitleL…...
Opencv中的addweighted函数
一.addweighted函数作用 addweighted()是OpenCV库中用于图像处理的函数,主要功能是将两个输入图像(尺寸和类型相同)按照指定的权重进行加权叠加(图像融合),并添加一个标量值&#x…...
1688商品列表API与其他数据源的对接思路
将1688商品列表API与其他数据源对接时,需结合业务场景设计数据流转链路,重点关注数据格式兼容性、接口调用频率控制及数据一致性维护。以下是具体对接思路及关键技术点: 一、核心对接场景与目标 商品数据同步 场景:将1688商品信息…...
将对透视变换后的图像使用Otsu进行阈值化,来分离黑色和白色像素。这句话中的Otsu是什么意思?
Otsu 是一种自动阈值化方法,用于将图像分割为前景和背景。它通过最小化图像的类内方差或等价地最大化类间方差来选择最佳阈值。这种方法特别适用于图像的二值化处理,能够自动确定一个阈值,将图像中的像素分为黑色和白色两类。 Otsu 方法的原…...
第25节 Node.js 断言测试
Node.js的assert模块主要用于编写程序的单元测试时使用,通过断言可以提早发现和排查出错误。 稳定性: 5 - 锁定 这个模块可用于应用的单元测试,通过 require(assert) 可以使用这个模块。 assert.fail(actual, expected, message, operator) 使用参数…...
鱼香ros docker配置镜像报错:https://registry-1.docker.io/v2/
使用鱼香ros一件安装docker时的https://registry-1.docker.io/v2/问题 一键安装指令 wget http://fishros.com/install -O fishros && . fishros出现问题:docker pull 失败 网络不同,需要使用镜像源 按照如下步骤操作 sudo vi /etc/docker/dae…...
laravel8+vue3.0+element-plus搭建方法
创建 laravel8 项目 composer create-project --prefer-dist laravel/laravel laravel8 8.* 安装 laravel/ui composer require laravel/ui 修改 package.json 文件 "devDependencies": {"vue/compiler-sfc": "^3.0.7","axios": …...
Selenium常用函数介绍
目录 一,元素定位 1.1 cssSeector 1.2 xpath 二,操作测试对象 三,窗口 3.1 案例 3.2 窗口切换 3.3 窗口大小 3.4 屏幕截图 3.5 关闭窗口 四,弹窗 五,等待 六,导航 七,文件上传 …...
STM32---外部32.768K晶振(LSE)无法起振问题
晶振是否起振主要就检查两个1、晶振与MCU是否兼容;2、晶振的负载电容是否匹配 目录 一、判断晶振与MCU是否兼容 二、判断负载电容是否匹配 1. 晶振负载电容(CL)与匹配电容(CL1、CL2)的关系 2. 如何选择 CL1 和 CL…...


