当前位置: 首页 > news >正文

栈和队列详解(1)

目录

一、什么是栈?

二、创建一个我们自己的栈

1.前置准备

1.1需要的三个文件

 1.2结构体的创建和头文件的引用

 2.接口的实现

2.1初始化栈结构体

2.2尾插(压栈)

2.3栈存放的元素个数和判断栈是否为空

2.4获取栈顶元素

2.5出栈

2.6摧毁栈

2.7测试接口

三、所有代码

1.接口实现

2.栈的头文件

3.测试代码


一、什么是栈?

栈是计算机科学中的一种数据结构,它是一种线性结构,按照先进后出的原则进行存储和访问。栈通常也称作堆栈、堆叠或简称电梯。

在栈中,添加或删除元素只能在同一端进行,这一端被称为栈顶。当向栈顶添加一个元素时,我们称之为入栈;当从栈顶删除一个元素时,我们称之为出栈。对于栈的一项重要特性是,每次只能访问位于栈顶的元素,因此栈是不支持随机访问的数据结构。栈和我们之前所学习过的顺序表很相似,区别就在于,顺序表支持尾插尾删,头插头删,而栈只支持后进先出也就是只支持尾插尾删。它就像一个竖井,当队伍走进这个井后,要退出来也只能是队伍的末端最先退出。这里博主给大家画了张图,方便大家好理解。

二、创建一个我们自己的栈

1.前置准备

1.1需要的三个文件

在开始之前,我们最好创建三个文件,一个放栈函数的实现,一个用来测试栈函数,最后一个放栈函数的引用和头文件的引用,这样到时侯想要使用栈函数直接包这一个头文件即可。创建完之后,呈现出来的效果与下图差不多即可。

 1.2结构体的创建和头文件的引用

在进行操作之前,我们先在存放头文件和栈函数的文件中包几个常用的头文件,并且定义一下栈的结构体类型,栈只需要后进先出,也就是尾插尾删,那么使用数组亦或者使用链表实现难度是差不多的,这里我们使用数组实现。

使用数组实现要注意的便是,我们应该使用数组指针的形式实现,而不是单纯就一个数组,如果单纯就一个数组 ,就是一个静态的栈空间,而静态的栈空间在实际中几乎是没有任何用处的,这里我们要实现的是动态的。既然要实现的是动态的,那么我们应该想办法存储一下数组存放的元素个数,以及这个数组的容量大小,这样才能够判断出这个栈空间是否满了,从而根据需求扩大空间。因此我们创建的结构体应该要有一个数组指针,一个存放容量的大小,一个存放数组里面已经存放的元素个数。

最后呈现出来的差不多就是这个样子

#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
typedef int STDateType;
//到时修改类型时只用改这里的一个就可以,不需要一个个修改
//同样,这也是为了和单一的int作区分
typedef struct stack
{STDateType* stack;//栈空间int top;//已经存放的元素个数int capacity;//容量大小
}ST;//创建栈的结构体,并将它的名字自定义为ST

 2.接口的实现

2.1初始化栈结构体

初始化栈结构体,一共有三步,第一步是将栈空间的空间开辟好,第二步是初始化栈结构体的容量,最后一步初始化栈结构体中存放元素个数的变量。

void init_stack(ST* s1)
{assert(s1);//传过来的是一个指针,不应该是空指针,空指针无法操作,故断言s1->stack = (STDateType*)malloc(sizeof(STDateType)*4);//将栈空间初始化成只可以存放4个元素的空间if (s1->stack == NULL){perror("init_stack");//如果连基本的初始化都完成失败,就没有进行下去的必要了exit(-1);}s1->capacity = 4;//容量初始化成4s1->top = 0;//已经存放的元素个数初始化为0
}

2.2尾插(压栈)

压栈需要注意的一点便是,当栈满了的时候我们应该要考虑扩容

void push_stack(ST* s1, STDateType x)
{assert(s1);if (s1->capacity == s1->top)//空间满了,要扩容{int newcapacity = (s1->capacity) * 2;//扩容至原来的两倍s1->stack=(STDateType*)realloc(s1->stack, sizeof(STDateType)*newcapacity);if (s1->stack == NULL){perror("push_stack");exit(-1);//扩容失败也别玩了}s1->capacity = newcapacity;//扩容成功,容量改变}s1->stack[s1->top] = x;//压栈s1->top++;//压栈成功,存放的元素个数+1
}

