数据结构数组栈的实现
Hello,今天我们来实现一下数组栈,学完这个我们又更进一步了。
一、栈
栈的概念
栈是一种特殊的线性表,它只允许在固定的一端进行插入和删除元素的操作。
进行数据的插入和删除只在栈顶实现,另一端就是栈底。
栈的元素是后进先出。
压栈:栈的数据进入就是压栈
出栈:栈的数据删除就叫出栈
我们画一个原理图让大家比较好理解一下。
这一过程叫做pop出栈
我们上述的过程都是在栈顶实现出栈入栈,并不能像顺序表和单链表那样从任意位置删除和增加,但这就是栈的性质,我们后面会讲它的作用。
实现栈我们可以用链表产生节点的方式链接他们,但是也可以用数组下标访问的方式,类似顺序表这样的方法
那这两个方法哪个好呢,我们来比较一下。
因为栈的性质我们不得从栈顶出栈和入栈,如果我们实现的时候是链表的方式,那必然会存在一个问题,就是我们的时间复杂度是O(N)我们需要遍历一遍数组,这样的话栈好像变得“土”,所以用数组的方式更快的提高效率,
二、栈的定义
typedef int StackDataType;
#define N 100
struct Stack
{StackDataType arry[N];StackDataType top;
};
这是静态栈,在顺序表的时候我们就讲过静态栈存在缺点,最大的缺点就是不能开辟空间,100个最多只能存100个数据,如果我只使用10个int空间就存在浪费了,如果我要存储1000个数据,我们的空间又不够了,这就会造成一系列问题,所以我们改一下,变成动态栈,我们来实现一下吧。
typedef int StackDataType;
typedef struct Stack
{StackDataType* arry;int top;int capacity;
}Stack;
有了结构体还是老样子,我们来实现一下接口函数,开整!
初始化栈
void StackInit(Stack* pst)
{assert(pst);pst->arry = NULL;pst->capacity = pst->top = 0;
}
初始化栈这个大家肯定会了。
销毁
void StackDestory(Stack* pst)
{assert(pst);free(pst->arry);pst->capacity = pst->top = 0;}
判断栈是否为空
bool StackEmpty(Stack* pst)
{assert(pst);return pst->top == 0;
}
现在我们要实现一个入栈的方法,入栈的时候我们需要检查一下我们的内存空间是不是满了,和顺序表一样的道理,如果满了我们就需要扩容。所以在入栈的时候需要判断一下它空间有没有满。
void StackPush(Stack* pst, StackDataType x)
{assert(pst);if (pst->capacity == pst->top){int newcapacity = pst->capacity == 0 ? 4 : pst->capacity * 2;StackDataType* tmp = (StackDataType*)realloc(pst->arry, sizeof(int) * newcapacity);if (tmp == NULL){printf("realloc fail\n");exit(-1);}pst->arry = tmp;pst->capacity = newcapacity;}pst->arry[pst->top - 1] = x;pst->top++;}
这和我们顺序表的尾插一摸一样,现在看大家肯定觉得简单很多了。
有了入栈,那就有出栈。
void StackPop(Stack* pst)
{assert(pst);if (pst->top > 0){pst->top--;}
}
因为我们上面写了一个判断该数是不是为空我们也可以写成
void StackPop(Stack* pst)
{assert(pst);if (!StackEmpty(pst)){pst->top--;}
}
返回栈顶数据
StackDataType StackTop(Stack* pst)
{assert(pst);return pst->arry[pst->top - 1];
}
统计栈里有多少数
int StackSize(Stack* pst)
{assert(pst);return pst->top;
}
完整代码
#pragma once#include<stdio.h>
#include<assert.h>
#include<stdlib.h>
#include<stdbool.h>
//typedef int StackDataType;
//#define N 100
//struct Stack
//{
// StackDataType arry[N];
// StackDataType top;
//};typedef int StackDataType;
typedef struct Stack
{StackDataType* arry;int top;int capacity;
}Stack;void StackInit(Stack* pst);void StackDestory(Stack* pst);bool StackEmpty(Stack* pst);void StackPush(Stack* pst, StackDataType x);void StackPop(Stack* pst);StackDataType StackTop(Stack* pst);int StackSize(Stack* pst);
#include"Stack.h"void StackInit(Stack* pst)
{assert(pst);pst->arry = NULL;pst->capacity = pst->top = 0;
}void StackDestory(Stack* pst)
{assert(pst);free(pst->arry);pst->capacity = pst->top = 0;}bool StackEmpty(Stack* pst)
{assert(pst);return pst->top == 0;
}void StackPush(Stack* pst, StackDataType x)
{assert(pst);if (pst->capacity == pst->top){int newcapacity = pst->capacity == 0 ? 4 : pst->capacity * 2;StackDataType* tmp = (StackDataType*)realloc(pst->arry, sizeof(int) * newcapacity);if (tmp == NULL){printf("realloc fail\n");exit(-1);}pst->arry = tmp;pst->capacity = newcapacity;}pst->arry[pst->top - 1] = x;pst->top++;}void StackPop(Stack* pst)
{assert(pst);if (pst->top > 0){pst->top--;}
}void StackPop(Stack* pst)
{assert(pst);if (!StackEmpty(pst)){pst->top--;}
}StackDataType StackTop(Stack* pst)
{assert(pst);return pst->arry[pst->top - 1];
}int StackSize(Stack* pst)
{assert(pst);return pst->top;
}
栈的应用也有很多,后面会分享给大家,我们下次再见
相关文章:

数据结构数组栈的实现
Hello,今天我们来实现一下数组栈,学完这个我们又更进一步了。 一、栈 栈的概念 栈是一种特殊的线性表,它只允许在固定的一端进行插入和删除元素的操作。 进行数据的插入和删除只在栈顶实现,另一端就是栈底。 栈的元素是后进先出。…...

成集云 | 抖店连接器客户静默下单催付数据同步钉钉 | 解决方案
源系统成集云目标系统 方案介绍 随着各品牌全渠道铺货,主播在平台上直播时客户下了订单后不能及时付款,第一时间客户收不到提醒,不仅造成了客户付款率下降,更大量消耗了企业的人力成本和经济。而成集云与钉钉深度合作࿰…...

【算法专题突破】双指针 - 复写零(2)
目录 1. 题目解析 2. 算法原理 3. 代码编写 写在最后: 1. 题目解析 题目链接:1089. 复写零 - 力扣(Leetcode) 我先来读题, 题目的意思非常的简单,其实就是, 遇到 0 就复制一个写进数组&a…...

【Java从0到1学习】11 Java集合框架
1. Collection 1.1 Java类中集合的关系图 1.2 集合类概述 在程序中可以通过数组来保存多个对象,但在某些情况下开发人员无法预先确定需要保存对象的个数,此时数组将不再适用,因为数组的长度不可变。例如,要保存一个学校的学生信…...

uniapp使用uni.chooseLocation()打开地图选择位置
使用uni.chooseLocation()打开地址选择位置: 在Uniapp源码视图进行设置 添加这个属性:"requiredPrivateInfos":["chooseLocation"] </template><view class"location_box"><view class"locatio…...

学习笔记|课后练习解答|电磁炉LED实战|逻辑运算|STC32G单片机视频开发教程(冲哥)|第八集(下):课后练习分析与解答
文章目录 课后练习解答需求分解增加KEY3控制代码如下: 第一版代码问题分析Tips:STC-ISP的设置 Tips:定时器实现完整电磁炉显示功能的代码测试流程 总结 课后练习解答 增加按键3,按下后表示启动,选择的对应的功能的LED…...

前端高频面试题 js中堆和栈的区别和浏览器的垃圾回收机制
一、 栈(stack)和 堆(heap) 栈(stack):是栈内存的简称,栈是自动分配相对固定大小的内存空间,并由系统自动释放,栈数据结构遵循FILO(first in last out)先进后出的原则,较为经典的就是乒乓球盒结…...

