栈:概念与实现
1.概念

- 压栈:栈的插入操作叫做进栈/压栈/入栈,入数据在栈顶。
- 出栈:栈的删除操作叫做出栈,出数据也在栈顶。
- 栈的元素遵循后进先出LIFO(Last In First Out)的原则。后面进来的数据先出去
2.栈的实现
- 三种实现方法,数组,单链表,双链表
- 这里我们采用数组,因为数组的缓存利用率高,而且基于结构更加容易访问,异地扩容的时候会消耗时间,但是这个开销对于栈来说很小。
- 双链表虽然很方便,有前后指针但是要多维护一个指针,同时也会增加空间的浪费,那还不然单链表。
- 分为三个部分,Stack.h 和 Stack.c 还有test.c;这里只说Stack.c的核心部分
- 栈的基本结构
typedef struct Stack
{STDataType* pa;//数组int top;//栈顶int capacity;//有效个数
}ST;
2.1初始化,销毁
- 这里的关键问题点在于,初始化为0(下标位置) 的时候你要不要放入数据?,可是初始化本来就不用放数据
- 在top位置放数据的时候,需要 top++指向下一个地方,为下一个准备放数据

//初始化
void STInit(ST* ps)
{assert(ps);ps->pa = NULL;ps->top = ps->capacity = 0;
}//销毁
void STDestroy(ST* ps)
{assert(ps);ps->top = ps->capacity = 0;free(ps);//删除元素不行销毁,因为数组的空间是一次性开辟的ps = NULL;
}
2.2压栈(push),删除(pop)
- 压栈就是插入到数组后面,再插入之前需要看看有没有空间,就在结构体里面的ps->size插入就行,假如是2,刚好放到数组下标2位置处
- 防止数据丢失不要直接空间给ps->pa,而是先拿个tmp的临时空间来装着。
- 如果还是不太熟悉,看看我的单链表这篇文章更加详细
//压栈
void STPush(ST* ps,STDataType x)
{assert(ps);//为NULL,你插入个屁if (ps->top == ps->capacity)//相等说明没空间{int new = ps->capacity == 0 ? 4 : ps->capacity * 2;STDataType* tmp = (STDataType*)realloc(ps->pa,sizeof(STDataType) * new);//假如pa 为NULL则 和malloc一样if (tmp == NULL){perror("STPush()::realloc()");return;}//不要让ps->pa 直接去接收新空间的地址ps->pa = tmp;ps->capacity = new;}ps->pa[ps->top] = x;ps->top++;
}
- pop,只有一行可不可不调用函数,删除数据呢?不行;因为没有断言检查了
- 这里直接有效个数,top-- 就行
- 入栈顺序不代表出栈顺寻,可以边进变出,或者入3个在途中出两个
- 进栈顺序只有一种,出栈顺序有很多种