2.3栈存放的元素个数和判断栈是否为空

可能有小伙伴不明白为什么又要设计这两个接口,因为这两个信息都可以直接通过栈的结构体获得,好像没什么作用啊。设计这两个接口并使用它们而不是直接通过结构体的内容来判断是因为,当我们的需求发生改变了,所创建的结构体可能也会跟着修改,可能提取的方式会发生一些改变。如果我们在使用栈的时候已经直接通过结构体的内容进行了多次的判断,那么我们要修改起来,要修改多次,很不方便,这样做的好处就是只用修改一次即可。

栈存放的元素个数

int size_stack(ST* s1)
{assert(s1);return s1->top;//返回元素个数
}

 判断栈是否为空

int empty_stack(ST* s1)
{assert(s1);return s1->top == 0;//当存放的元素个数等于0意味着空//为空返回1(真),不为空返回0(假)
}

2.4获取栈顶元素

需要注意的点是,首先栈不能够是空的,其次top是元素的个数,不是当前元素的下标,上一个才是对应元素的下标。举个例子,当栈有一个元素时,top就为1了,而1指的是数组的第二个元素。

STDateType sttop(ST* s1)
{assert(s1);assert(!empty_stack(s1));//栈不能为空,为空则出不了栈return s1->stack[s1->top - 1];
}

2.5出栈

出栈相当简单,直接将存放元素个数的内容-1即可,如此就不可能再次访问到它

void pop_stack(ST* s1)
{assert(s1);assert(!empty_stack(s1));//栈不能为空s1->top--;
}

2.6摧毁栈

这个很简单,没什么好说的,直接将栈结构体的空间释放掉,并将对应的内容归零即可。

void destory_stack(ST* s1)
{assert(s1);s1->capacity = 0;s1->top = 0;free(s1->stack);s1->stack = NULL;
}

2.7测试接口

测试代码:
 

