数据结构初阶 栈

news2024/12/23 9:49:01

一. 栈的基本介绍

1. 基本概念

栈是一种线性表 是一种特殊的数据结构

栈顶:进行数据插入和删除操作的一端

另一端叫做栈底

压栈:插入数据叫做压栈 压栈的数据在栈顶

出栈: 栈的删除操作叫做出栈 出栈操作也是在栈顶

栈遵循一个原则 叫做后进先出

(比如说子弹的弹夹 其实就是一种设计好的栈结构)

画图表示如下

2. 代码结构 (动态数组实现) 

因为数组模式相对于链表模式来说 尾插的操作消耗更好些

此外因为静态的数组不能变更空间大小 所以说我们这里用动态数组的代码来实现一下

typedef int STDateType;

typedef struct Stack
{
    int* a;//存储数据的大小
    int Top;//栈顶
    int capacity;//容量大小
}ST;

 二. 接口函数实现

1. 初始化栈

这个很简单 初始化栈里面的三个值就好

代码表示如下

//初始化
void STInit(ST* ps)
{
	assert(ps);
	ps->a = (STDateType*)malloc(sizeof(STDateType)*4);
	if (ps->a == NULL)
	{
		perror("malloc fail");
		return;
	}
	ps->Top = 0;//top是栈顶元素的下一个位置
	ps->capacity = 4;
}

我们这里要注意Top初始化值的不同后面几个操作Top也不同

初始化为0表示栈顶元素的下一个位置,初始化为1表示栈顶的位置

2. 压栈

这里我们需要考虑一个问题

我们压栈的时候是否空间满了呢?

所以在压栈之前我们先判断一下Top和capacity来看看栈空间是否满了

整体代码表示如下

void STPush(ST* ps, STDateType x)
{
	assert(ps);
	if (ps->Top == ps->capacity)
	{
		STDateType* tmp = (STDateType*)realloc(ps->a, sizeof(STDateType) * ps->capacity * 2);
		if (tmp == NULL)
		{
			perror("realloc fail");
			return;
		}
		ps->a = tmp;
		ps->capacity *= 2;
	}
	ps->a[ps->Top] = x;
	ps->Top++;
}

来看看效果:

 

可以运行

3. 出栈

这个很简单 只需要考虑一个问题

是否删除了过多的数据导致错误

代码表示如下

//出栈
void STPop(ST* ps)
{
	assert(ps);
	assert(!STEmpty(ps));

	 ps->Top--;
}

我们在打印压栈操作的时候已经用过我们的出栈操作,否则无法打印

效果如下:

4. 找到个数

这个很简单 返回Top的值就可以

//个数
int STSize(ST* ps)
{
	assert(ps);

	return ps->Top;
}

5. 判断是否为空

这个也很简单 两行代码搞定

//判断空
bool STEmpty(ST* ps)
{
	assert(ps);

	return ps->Top==0;
}

6. 摧毁栈

释放开辟出的内存空间 之后再指针置空就可以

这个也很简单 这里就不过多介绍了

//销毁
void STDestroy(ST* ps)
{
	assert(ps);
	free(ps->a);
	ps->capacity = 0;
	ps->Top = 0;
	ps->a = NULL;
}

7.top的位置

//top的位置
STDateType STTop(ST* ps)
{
	assert(ps);
	assert(!STEmpty(ps));

	return ps->a[ps->Top - 1];
}

也很简单,根据前面我们top初始化的值,这里需要top-1

三. 两道简单的题目

题目一

一个栈的初始状态为空。现将元素1、2、3、4、5、A、B、C、D、E依次入栈,然后再依次出栈,则元素出栈的
顺序是( )。
A 12345ABCDE
B EDCBA54321
C ABCDE12345
D 54321EDCBA

答案是B 遵循后进先出的原则

题目二

若进栈序列为 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 再出栈1 压栈 2 3 4 再依次出栈就可以 没问题

B选项

我们先压栈 1 2 出栈2 再压栈3 4 再依次出栈就可以 没有问题

C选项

我们先压栈123 出栈3 之后再出栈1 这个就不对了 要想出栈1 必须先出栈2