//删除
void STPop(ST* ps)
{assert(ps);assert(ps->top);//为0 不能删了ps->top--;
}
2.3有效个数(size),栈顶数据(top),栈是否为NULL(empty)
//有效个数
int STSize(ST* ps)
{assert(ps);return ps->top;
}
//取栈顶元素
STDataType STTop(ST* ps)
{assert(ps);assert(ps->top > 0);//不大于0,你还怎么取栈顶元素return ps->pa[ps->top - 1];//因为是有效元素的前一个
}
bool STEmpty(ST* ps)
{assert(ps);return ps->top == 0;//表达式为真返回1,假返回0
}
2.4完整代码
2.4.1Stack.h
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <assert.h>
#include <stdlib.h>
#include <stdbool.h>
//可任意更换类型
typedef int STDataType;
typedef struct Stack
{STDataType* pa;//数组int top;//栈顶int capacity;//有效个数
}ST;//初始化和销毁
void STInit(ST* ps);
void STDestroy(ST* ps);//压栈和出栈
void STPush(ST* ps, STDataType x);
void STPop(ST* ps);//栈顶元素
STDataType STTop(ST* ps);//有效个数
int STSize(ST* ps);//判断是否为NULL
bool STEmpty(ST* ps);
2.4.2Stack.c
#include "Stack.h"
//初始化
void STInit(ST* ps)
{assert(ps);ps->pa = NULL;ps->top = ps->capacity = 0;
}//压栈
void STPush(ST* ps,STDataType x)
{assert(ps);//为NULL,你插入个屁if (ps->top == ps->capacity)//相等说明没空间{int new = ps->capacity == 0 ? 4 : ps->capacity * 2;STDataType* tmp = (STDataType*)realloc(ps->pa,sizeof(STDataType) * new);//假如pa 为NULL则 和malloc一样if (tmp == NULL){perror("STPush()::realloc()");return;}//不要让ps->pa 直接去接收新空间的地址ps->pa = tmp;ps->capacity = new;}ps->pa[ps->top] = x;ps->top++;
}
//删除
void STPop(ST* ps)
{assert(ps);assert(ps->top);//为0 不能删了ps->top--;
}
//取栈顶元素
STDataType STTop(ST* ps)
{assert(ps);assert(ps->top > 0);//不大于0,你还怎么取栈顶元素return ps->pa[ps->top - 1];//因为是有效元素的后一个
}
//销毁
void STDestroy(ST* ps)
{assert(ps);ps->top = ps->capacity = 0;free(ps);//删除元素不行销毁,因为数组的空间是一次性开辟的ps = NULL;
}
//有效个数
int STSize(ST* ps)
{assert(ps);return ps->top;
}
//判空
bool STEmpty(ST* ps)
{assert(ps);return ps->top == 0;//表达式为真返回1,假返回0
}
2.4.3test.c
#include "Stack.h"
void STTest()
{ST s;STInit(&s);//压栈STPush(&s, 1);STPush(&s, 2);STPop(&s);//边进边出STPush(&s, 3);STPush(&s, 4);//printf("%d\n", STTop(&s));//STPop(&s);//printf("%d\n", STTop(&s));//STPop(&s); //STPop(&s);//printf("%d\n", STTop(&s));//STPop(&s);//STPop(&s);while (!STEmpty(&s))//返回假(0),返回的结果为假 就运行{printf("%d ", STTop(&s));STPop(&s);}
}
int main()
{STTest();return 0;
}
总结:
- 栈的整体不算难,学会理解后要独立完成联系
- 栈也是有应用场景的,至于为什么有这些结构体,都是前人发明出来的,学习知识有延后性;意思就是说从小到大不是学习的所有知识都是有用的,但是也要学
- 这个时候就体现了,笔记和博客的重要性;方便后续复习,知识多了肯定记不住
相关文章:
栈:概念与实现
1.概念 压栈:栈的插入操作叫做进栈/压栈/入栈,入数据在栈顶。出栈:栈的删除操作叫做出栈,出数据也在栈顶。栈的元素遵循后进先出LIFO(Last In First Out)的原则。后面进来的数据先出去 2.栈的实现 三种实现方法,数组…...
【Linux】查找服务器中某个文件的完整路径
方法一: 使用 -wholename 来搜索路径: find / -wholename */esm/data.py这个命令会搜索与 */esm/data.py 完全匹配的路径,其中 * 代表任意数量的任意字符。这应该会找到位于任何目录下的 esm/data.py 文件。 可以限定在某个目录下查找&…...
windows server 2019 安装 docker环境
一、根据官方说明进行安装 , 看起来过程相当简单, 但问题还是有的 准备 Windows 操作系统容器 | Microsoft Learn // 一个 powershell 脚本,该脚本配置环境以启用与容器相关的 OS 功能并安装 Docker 运行时。 Invoke-WebRequest -UseBasicParsing "https://r…...
【Linux】探索 Linux du 命令:管理磁盘空间的利器
给我一个拥抱 给我肩膀靠靠 你真的不需要 对我那么好 思念就像毒药 让人受不了的煎熬 我会迷恋上瘾赖在你怀抱 🎵 陶钰玉《深夜地下铁》 在 Linux 系统管理中,磁盘空间管理是一项基础而重要的任务。du(disk usage&#…...
Service 和 Ingress
文章目录 Service 和 IngressServiceEndpointservice 的定义代理集群外部服务反向代理外部域名Service 常用类型 IngressIngress-nginx安装使用 Service 和 Ingress service 和 ingress 是kubernetes 中用来转发网络请求的两个服务,两个服务用处不同,se…...
C++(类和对象—封装)
C面向对象的三大特性 封装 继承 多态 C认为万事万物皆为对象,对象上有其属性和行为 什么是封装? 封装是C面向对象三大特性之一 封装的意义: 将属性和行为作为一个整体,表现生活中的事物 将属性和行为加以权限控制封装意义一: …...
如何训练一个大模型:LoRA篇
目录 写在前面 一、LoRA算法原理 1.设计思想 2.具体实现 二、peft库 三、完整的训练代码 四、总结 写在前面 现在有很多开源的大模型,他们一般都是通用的,这就意味着这些开源大模型在特定任务上可能力不从心。为了适应我们的下游任务,…...
Spring Cloud学习笔记(Nacos):基础和项目启动
这是本人学习的总结,主要学习资料如下 - 马士兵教育 1、基础和版本选择2、启动项目2.1、源码启动项目2.2、命令行启动 1、基础和版本选择 Nacos是用于服务发现和注册,是Spring Cloud Alibaba的核心模块。 根据文档,Spring Cloud Alibaba的版…...
音频提取特征
目录 音频提取特征 音频切割 依赖项: pip install librosa pip install transformers 音频提取特征 import librosa import numpy as np import torch from transformers import Wav2Vec2Processorprocessor Wav2Vec2Processor.from_pretrained("faceboo…...
AJAX前端与后端交互技术知识点以及案例
Promise promise对象用于表示一个异步操作的最终完成(或失败)及其结果值 好处: 逻辑更清晰了解axios函数内部运作机制成功和失败状态,可以关联对应处理程序能解决回调函数地狱问题 /*** 目标:使用Promise管理异步任…...
[AutoSar]BSW_Diagnostic_003 ReadDataByIdentifier(0x22)介绍
目录 关键词平台说明背景一、请求格式二、常用DID三、响应格式四、NRC五、case 关键词 嵌入式、C语言、autosar、OS、BSW、UDS、diagnostic 平台说明 项目ValueOSautosar OSautosar厂商vector , EB芯片厂商TI 英飞凌编程语言C,C编译器HighTec (GCC)au…...
买卖股票的最佳时机 II(LeetCode 122)
❤️❤️❤️ 欢迎来到我的博客。希望您能在这里找到既有价值又有趣的内容,和我一起探索、学习和成长。欢迎评论区畅所欲言、享受知识的乐趣! 推荐:数据分析螺丝钉的首页 格物致知 终身学习 期待您的关注 导航: LeetCode解锁100…...
Spring Boot:让微服务开发像搭积木一样简单!
带你一探 Spring Boot 的自动配置和 Starter POMs 的神奇之处,展示如何通过几个简单的步骤就能让你的微服务应用在云端翱翔! 文章目录 1. 引言1.1 简述Spring框架的起源与重要性1.2 阐述文章目的:深入解析Spring核心功能与应用实践2. 背景介绍…...
WordPress 、Typecho 站点的 MySQL/MariaDB 数据库优化
今天明月给大家分享一下 WordPress 、Typecho 站点的 MySQL/MariaDB 数据库优化,无论你的站点采用是 WordPress 还是 Typecho,都要用到 MySQL/MariaDB 数据库,我们以 MySQL 为主(MariaDB 其实跟 MySQL 基本没啥大的区别࿰…...
==与===的区别
在许多编程语言和脚本语言中,包括 JavaScript 和 PHP 等, 和 是用于比较值的操作符。 “” 是相等运算符,用于比较两个值是否相等。它比较值时会进行类型转换,如果两个值在类型转换后相等,那么它们就被认为是相等的。…...
什么是ACID及基本实现的示例
什么是ACID特性 ACID 是一个缩写词,代表数据库事务的四个关键特性:原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation)、持久性(Durability)。这些…...
【启明智显技术分享】SSD202核心板Rootfs下如何烧录mac地址
提示:作为Espressif(乐鑫科技)大中华区合作伙伴及sigmastar(厦门星宸)VAD合作伙伴,我们不仅用心整理了你在开发过程中可能会遇到的问题以及快速上手的简明教程供开发小伙伴参考。同时也用心整理了乐鑫及星宸…...
springboot3 集成spring-authorization-server (一 基础篇)
官方文档 Spring Authorization Server 环境介绍 java:17 SpringBoot:3.2.0 SpringCloud:2023.0.0 引入maven配置 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter…...
AVL树!
文章目录 1.AVL树的概念2.AVL树的插入和旋转3.AVL树的旋转3.1旋转的底层:3.2 右旋转3.3 左旋转3.4 双旋 4.AVL树的底层 1.AVL树的概念 当向二叉搜索树中插入新结点后,如果能保证每个结点的左右子树高度之差的绝对值不超过1(需要对树中的结点进行调整)&a…...
知识付费系统怎么安装教程,教师课堂教学该掌握哪些表达技巧?
课堂教学语言表达是教学艺术的一个基本且重要的组成部分。教师向学生传道、授业、解惑以及师生之间信息的传递和情感的交流,都离不开运用教学语言这一有力的工具,在课堂上,教师通过情趣盎然的表述,鞭辟入里的分析,恰到…...
uniapp 对接腾讯云IM群组成员管理(增删改查)
UniApp 实战:腾讯云IM群组成员管理(增删改查) 一、前言 在社交类App开发中,群组成员管理是核心功能之一。本文将基于UniApp框架,结合腾讯云IM SDK,详细讲解如何实现群组成员的增删改查全流程。 权限校验…...
挑战杯推荐项目
“人工智能”创意赛 - 智能艺术创作助手:借助大模型技术,开发能根据用户输入的主题、风格等要求,生成绘画、音乐、文学作品等多种形式艺术创作灵感或初稿的应用,帮助艺术家和创意爱好者激发创意、提高创作效率。 - 个性化梦境…...
Vue记事本应用实现教程
文章目录 1. 项目介绍2. 开发环境准备3. 设计应用界面4. 创建Vue实例和数据模型5. 实现记事本功能5.1 添加新记事项5.2 删除记事项5.3 清空所有记事 6. 添加样式7. 功能扩展:显示创建时间8. 功能扩展:记事项搜索9. 完整代码10. Vue知识点解析10.1 数据绑…...
C++实现分布式网络通信框架RPC(3)--rpc调用端
目录 一、前言 二、UserServiceRpc_Stub 三、 CallMethod方法的重写 头文件 实现 四、rpc调用端的调用 实现 五、 google::protobuf::RpcController *controller 头文件 实现 六、总结 一、前言 在前边的文章中,我们已经大致实现了rpc服务端的各项功能代…...
springboot 百货中心供应链管理系统小程序
一、前言 随着我国经济迅速发展,人们对手机的需求越来越大,各种手机软件也都在被广泛应用,但是对于手机进行数据信息管理,对于手机的各种软件也是备受用户的喜爱,百货中心供应链管理系统被用户普遍使用,为方…...
docker详细操作--未完待续
docker介绍 docker官网: Docker:加速容器应用程序开发 harbor官网:Harbor - Harbor 中文 使用docker加速器: Docker镜像极速下载服务 - 毫秒镜像 是什么 Docker 是一种开源的容器化平台,用于将应用程序及其依赖项(如库、运行时环…...
vue3 字体颜色设置的多种方式
在Vue 3中设置字体颜色可以通过多种方式实现,这取决于你是想在组件内部直接设置,还是在CSS/SCSS/LESS等样式文件中定义。以下是几种常见的方法: 1. 内联样式 你可以直接在模板中使用style绑定来设置字体颜色。 <template><div :s…...
第一篇:Agent2Agent (A2A) 协议——协作式人工智能的黎明
AI 领域的快速发展正在催生一个新时代,智能代理(agents)不再是孤立的个体,而是能够像一个数字团队一样协作。然而,当前 AI 生态系统的碎片化阻碍了这一愿景的实现,导致了“AI 巴别塔问题”——不同代理之间…...
【开发技术】.Net使用FFmpeg视频特定帧上绘制内容
目录 一、目的 二、解决方案 2.1 什么是FFmpeg 2.2 FFmpeg主要功能 2.3 使用Xabe.FFmpeg调用FFmpeg功能 2.4 使用 FFmpeg 的 drawbox 滤镜来绘制 ROI 三、总结 一、目的 当前市场上有很多目标检测智能识别的相关算法,当前调用一个医疗行业的AI识别算法后返回…...
Maven 概述、安装、配置、仓库、私服详解
目录 1、Maven 概述 1.1 Maven 的定义 1.2 Maven 解决的问题 1.3 Maven 的核心特性与优势 2、Maven 安装 2.1 下载 Maven 2.2 安装配置 Maven 2.3 测试安装 2.4 修改 Maven 本地仓库的默认路径 3、Maven 配置 3.1 配置本地仓库 3.2 配置 JDK 3.3 IDEA 配置本地 Ma…...