#include"stack.h"
void test1()
{ST s1;init_stack(&s1);push_stack(&s1, 1);push_stack(&s1, 2);push_stack(&s1, 3);push_stack(&s1, 4);push_stack(&s1, 5);printf("%d\n", size_stack(&s1));while (!empty_stack(&s1)){printf("%d ", sttop(&s1));pop_stack(&s1);//边打印栈顶元素边出栈}destory_stack(&s1);//摧毁栈
}
int main()
{test1();
}

测试结果:

三、所有代码

1.接口实现

#include"stack.h"
void init_stack(ST* s1)
{assert(s1);//传过来的是一个指针,不应该是空指针,空指针无法操作,故断言s1->stack = (STDateType*)malloc(sizeof(STDateType)*4);//将栈空间初始化成只可以存放4个元素的空间if (s1->stack == NULL){perror("init_stack");//如果连基本的初始化都完成失败,就没有进行下去的必要了exit(-1);}s1->capacity = 4;//容量初始化成4s1->top = 0;//已经存放的元素个数初始化为0
}
void push_stack(ST* s1, STDateType x)
{assert(s1);if (s1->capacity == s1->top)//空间满了,要扩容{int newcapacity = (s1->capacity) * 2;//扩容至原来的两倍s1->stack=(STDateType*)realloc(s1->stack, sizeof(STDateType)*newcapacity);if (s1->stack == NULL){perror("push_stack");exit(-1);//扩容失败也别玩了}s1->capacity = newcapacity;//扩容成功,容量改变}s1->stack[s1->top] = x;//压栈s1->top++;//压栈成功,存放的元素个数+1
}
void pop_stack(ST* s1)
{assert(s1);assert(!empty_stack(s1));//栈不能为空s1->top--;
}
STDateType sttop(ST* s1)
{assert(s1);assert(!empty_stack(s1));//栈不能为空,为空则出不了栈return s1->stack[s1->top - 1];
}
int size_stack(ST* s1)
{assert(s1);return s1->top;//返回元素个数
}
int empty_stack(ST* s1)
{assert(s1);return s1->top == 0;//当存放的元素个数等于0意味着空//为空返回1(真),不为空返回0(假)
}
void destory_stack(ST* s1)
{assert(s1);s1->capacity = 0;s1->top = 0;free(s1->stack);s1->stack = NULL;
}

2.栈的头文件

#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
typedef int STDateType;
//到时修改类型时只用改这里的一个就可以,不需要一个个修改
//同样,这也是为了和单一的int作区分
typedef struct stack
{STDateType* stack;//栈空间int top;//已经存放的元素个数int capacity;//容量大小
}ST;//创建栈的结构体,并将它的名字自定义为ST
void init_stack(ST* s1);
void push_stack(ST* s1,STDateType x);
STDateType sttop(ST* s1);
int size_stack(ST*s1);
int empty_stack(ST* s1);
void destory_stack(ST* s1);
void pop_stack(ST* s1);

3.测试代码

#include"stack.h"
void test1()
{ST s1;init_stack(&s1);push_stack(&s1, 1);push_stack(&s1, 2);push_stack(&s1, 3);push_stack(&s1, 4);push_stack(&s1, 5);printf("%d\n", size_stack(&s1));while (!empty_stack(&s1)){printf("%d ", sttop(&s1));pop_stack(&s1);//边打印栈顶元素边出栈}destory_stack(&s1);//摧毁栈
}
int main()
{test1();
}

好了,栈就说完了,再来个三小时,博主爆肝一篇队列的。

感谢各位友友的来访,祝各位友友前程似锦O(∩_∩)O

相关文章:

栈和队列详解(1)

目录 一、什么是栈&#xff1f; 二、创建一个我们自己的栈 1.前置准备 1.1需要的三个文件 1.2结构体的创建和头文件的引用 2.接口的实现 2.1初始化栈结构体 2.2尾插(压栈) 2.3栈存放的元素个数和判断栈是否为空 2.4获取栈顶元素 2.5出栈 2.6摧毁栈 2.7测试接口 三、…...

苏州OV泛域名RSA加密算法https

RSA加密算法是一种非对称加密算法&#xff0c;它被广泛应用于信息安全领域。与对称加密算法不同&#xff0c;RSA加密算法使用了两个密钥&#xff0c;一个公钥和一个私钥。公钥可以公开&#xff0c;任何人都可以使用它加密信息&#xff0c;但只有私钥的持有者才能解密信息。RSA加…...

凯迪正大—微机继电保护校验仪

一、继电保护测试仪产品概述 KDJB-802继电保护测试仪是在参照电力部颁发的《微机型继电保护试验装置技术条件&#xff08;讨论稿&#xff09;》的基础上&#xff0c;听取用户意见&#xff0c;总结目前国内同类产品优缺点&#xff0c;充分使用现代的微电子技术和器件实现的一种新…...

Linux文件属性与权限管理(可读、可写、可执行)

Linux把所有文件和设备都当作文件来管理&#xff0c;这些文件都在根目录下&#xff0c;同时Linux中的文件名区分大小写。 一、文件属性 使用ls -l命令查看文件详情&#xff1a; 1、每行代表一个文件&#xff0c;每行的第一个字符代表文件类型&#xff0c;linux文件类型包括&am…...

Centos7.9安装lrzsz进行文件传输---Linux工作笔记059

这里咱们lrzsz命令,需要用来进行文件传输,因为如果不安装这个命令的话,那么 传输安装包什么的就不方便因为只有少数传输工具,才支持,直接拖拽的.没有的时候就可以用这个工具,用命令来传输 直接就是: sz 文件名 就可以把文件下载下来 rz 选择一个文件, 就可以把文件上传到当…...

酒吧座位全解析 小白必看

相信还有很多第一次去酒吧的朋友们还不了解吧台、散台、卡座的区分&#xff0c;下面我简单解说一下&#xff0c;如有错漏&#xff0c;欢迎指正&#xff01;一、吧台吧台是酒吧的核心部位&#xff0c;走进酒吧门&#xff0c;首先映入眼帘的就是吧台&#xff0c;一排人围着吧台几…...

DAY19

题目一 空间尝试模型 一个样本做行一个样本做列 范围尝试模型 以....做分隔 dp[i][j] 为以i为左界限 以j为右界限 求这个范围内的计算值(不对 是方法数) 这& | ^ 都是双目运算符 观察一下规律 整体字符数量一定为奇数(包括运算符和数字) 对应到数组中 数组的位一定是偶数…...

Data analysis|Tableau基本介绍及可实现功能

一、基础知识介绍 &#xff08;一&#xff09;什么是tableau tableau 成立于 2003 年&#xff0c;是斯坦福大学一个计算机科学项目的成果&#xff0c;该项目旨在改善分析流程并让人们能够通过可视化更轻松地使用数据。Tableau可以帮助用户更好地理解和发现数据中的价值&#x…...

单元测试优化:为什么要对程序进行测试?测试有什么好处?

单元测试&#xff08;Unit Testing&#xff09;又称为模块测试, 是针对程序模块&#xff08;软件设计的最小单位&#xff09;来进行正确性检验的测试工作。 程序单元是应用的最小可测试部件。简单来说&#xff0c;就是测试数据的稳定性是否达到程序的预期。 我们日常开发时可能…...

自动装配在Spring Boot中的重要性及实现方式

这里写目录标题 自动装配在Spring Boot中的重要性及实现方式什么是自动装配&#xff1f;如何实现自动装配&#xff1f;如何使用自动装配自动装配的优势总结 手写自动装配的Java代码示例原理 自动装配在Spring Boot中的重要性及实现方式 Spring Boot是基于Spring框架的开源框架…...

校对软件在司法系统中的应用:加强刑事文书审查

校对软件在司法系统中的应用可以加强刑事文书审查&#xff0c;提高文书的准确性和可靠性。 以下是校对软件在刑事文书审查方面的应用&#xff1a; 1.语法和拼写检查&#xff1a;校对软件可以自动检查刑事文书中的语法错误和拼写错误。这包括句子结构、主谓一致、动词形式等方面…...

微信小程序上传图片和文件

1.从微信里选择图片或文件上传 使用的vant的上传组件 原生用 wx.chooseMessageFile() html <!-- 从微信上面选择文件 --><van-uploader file-list"{{ file }}" bind:after-read"afterRead" max-count"{{3}}" deletable"{{ true…...

拥抱AIGC浪潮,亚信科技将如何把握时代新增量?

去年底&#xff0c;由ChatGPT带起的AIGC浪潮以迅雷不及掩耳之势席卷全球。 当互联网技术的人口红利逐渐消退之际&#xff0c;AIGC就像打开通用人工智能大门的那把秘钥&#xff0c;加速开启数智化时代的到来。正如OpenAI CEO Sam Altman所言&#xff1a;一个全新的摩尔定律可能…...

【opencv】指定宽或高按比例缩放图片 拼接图片

指定宽或高按比例缩放图片 import cv2def resize_by_ratio(image, widthNone, heightNone, intercv2.INTER_AREA):img_new_size None(h, w) image.shape[:2] # 获得高度和宽度if width is None and height is None: # 如果输入的宽度和高度都为空return image # 直接返回原图…...

使用C#加载TOOLBLOCK

前言 因为Vpp文件类型包含了以下三种 QuickBuidJobToolBlock 不同类型的打开方式不同&#xff0c;需要提前知道vpp是什么类型 例如 这个TB.vpp文件是TOOLBLOCK&#xff0c;就不能直接在visionpro中打开&#xff08;直接打开需要QuickBuid文件&#xff09;&#xff0c; 可以…...

MPAS-A原理及陆面模式的基本概念

跨尺度预测模式&#xff08;The Model for Prediction Across Scales - MPAS&#xff09;是由洛斯阿拉莫斯实验室和美国国家大气研究中心(NCAR)共同开发&#xff0c;其由3个部分组成&#xff0c;分别称为 MPAS-A&#xff08;大气模型&#xff09;、MPAS-O&#xff08;海洋模型&…...

前端技术Html,Css,JavaScript,Vue3

Html 1.基本标签 <h1>最大的标题</h1> <h2> . . . </h2> <h3> . . . </h3> <h4> . . . </h4> <h5> . . . </h5> <h6>最小的标题</h6><p>这是一个段落。</p> <br> &#xff08;换…...

实战项目——多功能电子时钟

一&#xff0c;项目要求 二&#xff0c;理论原理 通过按键来控制状态机的状态&#xff0c;在将状态值传送到各个模块进行驱动&#xff0c;在空闲状态下&#xff0c;数码管显示基础时钟&#xff0c;基础时钟是由7个计数器组合而成&#xff0c;当在ADJUST状态下可以调整时间&…...

【es6】对象解构赋值

es6中对象解构赋值&#xff1a; 代码 let { foo: baz } { foo: rose, bar: jeck }; baz // "rose"let obj { first: tom, last: rose }; let { first: f, last: l } obj; f // tom l // roselet { foo: baz } { foo: rose, bar: jeck }中的foo:baz部分&#xff…...

腾讯云服务器CVM标准型S6详细介绍_性能测评

腾讯云服务器CVM标准型S6实例是最新一代的标准型实例&#xff0c;CPU采用Intel Xeon Ice Lake处理器&#xff0c;主频2.7GHz&#xff0c;睿频3.3GHz&#xff0c;内存采用最新 DDR4&#xff0c;默认网络优化&#xff0c;最高内网收发能力达1900万pps&#xff0c;最高内网带宽可支…...

AI-调查研究-01-正念冥想有用吗?对健康的影响及科学指南

点一下关注吧&#xff01;&#xff01;&#xff01;非常感谢&#xff01;&#xff01;持续更新&#xff01;&#xff01;&#xff01; &#x1f680; AI篇持续更新中&#xff01;&#xff08;长期更新&#xff09; 目前2025年06月05日更新到&#xff1a; AI炼丹日志-28 - Aud…...

idea大量爆红问题解决

问题描述 在学习和工作中&#xff0c;idea是程序员不可缺少的一个工具&#xff0c;但是突然在有些时候就会出现大量爆红的问题&#xff0c;发现无法跳转&#xff0c;无论是关机重启或者是替换root都无法解决 就是如上所展示的问题&#xff0c;但是程序依然可以启动。 问题解决…...

linux之kylin系统nginx的安装

一、nginx的作用 1.可做高性能的web服务器 直接处理静态资源&#xff08;HTML/CSS/图片等&#xff09;&#xff0c;响应速度远超传统服务器类似apache支持高并发连接 2.反向代理服务器 隐藏后端服务器IP地址&#xff0c;提高安全性 3.负载均衡服务器 支持多种策略分发流量…...

STM32+rt-thread判断是否联网

一、根据NETDEV_FLAG_INTERNET_UP位判断 static bool is_conncected(void) {struct netdev *dev RT_NULL;dev netdev_get_first_by_flags(NETDEV_FLAG_INTERNET_UP);if (dev RT_NULL){printf("wait netdev internet up...");return false;}else{printf("loc…...

Auto-Coder使用GPT-4o完成:在用TabPFN这个模型构建一个预测未来3天涨跌的分类任务

通过akshare库&#xff0c;获取股票数据&#xff0c;并生成TabPFN这个模型 可以识别、处理的格式&#xff0c;写一个完整的预处理示例&#xff0c;并构建一个预测未来 3 天股价涨跌的分类任务 用TabPFN这个模型构建一个预测未来 3 天股价涨跌的分类任务&#xff0c;进行预测并输…...

NLP学习路线图(二十三):长短期记忆网络(LSTM)

在自然语言处理(NLP)领域,我们时刻面临着处理序列数据的核心挑战。无论是理解句子的结构、分析文本的情感,还是实现语言的翻译,都需要模型能够捕捉词语之间依时序产生的复杂依赖关系。传统的神经网络结构在处理这种序列依赖时显得力不从心,而循环神经网络(RNN) 曾被视为…...

uniapp 开发ios, xcode 提交app store connect 和 testflight内测

uniapp 中配置 配置manifest 文档&#xff1a;manifest.json 应用配置 | uni-app官网 hbuilderx中本地打包 下载IOS最新SDK 开发环境 | uni小程序SDK hbulderx 版本号&#xff1a;4.66 对应的sdk版本 4.66 两者必须一致 本地打包的资源导入到SDK 导入资源 | uni小程序SDK …...

springboot 日志类切面,接口成功记录日志,失败不记录

springboot 日志类切面&#xff0c;接口成功记录日志&#xff0c;失败不记录 自定义一个注解方法 import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target;/***…...

c# 局部函数 定义、功能与示例

C# 局部函数&#xff1a;定义、功能与示例 1. 定义与功能 局部函数&#xff08;Local Function&#xff09;是嵌套在另一个方法内部的私有方法&#xff0c;仅在包含它的方法内可见。 • 作用&#xff1a;封装仅用于当前方法的逻辑&#xff0c;避免污染类作用域&#xff0c;提升…...

解析两阶段提交与三阶段提交的核心差异及MySQL实现方案

引言 在分布式系统的事务处理中&#xff0c;如何保障跨节点数据操作的一致性始终是核心挑战。经典的两阶段提交协议&#xff08;2PC&#xff09;通过准备阶段与提交阶段的协调机制&#xff0c;以同步决策模式确保事务原子性。其改进版本三阶段提交协议&#xff08;3PC&#xf…...