所以答案是C

D选项

我们先压栈 1 2 3 再出栈3 然后压栈4 再依次出栈就可以 没有问题

以上便是本文所以内容了,如有错误请各位大佬不吝赐祭,感谢留言

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

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

相关文章

人脸检测--FaceNet(四)

FaceNet 是一个由 Google 研究团队开发的人脸识别系统,它基于深度学习技术,可以实现高精度的人脸识别、验证和聚类任务。FaceNet 通过学习直接从图像像素到人脸嵌入的映射,使得它在各种人脸识别任务中表现出色。下面是对 FaceNet 的详细介绍&…

python探索时钟模拟之旅:从设计到实现

新书上架~👇全国包邮奥~ python实用小工具开发教程http://pythontoolsteach.com/3 欢迎关注我👆,收藏下次不迷路┗|`O′|┛ 嗷~~ 目录 一、引言 二、设计时钟类 三、代码实现 四、扩展功能:指定步数后自动停止 五…

编程中的模块迷宫:区分与正确使用

新书上架~👇全国包邮奥~ python实用小工具开发教程http://pythontoolsteach.com/3 欢迎关注我👆,收藏下次不迷路┗|`O′|┛ 嗷~~ 目录 一、模块混淆的陷阱 二、碳模块与探母模块的区别 三、如何正确使用模块 四、代码示例 五…

【Linux】数据链路层协议+ICMP协议+NAT技术

欢迎来到Cefler的博客😁 🕌博客主页:折纸花满衣 🏠个人专栏:Linux 目录 👉🏻数据链路层👉🏻以太网以太网帧格式网卡Mac地址对比ip地址 👉🏻MTUMTU…

9、C#【进阶】特性

特性 文章目录 1、特性概念2、自定义特性 Attribute3、特性的使用4、限制自定义特性的使用范围5、系统自带特性1、过时特性2、调用者信息特性3、条件编译特性4、外部dll包函数特性 1、特性概念 特性是一种允许我们向程序的程序集添加元数据的语言结构 它是用于保存程序机构信息…

5、xss-labs之level6

一、level6-----大小写绕过 1、测试分析 测试了之前用过的payload&#xff0c;发现都不行&#xff0c;并且level4使用的Java伪协议也不行&#xff0c;可以得出<>、script、onclick都被过滤 2、构造payload 因为href被过滤&#xff0c;可以试一下大写HREF 初试payload…

【debug】windows11安装WSL+Docker+本地部署cvcat

windows系统安装wsl虚拟机 首先观察是否已启用虚拟化&#xff1a; 在windows应用商店下载wsl 下载好后打开&#xff0c;创建用户名和密码&#xff0c;即可使用&#xff1a; 换源&#xff1a;ubuntu | 镜像站使用帮助 | 清华大学开源软件镜像站 | Tsinghua Open Source Mirr…

双机多网口配置同网段地址,可以通过目的IP确定接收数据的网卡吗?

环境 两台机器两网卡同网段接入同一个二层交换机。 机器A ens38 00:0c:29:a4:8b:fb 10.0.0.11/24 ens39 00:0c:29:a4:8b:05 10.0.0.12/24 机器B ens38 00:0c:29:4f:a6:c4 10.0.0.21/24 ens39 00:0c:29:4f:a6:ce 10.0.0.22/24 初始ARP表 只有管理口接口的ARP表项&#xff0c…

【C++】list的使用方法和模拟实现

❤️欢迎来到我的博客❤️ 前言 list是可以在常数范围内在任意位置进行插入和删除的序列式容器&#xff0c;并且该容器可以前后双向迭代list的底层是双向链表结构&#xff0c;双向链表中每个元素存储在互不相关的独立节点中&#xff0c;在节点中通过指针指向其前一个元素和后…

Pytest用例自定义 - 重复、并行、串行

简介&#xff1a;面对快速迭代和持续交付的需求&#xff0c;提高测试效率变得至关重要。并行测试因其显著的时间节省优势而备受青睐。然而&#xff0c;并非所有测试都适合并行执行。在某些情况下&#xff0c;串行执行是必要的&#xff0c;以确保测试的正确性和稳定性。本文将探…

