数据结构-栈(带图)

目录

栈的概念

画图理解栈

栈的实现

fun.h

fun.c

main.c


栈的概念

栈(Stack)是一种基本的数据结构,其特点是只允许在同一端进行插入和删除操作,这一端被称为栈顶。遵循后进先出(Last In, First Out, LIFO)原则,即最后存入栈中的元素最先被取出。形象地讲,栈就像是生活中堆放盘子的架子,我们总是把新的盘子放在最上面,而需要拿盘子时也是从最上面开始拿。

生活中就有栈的一些例子比如这些图片:

栈的基本操作包括

  1. 压栈(Push):向栈顶添加一个元素。相当于在堆叠的顶部放入一个新的物品。
  2. 出栈(Pop):从栈顶移除一个元素,并可选择返回这个元素。这类似于从堆叠顶部移走最上面的物品。
  3. 查看栈顶元素(Peek/Top):获取栈顶的元素但不移除它,用于检查或获取栈顶的信息。
  4. 判断栈是否为空(IsEmpty):检查栈中是否有元素。
  5. 获取栈的大小(Size):返回栈中元素的数量

画图理解栈

首先我们栈有一个原理:先进后出,后进先出,于是我们得得到这么个图


开始压栈,压栈的同时我们的p指针也要同时往后面走


最总


出栈


依次出栈后

这里为什么会1 2 3 4压栈出栈后变成了4321?

其实正确的压栈出栈我们需要边压栈边出栈就不会出现这种情况了,所以我main函数中是这样写的

int main1() {
	Stack p;
	STInit(&p);//初始化栈
	StackPush(&p, 1);//压栈
	StackPop(&p);//出栈
	printf("%d\n", p.a[p.top]);
	StackPush(&p, 2);
	StackPop(&p);
	printf("%d\n", p.a[p.top]);
	StackPush(&p, 3);
	StackPop(&p);
	printf("%d\n", p.a[p.top]);	
}

栈的实现

接下来我们用代码实现栈,这里我用了三个文件,解析都在注释中

fun.h

这个文件里有我实现了栈的一些功能

#pragma once
//头文件
#include<stdlib.h>
#include<stdbool.h>
#include<stdio.h>
#include<assert.h>

typedef int STDataType;
//栈的结构
typedef struct Stack
{
	STDataType* a;//指针
	int top;//栈顶
	int capacity;//容量
}Stack;

// 初始化栈 
void StackInit(Stack* ps);
// 入栈 
void StackPush(Stack* ps, STDataType data);
// 出栈 
void StackPop(Stack* ps);
// 获取栈顶元素 
STDataType StackTop(Stack* ps);
// 获取栈中有效元素个数 
int StackSize(Stack* ps);
// 检测栈是否为空,如果为空返回非零结果,如果不为空返回0 
bool StackEmpty(Stack* ps);
// 销毁栈 
void StackDestroy(Stack* ps);

fun.c

#define _CRT_SECURE_NO_WARNINGS 1
#include"fun.h"

//扩容函数
void Exp(Stack* p) {
	if (p->capacity == p->top)
	{
		//利用三目运算来判断是否
		int New_cap = p->capacity == 0 ? 4 : p->capacity * 2;
		STDataType* tmp = (STDataType*)realloc(p->a, New_cap * sizeof(STDataType));
		if (tmp == NULL)
		{
			assert("realloc");
			return;
		}
		//将开辟空间给给原来的变量
		p->a = tmp;
		p->capacity = New_cap;
	}
}

//初始化
void StackInit(Stack* p) {
	assert(p);
	p->a = NULL;
	p->capacity = p->top = 0;
}
// 入栈 
void StackPush(Stack* p, STDataType data){
	assert(p);
	//判断空间
	Exp(p);
	//入栈
	p->a[p->top] = data;
	//入栈后栈顶向上移动
	p->top++;
}
//出栈
void StackPop(Stack* p) {
	assert(p);
	assert(p->top > 0);//确保不为空

	//判断是否元素是否为0,避免越界 
	/*if (p->top == 0)
	{
		return;
	}*/
	p->top--;
}
// 获取栈顶元素 
STDataType StackTop(Stack* p) {
	//判断是否为0
	if (p->top == 0)
	{
		return (STDataType)0;//由于返回类型是 STDataType,所以需要强制转换
	}
	return p->a[p->top - 1];
}
// 获取栈中有效元素个数 
int StackSize(Stack* p) {
	return p->top;

}
//判空
bool StackEmpty(Stack* p) {
	// 使用逻辑非操作符(!)来检查栈顶指针(top)是否为0(即栈是否为空)
	// 如果top为0,说明栈中没有任何元素,因此栈是空的
	// 在C语言中,逻辑非操作符会将0转换为1(true),非0转换为0(false)
	// 所以当栈顶指针top为0时,!p->top的结果为true(非零值),表示栈为空
	// 反之,如果栈中有元素(top非0),则!p->top的结果为false(0),表示栈非空
	return !p->top;
}
// 销毁栈 
void StackDestroy(Stack* p) {
	if (p->a)
	{
		free(p->a);
		p->a = NULL;
		p->capacity = p->top = 0;
	}
}