自然语言处理:大语言模型入门介绍
自然语言处理:大语言模型入门介绍 语言模型的历史演进大语言模型基础知识预训练Pre-traning微调Fine-Tuning指令微调Instruction Tuning对齐微调Alignment Tuning 提示Prompt上下文学习In-context Learning思维链Chain-of-thought提示开发(调用ChatGPT的…...

使用秘籍|如何实现图数据库 NebulaGraph 的高效建模、快速导入、性能优化
本文整理自 NebulaGraph PD 方扬在「NebulaGraph x KubeBlocks」meetup 上的演讲,主要包括以下内容: NebulaGraph 3.x 发展历程NebulaGraph 最佳实践 建模篇导入篇查询篇 NebulaGraph 3.x 的发展历程 NebulaGraph 自 2019 年 5 月开源发布第一个 alp…...

对于pycharm 运行的时候不在cmd中运行,而是在python控制台运行的情况,如何处理?
对于pycharm 运行的时候不在cmd中运行,而是在python控制台运行的情况,如何处理? 比如,你在运行你的代码的时候 它总在python控制台运行,十分难受 解决方法 在pycharm中设置下即可,很简单 选择运行点击…...

Spring MVC 二 :基于xml配置
创建一个基于xml配置的Spring MVC项目。 Idea创建新项目,pom文件引入依赖: <dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>5.2.12.RELEASE</version>…...

springboot aop方式实现接口入参校验
一、前言 在实际开发项目中,我们常常需要对接口入参进行校验,如果直接在业务代码中进行校验,则会显得代码非常冗余,也不够优雅,那么我们可以使用aop的方式校验,这样则会显得更优雅。 二、如何实现…...

解决git上传远程仓库时的大文件提交
在git中超过100M的文件会上传失败,而当一个文件超过50M时会给你警告,如下 warning: File XXXXXX is 51.42 MB; this is larger than GitHubs recommended maximum file size of 50.00 MB 解决这种问题,首先在项目的.git文件夹中找到.gitigno…...

HTML学习笔记02
HTML笔记02 页面结构分析 元素名描述header标题头部区域的内容(用于页面或页面中的一块区域)footer标记脚部区域的内容(用于整个页面或页面的一块区域)sectionWeb页面中的一块独立区域article独立的文章内容aside相关内容或应用…...

<C++> 内存管理
1.C/C内存分布 让我们先来看看下面这段代码 int globalVar 1; static int staticGlobalVar 1; void Test() {static int staticVar 1;int localVar 1;int num1[10] {1, 2, 3, 4};char char2[] "abcd";char *pChar3 "abcd";int *ptr1 (int *) mal…...

【Java】ByteBuffer类的arrayOffset方法详解+示例
arrayOffset功能详解;arrayOffset在position等于0和非0两种场景下的demo。使用类java.nio.ByteBuffer中的arrayOffset()方法可以获得这个缓冲区的第一个元素在底层支持(backing)数组中的偏移量。 如果这个buffer底层是由数组支持的,那么buffer的postion p对应于数组的index…...

【C++】C++ 引用详解 ⑤ ( 函数 “ 引用类型返回值 “ 当左值被赋值 )
文章目录 一、函数返回值不能是 " 局部变量 " 的引用或指针1、函数返回值常用用法2、分析函数 " 普通返回值 " 做左值的情况3、分析函数 " 引用返回值 " 做左值的情况 函数返回值 能作为 左值 , 是很重要的概念 , 这是实现 " 链式编程 &quo…...

Git,分布式版本控制工具
1.为常用指令配置别名(可选) 打开用户目录,创建.bashrc文件 (touch ~/.bashrc) 2.往其输入内容 #用于输出git提交日志 alias git-loggit log --prettyoneline --all --graph --abbrev-commit #用于输出当前目录所有文…...

LeetCode 面试题 02.02. 返回倒数第 k 个节点
文章目录 一、题目二、C# 题解 一、题目 实现一种算法,找出单向链表中倒数第 k 个节点。返回该节点的值。 注意:本题相对原题稍作改动 点击此处跳转题目。 示例: 输入: 1->2->3->4->5 和 k 2 输出: 4 说…...

SpeedBI数据可视化工具:丰富图表,提高报表易读性
数据可视化工具一大作用就是能把复杂数据可视化、直观化,更容易看懂,也就更容易实现以数据驱动业务管理升级,因此一般的数据可视化工具都会提供大量图形化的数据可视化图表,以提高报表的易懂性,更好地服务企业运营决策…...

编写Dockerfile制作Web应用系统nginx镜像
文章目录 题目要求:一、创建文档,编写Dockerfile文件可以将harbor仓库去启动先起来 二、运行Dockerfile,构建nginx镜像三、推送导私有仓库,也就是我们的harbor仓库 题目要求: 编写Dockerfile制作Web应用系统nginx镜像…...

记录一次微服务连接Nacos异常-errorMsg: Illegal character in authority at index 7:
组件信息 Nacos 2.2.3 SpringCloud微服务 部署环境:centerOS 部署方式:k8s 前言 nacos开启鉴权,nacos地址通过变量方式传入服务中 PropsUtil.setProperty(props, "spring.cloud.nacos.discovery.server-addr", "${NACO…...

【Java】反射 之 调用构造方法
调用构造方法 我们通常使用new操作符创建新的实例: Person p new Person();如果通过反射来创建新的实例,可以调用Class提供的newInstance()方法: Person p Person.class.newInstance();调用Class.newInstance()的局限是,它只…...

Hightopo 使用心得(6)- 3D场景环境配置(天空球,雾化,辉光,景深)
在前一篇文章《Hightopo 使用心得(5)- 动画的实现》中,我们将一个直升机模型放到了3D场景中。同时,还利用动画实现了让该直升机围绕山体巡逻。在这篇文章中,我们将对上一篇的场景进行一些环境上的丰富与美化。让场景更…...

【Python PEP 笔记】201 - 同步迭代 / zip() 函数的使用方法
原文地址:https://peps.python.org/pep-0201/ PDF 地址: 什么是同步迭代 同步迭代就是用 for 一次循环多个序列。 类似于这样的东西: arr1 [1, 2, 3, 4] arr2 [a, b, c, d] for a, b in arr1, arr2:print(a, b)使用 map 实现 for a, b …...

远程控制:用了向日葵控控A2后,我买了BliKVM v4
远程控制电脑的场景很多,比如把办公室电脑的文件发到家里电脑上,但是办公室电脑旁边没人。比如当生产力用的电脑一般都比较重,不可能随时带在身边,偶尔远程操作一下也是很有必要的。比如你的设备在工况恶劣的环境中,你…...

基于swing的火车站订票系统java jsp车票购票管理mysql源代码
本项目为前几天收费帮学妹做的一个项目,Java EE JSP项目,在工作环境中基本使用不到,但是很多学校把这个当作编程入门的项目来做,故分享出本项目供初学者参考。 一、项目描述 基于swing的火车站订票系统 系统有2权限:…...

MAVEN利器:一文带你了解IDEA中如何使用Maven
前言: 强大的构建工具——Maven。作为Java生态系统中的重要组成部分,Maven为开发人员提供了一种简单而高效的方式来构建、管理和发布Java项目。无论是小型项目还是大型企业级应用,Maven都能帮助开发人员轻松处理依赖管理、编译、测试和部署等…...

R语言15-R语言中的列的分裂与合并长宽数据转换
列的分裂与合并 列的分裂: 使用 separate() 函数将一个包含多个值的列分裂成多个列。 install.packages("tidyr") # 安装 tidyr 包(如果尚未安装) library(tidyr)data <- data %>%separate(col_name, into c("part1…...

使用Pytorch和OpenCV实现视频人脸替换
“DeepFaceLab”项目已经发布了很长时间了,作为研究的目的,本文将介绍他的原理,并使用Pytorch和OpenCV创建一个简化版本。 本文将分成3个部分,第一部分从两个视频中提取人脸并构建标准人脸数据集。第二部分使用数据集与神经网络一…...