进程和用户管理

查看进程的命令 ps top pstree 发送信号命令 kill 使用是后加-l 用户管理命令 添加用户:sudo adduser 用户名 修改组:sudo usermod -G 用户名1 用户名2 修改家目录:sudo usermod -d /home/用户名 -m 用户名 删除用户名:sudo deluser --remove -home 用户名

newinit.sh挖矿攻击处理与规避方案

目录 攻击分析 恢复措施&#xff1a; 问题排查 攻击入口分析 预防 临时处理方案&#xff1a; 攻击分析 攻击者&#xff1a;职业黑客&#xff08;99%&#xff09; 攻击方式&#xff1a;挖矿病毒newinit.sh和蠕虫病毒pnscan 中毒现象: 服务器负载异常&#xff0c;具体表…

Celery教程

一、什么是Celery 1.1、celery是什么 Celery是一个简单、灵活且可靠的&#xff0c;处理大量消息的分布式系统&#xff0c;专注于实时处理的异步任务队列&#xff0c;同时也支持任务调度。 Celery的架构由三部分组成&#xff0c;消息中间件&#xff08;message broker&#x…

利用基于CNN的人员检测与关键词识别的TinyML实现无接触电梯

目录 说明 论文概述 摘要 引言 现有非接触式电梯解决方案 新解决方案的需求 tinyML实施 系统构建和算法管道 CNN和TinyML实现 结果与讨论 结论 视频演示和代码可用性 一点感想 说明 我一直使用Google Schloar订阅最新的论文消息&#xff0c;今天看到一篇论文的标…

【Docker|漏洞】Docker api未授权导致rce

一、漏洞描述 扫描出http://ip地址:4243漏洞&#xff0c;该漏洞可通过Docker pai未授权访问可以直接执行命令&#xff0c;获取服务器权限。 二、解决方案 禁用Docker api远程访问功能&#xff0c;或者通过安全授权等方式限制其使用权限。升级duoker至最新版本。 三、漏洞排查…

java第十七课 —— 递归

方法递归调用 递归就是方法自己调用自己&#xff0c;每次调用时传入不同的变量&#xff0c;递归有助于编程者解决复杂问题&#xff0c;同时可以让代码变得简洁。 递归重要规则 执行一个方法时&#xff0c;就创建一个新的受保护的独立空间&#xff08;栈空间&#xff09;。方…

【CTF Web】CTFShow web11 Writeup(RCE+PHP+代码审计)

web11 1 阿呆听完自己菜死了&#xff0c;自己呆了。决定修好漏洞&#xff0c;绝对不能让自己再菜死了。 解法 可知 flag 在 config.php。 <?php # flag in config.php include("config.php"); if(isset($_GET[c])){$c $_GET[c];if(!preg_match("/system…

Maven高级详解

文章目录 一、分模块开发与设计分模块开发的意义模块拆分原则 分模块开发(模块拆分)创建Maven模块书写模块代码通过maven指令安装模块到本地仓库(install指令) 二、依赖管理依赖传递可选依赖排除依赖可选依赖和排除依赖的区别 三、聚合与继承聚合工程聚合工程开发创建Maven模块…

专业的Java工程管理软件源码:详尽的项目模块及其功能点清单

在工程项目管理软件领域&#xff0c;我们致力于提供全过程、全方位的综合管理解决方案。该软件覆盖了建设工程项目管理组织建设、项目策划决策、规划设计、施工建设到竣工交付、总结评估、运维运营的各个环节&#xff0c;确保项目管理的全面性和高效性。 工程项目管理软件包含…

VirtualBox虚拟机与bhyve虚拟机冲突问题解决@FreeBSD

问题 在安装完bhyve虚拟系统的主机上启动VirtualBox虚拟机的时候&#xff0c;报错&#xff1a;不能为虚拟电脑 debian 打开一个新任务. VirtualBox cant operate in VMX root mode. Please close all other virtualization programs. (VERR_VMX_IN_VMX_ROOT_MODE). 返回 代码…