main.c

#define _CRT_SECURE_NO_WARNINGS 1
#include"fun.h"
//
//int main1() {
//	Stack p;
//	STInit(&p);
//	StackPush(&p, 1);
//	StackPop(&p);
//	printf("%d\n", p.a[p.top]);
//	StackPush(&p, 2);
//	StackPop(&p);
//	printf("%d\n", p.a[p.top]);
//	StackPush(&p, 3);
//	StackPop(&p);
//	printf("%d\n", p.a[p.top]);
//	
//	
//}

int main() { 
	Stack s1;
	StackInit(&s1);
	StackPush(&s1, 1);
	StackPush(&s1, 2);
	printf("栈中元素个数:%d个\n", StackSize(&s1));
	while (!StackEmpty(&s1))
	{
		printf("%d\n", StackTop(&s1));
		StackPop(&s1);
	}
	printf("栈中元素个数:%d个", StackSize(&s1));
	StackDestroy(&s1);
}

这个数据结构比较简单,里面的很多方法,都是和顺序表差不多,不懂得铁铁可以去看一下我前面的博客

数据结构:顺序表-CSDN博客文章浏览阅读838次,点赞18次,收藏9次。数据是计算机科学中的基本概念,它代表了在计算机程序中处理的一切信息内容。https://blog.csdn.net/2302_78381559/article/details/137435691这边可能你还是不是很理解栈,我们可以试着做一道Leetcode的题,来感受一下栈

题的链接

20. 有效的括号 - 力扣(LeetCode)icon-default.png?t=N7T8https://leetcode.cn/problems/valid-parentheses/description/

我对这道题理解之后写的一篇博客,供大家观看

20. 有效的括号 - 力扣(LeetCode)icon-default.png?t=N7T8https://leetcode.cn/problems/valid-parentheses/description/

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

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

相关文章

yarn : 无法加载文件 C:\app\nodejs\node_global\yarn.ps1,因为在此系统上禁止运行脚本

系统运行yarn命令报错 解决办法&#xff1a; 一、点击电脑右下角的开始&#xff0c;菜单出来后&#xff0c;直接按键盘输入powerShell搜索&#xff0c;然后右键以管理员身份运行 二、以管理员运行后&#xff0c;会出现下面命令窗口 在窗口上执行&#xff1a;set-ExecutionPoli…

羊大师分析,羊奶健康生活的营养源泉

羊大师分析&#xff0c;羊奶健康生活的营养源泉 羊奶&#xff0c;作为一种古老的饮品&#xff0c;近年来因其独特的营养价值和健康益处而备受关注。今天&#xff0c;羊大师就来探讨一下羊奶与健康之间的紧密联系。 羊奶富含蛋白质、脂肪、维生素和矿物质等多种营养成分。羊奶…

哪家PMP培训机构比较优秀?

不同的培训机构在服务、收费和师资上会有一些差异&#xff0c;但基本都差不多。老师的授课方式对学习兴趣很重要&#xff0c;价格在3000-4000左右&#xff0c;选择中间价位比较好。服务也很关键&#xff0c;有的机构提供代报名和PDU等额外服务。关于机构排名的文章可以参考&…

InnoDB 事务处理机制

文章目录 前言1. 事务处理挑战1.1 事务机制处理的问题1.2 并发事务带来的问题 2. InnodDB 和 ACID 模型2.1 Innodb Buffer Pool2.2 Redo log2.3 Undo log2.4 应用案例 3. 隔离级别和锁机制3.1 事务隔离级别3.1.1 READ UNCOMMITTED3.1.2 READ COMMITTED3.1.3 REPEATABLE READ3.1…

CCF20181201——小明上学

CCF20181201——小明上学 代码如下&#xff1a; #include<bits/stdc.h> using namespace std; int main() {int r,y,g,n,k[101],t[101],sum0;cin>>r>>y>>g;cin>>n; for(int i0;i<n;i){cin>>k[i]>>t[i];if(k[i]0||k[i]1)sumt[i];…

Linux中的计划任务(crontab)详解

&#x1f407;明明跟你说过&#xff1a;个人主页 &#x1f3c5;个人专栏&#xff1a;《Linux &#xff1a;从菜鸟到飞鸟的逆袭》&#x1f3c5; &#x1f516;行路有良友&#xff0c;便是天堂&#x1f516; 目录 一、前言 1、Linux的起源与发展 2、什么是计划任务&#xf…

Xilinx RAM IP核的使用及注意事项

对于RAM IP核(Block Memory Generator核)的使用以及界面的配置介绍&#xff0c;文章RAM的使用介绍进行了较详细的说明&#xff0c;本文对RAM IP核使用中一些注意的地方加以说明。 文章目录 三种RAM的区别单端口RAM(Single-port RAM)简单双端口RAM(Simple Dual-port RAM)真双端…

供应链投毒预警 | 开源供应链投毒202404月报发布(含投毒案例分析)

概述 悬镜供应链安全情报中心通过持续监测全网主流开源软件仓库&#xff0c;结合程序动静态分析方式对潜在风险的开源组件包进行动态跟踪和捕获&#xff0c;发现大量的开源组件恶意包投毒攻击事件。在2024年4月份&#xff0c;悬镜供应链安全情报中心在NPM官方仓库&#xff08;…

翻译《The Old New Thing》- Stupid debugger tricks: Calling functions and methods

Stupid debugger tricks: Calling functions and methods - The Old New Thing (microsoft.com)https://devblogs.microsoft.com/oldnewthing/20070427-00/?p27083 Raymond Chen 2007年04月27日 一个比较笨的调试技巧&#xff1a;调用函数和方法 在过去&#xff0c;如果你想在…

css+html 爱心❤

效果 代码实现 html <div class"main"><div class"aixin"></div></div>css .main {transform: rotate(-45deg);}.aixin {height: 100px;width: 100px;background-color: red;margin: auto;margin-top: 200px;position: relativ…

给app引导页说goodbye吧,皮之不存,毛将焉附。

有几个原因导致大部分创业者选择不开发独立的移动应用程序&#xff08;App&#xff09;&#xff1a; 成本和资源&#xff1a;开发和维护一个独立的移动应用程序需要投入大量的时间、资金和人力资源。对于创业公司来说&#xff0c;他们可能没有足够的资源来支持这样的开发和维护…

大数据性能测试怎么做?看完这篇终于懂了!

大数据性能测试的目的 1.大数据组件的性能回归&#xff0c;在版本升级的时候&#xff0c;进行新旧版本的性能比对。 2.在新版本/新的生产环境发布之后获取性能基线&#xff0c;建立可度量的参考标准&#xff0c;为其他测试场景或者调优过程提供对比参考。 3.在众多的发行版本…

【好书推荐-第十六期】《 LangChain技术解密:构建大模型应用的全景指南》(Github 6800+示例!)

&#x1f60e; 作者介绍&#xff1a;我是程序员洲洲&#xff0c;一个热爱写作的非著名程序员。CSDN全栈优质领域创作者、华为云博客社区云享专家、阿里云博客社区专家博主、前后端开发、人工智能研究生。公众号&#xff1a;洲与AI。 &#x1f388; 本文专栏&#xff1a;本文收录…

【Flask 系统教程 6】进阶操作

Flask操作cookie 在 Flask 中操作 Cookie 是相对简单的。Cookie 是一种存储在用户计算机上的小型数据片段&#xff0c;由服务器发送到用户浏览器&#xff0c;然后在每次请求时由浏览器发送回服务器。在 Flask 中&#xff0c;你可以使用 request 对象来读取 cookie&#xff0c;…

【Maven】简介_下载安装

1.maven简介 项目管理工具项目对象模型 project object model (POM) 一个项目&#xff1a;清理、编译、测试、打包、发布、部署 1.1 为什么需要使用maven 组装机和品牌机的概念IDE &#xff08;集成开发环境&#xff09;不是万能的依赖大量的手工操作&#xff0c;编译、测试、…

npm install [Error]

npm install 依赖的时候报错 依赖版本问题的冲突&#xff0c;忽视即可 使用 npm install --legacy-peer-deps

个人写表格辅助软件

该软件作用 Excel 的辅助&#xff0c;可以执行excel不方便的操作&#xff0c;从excel复制数据到软件进行操作又复制回Excel。 下载软件地址 ,大小&#xff1a;65kb 点击下载 完整UI 列操作 右键单击列名弹出菜单 单元格操作 右键单击单元格弹出菜单 导航模式 每个操作都可以…

如何给实拍添加旋转模糊效果?视频模糊特效PR模板剪辑素材

PR特效模板&#xff0c;高级旋转模糊效果视频模板剪辑素材。 特征&#xff1a; After Effects 2019及以上兼容项目。 Premiere Pro 2021及以上兼容项目。 可用分辨率&#xff08;4K–HD–方形–移动&#xff09;。 不需要插件。 包括教程。 免费下载&#xff1a;https://prmu…

什么是电表智能抄表?

1.什么叫电表智能抄表 电表智能抄表&#xff0c;又被称为全自动读表系统&#xff0c;是一种利用通信网技术&#xff0c;如wifi网络、物联网技术或通信网络&#xff0c;全自动收集解决电能消耗数据信息的软件。与传统手动式抄水表方式相比&#xff0c;它大大提高了高效率&#…

Hadoop大数据应用技术复习题分析

文章目录 复习一一. 单选题二. 多选题三. 填空题 复习三一. 单选题 复习一 一. 单选题 (单选题)压缩速度由大到小snappy、LZO、gzip、bzip2&#xff0c;压缩比最大的是 A. snappy B. LZO C. gzip D. zip2 正确答案: D:zip2; 答案解析&#xff1a; 压缩率&#xff1a;zip2>…