数据结构:6、栈

一、栈的概念

栈:一种特殊的线性表,其只允许在固定的一端进行插入和删除元素操作。进行数据插入和删除操作的一端
称为栈顶,另一端称为栈底。栈中的数据元素遵守后进先出LIFO(Last In First Out)的原则。
压栈:栈的插入操作叫做进栈/压栈/入栈,入数据在栈顶。
出栈:栈的删除操作叫做出栈。出数据也在栈顶。

如下图所示就是栈的进栈和出栈,全部代码附在文章末。

二、栈的实现

栈的实现一般可以使用数组或者链表实现,相对而言数组的结构实现更优一些。因为数组在尾上插入数据的代价比较小,所以这里就使用顺序表结构了。

 1、栈的初始化与销毁

首先创建一个顺序表,因为栈的原理就是,后进先出,也就是相当于数组,最后一位一个个出去,而先进入的数据在数组的前面,所以就定义成顺序表.

所以定义在初始化中,把容量和栈顶也就是capacity和top这两个变量,但是数组的表示一般都是指向下一位,例如:arr[0]就是第一位数据,所以top定义为0但是他指向的数据的下一位,销毁就是把存放数据的指针a释放,因为是连续的所以释放一次就行了,容量和栈顶赋值为0,代码如下。

typedef int STDatetype;typedef struct Stack
{STDatetype* a;int top;int capacity;
}ST;void StackInit(ST* ps)
{assert(ps);ps->a = NULL;ps->capacity = 0;ps->top = 0;
}void StackDestroy(ST* ps)
{assert(ps);free(ps->a);ps->a = NULL;ps->capacity = ps->top = 0;
}

2、判断是否为空

这个函数就是利用bool库函数的实现,当栈顶的数据top为0时就返回真,在外面使用也就是用个取反就可以了。

bool StackEmpty(ST* ps)
{assert(ps);return ps->top == 0;
}

3、进栈与出栈

这个入栈的时候,需要先判定是否还有容量,也就是容量等于栈顶的时候就去申请空间,这里利用了三目运算符,当容量为0时赋值为4,不等于0直接乘上2,然利用realloc申请空间,然后把新的容量和地址分别赋给a和容量,realloc在地址为空时它相当于melloc这时可以运行测试下,测试代码和运行结果如下。

这里是从1到6入栈,但是出栈是后一个个出,所以就是6 5 4 3 2 1,因为这里测试了下判断有用吗,也就是栈为空时不能删,会报错断言。

// 入栈
void StackPush(ST* ps, STDatetype data)
{assert(ps);if (ps->capacity == ps->top){int newcapacity = ps->capacity == 0 ? 4 : ps->capacity * 2;ST* newnode = (ST*)realloc(ps->a, newcapacity * sizeof(STDatetype));if (newnode == NULL){perror("recalloc fail");return;}ps->a = newnode;ps->capacity = newcapacity;}ps->a[ps->top] = data;ps->top++;
}// 出栈
void StackPop(ST* ps)
{assert(ps);assert(!StackEmpty(ps));ps->top--;
}

测试代码

void TestStack1()
{ST ST;int temp = 0;int size = 0;StackInit(&ST);StackPush(&ST, 1);StackPush(&ST, 2);StackPush(&ST, 3);StackPush(&ST, 4);StackPush(&ST, 5);StackPush(&ST, 6);temp=StackTop(&ST);StackPop(&ST);printf("%d ", temp);temp = StackTop(&ST);StackPop(&ST);printf("%d ", temp);temp = StackTop(&ST);StackPop(&ST);printf("%d ", temp);temp = StackTop(&ST);StackPop(&ST);printf("%d ", temp);temp = StackTop(&ST);StackPop(&ST);printf("%d ", temp);temp = StackTop(&ST);StackPop(&ST);printf("%d ", temp);temp = StackTop(&ST);StackPop(&ST);printf("%d ", temp);StackDestroy(&ST);
}

 

4、获取栈顶的元素与栈的元素个数

差点忘了,上文中测试时,利用了这里才说的获取栈顶元素,因为获取一个删一个打印一下,这里就是获取元素的个数和获取栈顶元素,因为当数据为空时,有效元素个数为0,这里测试就是打印,然后当元素为空时,再去获取就会报错。

// 获取栈顶元素
STDatetype StackTop(ST* ps)
{assert(ps);assert(!StackEmpty(ps));return ps->a[ps->top-1];
}// 获取栈中有效元素个数
int StackSize(ST* ps)
{assert(ps);assert(!StackEmpty(ps));return ps->top;
}

测试代码

void TestStack2()
{ST ST;int temp = 0;int size = 0;StackInit(&ST);StackPush(&ST, 1);StackPush(&ST, 2);StackPush(&ST, 3);StackPush(&ST, 4);StackPush(&ST, 5);StackPush(&ST, 6);size = StackSize(&ST);printf("\n%d\n", size);temp = StackTop(&ST);StackPop(&ST);printf("%d ", temp);temp = StackTop(&ST);StackPop(&ST);printf("%d ", temp);temp = StackTop(&ST);StackPop(&ST);printf("%d ", temp);size = StackSize(&ST);printf("\n%d\n", size);temp = StackTop(&ST);StackPop(&ST);printf("%d ", temp);temp = StackTop(&ST);StackPop(&ST);printf("%d ", temp);temp = StackTop(&ST);StackPop(&ST);printf("%d ", temp);size = StackSize(&ST);printf("\n%d\n", size);StackDestroy(&ST);
}

 

三、代码

ST.h

#pragma once
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <assert.h>typedef int STDatetype;typedef struct Stack
{STDatetype* a;int top;int capacity;
}ST;// 初始化栈
void StackInit(ST* ps);
// 入栈
void StackPush(ST* ps, STDatetype data);
// 出栈
void StackPop(ST* ps);
// 获取栈顶元素
STDatetype StackTop(ST* ps);
// 获取栈中有效元素个数
int StackSize(ST* ps);
// 检测栈是否为空,如果为空返回非零结果,如果不为空返回0
bool StackEmpty(ST* ps);
// 销毁栈
void StackDestroy(ST* ps);

ST.c

#define _CRT_SECURE_NO_WARNINGS 1#include "ST.h"// 初始化栈
void StackInit(ST* ps)
{assert(ps);ps->a = NULL;ps->capacity = 0;ps->top = 0;
}// 入栈
void StackPush(ST* ps, STDatetype data)
{assert(ps);if (ps->capacity == ps->top){int newcapacity = ps->capacity == 0 ? 4 : ps->capacity * 2;ST* newnode = (ST*)realloc(ps->a, newcapacity * sizeof(STDatetype));if (newnode == NULL){perror("recalloc fail");return;}ps->a = newnode;ps->capacity = newcapacity;}ps->a[ps->top] = data;ps->top++;
}// 出栈
void StackPop(ST* ps)
{assert(ps);assert(!StackEmpty(ps));ps->top--;
}// 获取栈顶元素
STDatetype StackTop(ST* ps)
{assert(ps);assert(!StackEmpty(ps));return ps->a[ps->top-1];
}// 获取栈中有效元素个数
int StackSize(ST* ps)
{assert(ps);assert(!StackEmpty(ps));return ps->top;
}// 检测栈是否为空,如果为空返回非零结果,如果不为空返回0
bool StackEmpty(ST* ps)
{assert(ps);return ps->top == 0;
}// 销毁栈
void StackDestroy(ST* ps)
{assert(ps);free(ps->a);ps->a = NULL;ps->capacity = ps->top = 0;
}

test.c

#define _CRT_SECURE_NO_WARNINGS 1#include "ST.h"void TestStack1()
{ST ST;int temp = 0;int size = 0;StackInit(&ST);StackPush(&ST, 1);StackPush(&ST, 2);StackPush(&ST, 3);StackPush(&ST, 4);StackPush(&ST, 5);StackPush(&ST, 6);temp=StackTop(&ST);StackPop(&ST);printf("%d ", temp);temp = StackTop(&ST);StackPop(&ST);printf("%d ", temp);temp = StackTop(&ST);StackPop(&ST);printf("%d ", temp);temp = StackTop(&ST);StackPop(&ST);printf("%d ", temp);temp = StackTop(&ST);StackPop(&ST);printf("%d ", temp);temp = StackTop(&ST);StackPop(&ST);printf("%d ", temp);temp = StackTop(&ST);StackPop(&ST);printf("%d ", temp);StackDestroy(&ST);
}void TestStack2()
{ST ST;int temp = 0;int size = 0;StackInit(&ST);StackPush(&ST, 1);StackPush(&ST, 2);StackPush(&ST, 3);StackPush(&ST, 4);StackPush(&ST, 5);StackPush(&ST, 6);size = StackSize(&ST);printf("\n%d\n", size);temp = StackTop(&ST);StackPop(&ST);printf("%d ", temp);temp = StackTop(&ST);StackPop(&ST);printf("%d ", temp);temp = StackTop(&ST);StackPop(&ST);printf("%d ", temp);size = StackSize(&ST);printf("\n%d\n", size);temp = StackTop(&ST);StackPop(&ST);printf("%d ", temp);temp = StackTop(&ST);StackPop(&ST);printf("%d ", temp);temp = StackTop(&ST);StackPop(&ST);printf("%d ", temp);size = StackSize(&ST);printf("\n%d\n", size);StackDestroy(&ST);
}void main()
{TestStack2();return 0;
}

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

今日AI:GPT-4.5意外曝光可能6月发布、UP主借AI识别情绪播放量186万、全球首个AI程序员诞生

欢迎来到【今日AI】栏目!这里是你每天探索人工智能世界的指南&#xff0c;每天我们为你呈现AI领域的热点内容&#xff0c;聚焦开发者&#xff0c;助你洞悉技术趋势、了解创新AI产品应用。 新鲜AI产品点击了解:AIbase - 智能匹配最适合您的AI产品和网站 &#x1f4e2;一分钟速…

CSS 背景

CSS 背景 背景颜色 背景颜色若不设置&#xff0c;默认为透明(transparent) background-color: 颜色;背景颜色半透明 background: rgba(0, 0, 0, 0.3)前三个参数设定颜色&#xff0c;最后一个参数&#xff08;例如上述例子中的0.3&#xff09;设定透明度。0&#xff5e;1: 0…

C语言strcmp函数讲解

strcmp函数介绍 在cplusplus官网上是这样介绍strcmp函数的 这里的意思是假如我们输入两个字符串一个是abcdef另一个也是abcdef他们两个字符的每个元素的ascii码值进行比较如果两个元素的ascii码值都相等就移动到下一个元素a与a进行比较b与b进行比较直到遇到\0为止&#xff0c…

论坛管理系统|基于Spring Boot+ Mysql+Java+B/S架构的论坛管理系统设计与实现(可运行源码+数据库+设计文档+部署说明+视频演示)

推荐阅读100套最新项目 最新ssmjava项目文档视频演示可运行源码分享 最新jspjava项目文档视频演示可运行源码分享 最新Spring Boot项目文档视频演示可运行源码分享 目录 目录 前台功能效果图 管理员功能登录前台功能效果图 用户功能模块 系统功能设计 数据库E-R图设计 l…

彩虹外链网盘界面UI美化版超级简洁好看

彩虹外链网盘界面UI美化版 彩虹外链网盘&#xff0c;是一款PHP网盘与外链分享程序&#xff0c;支持所有格式文件的上传&#xff0c;可以生成文件外链、图片外链、音乐视频外链&#xff0c;生成外链同时自动生成相应的UBB代码和HTML代码&#xff0c;还可支持文本、图片、音乐、…

Skywalking

1、简介 Skywalking是由国内开源爱好者吴晟开源并提交到Apache孵化器的开源项目&#xff0c; 2017年12月SkyWalking成为Apache国内首个个人孵化项目&#xff0c; 2019年4月17日SkyWalking从Apache基金会的孵化器毕业成为顶级项目&#xff0c; 目前SkyWalking支持Java、 .Net、 …

SSA-LSTM多输入分类预测 | 樽海鞘优化算法-长短期神经网络 | Matlab

目录 一、程序及算法内容介绍&#xff1a; 基本内容&#xff1a; 亮点与优势&#xff1a; 二、实际运行效果&#xff1a; 三、算法介绍&#xff1a; 四、完整程序下载&#xff1a; 一、程序及算法内容介绍&#xff1a; 基本内容&#xff1a; 本代码基于Matlab平台编译&am…

RabbitMQ自学笔记——消息可靠性问题

1.发送者的可靠性 1.1生产者重连 有时由于网络波动等原因&#xff0c;发送方一次可能没有连接上RabbitMQ&#xff0c;我们可以配置发送方的连接失败重试机制。但需要注意的是&#xff1a;SpringAMQP提供的重试机制是阻塞式的重试&#xff0c;也就是说多次重试等待的过程中&am…

考虑功率均分与电压频率的事件触发分布式二次控制MATLAB模型

微❤关注“电气仔推送”获得资料&#xff08;专享优惠&#xff09; 模型简介 此模型是在《基于事件触发机制的孤岛微电网二次电压与频率协同控制MATLAB仿真模型》上进一步创作的&#xff0c;之前的模型只考虑了二次电压与频率控制&#xff0c;并没有考虑均分这一项点。 因此…

Kafka MQ broker和集群

Kafka MQ broker和集群 broker和集群 一个独立的 Kafka 服务器被称为 broker。broker 接收来自生产者的消息&#xff0c;为消息设置偏移量&#xff0c;并提交消息到磁盘保存。broker 为消费者提供服务&#xff0c;对读取分区的请求作出响应&#xff0c;返回已经提交到磁盘上的…

C#重新认识笔记_ FixUpdate + Update

C#重新认识笔记_ FixUpdate Update Update: 刷新频率不一致,非物理对象的移动&#xff0c;简单的刷新可用&#xff0c; FixedUpdate: 刷新频率一致,按照固定频率刷新&#xff0c;一般调用FixedUpdate之后&#xff0c;会立即进入必要的物理计算中,因此&#xff0c;任何影响刚…

从零开始,一步步构建服务网格istio

一、环境情况 环境&#xff1a;Ubuntu20.04 机器数量&#xff1a;单机1台 IP&#xff1a;10.9.2.83 二、准备知识 为什么使用 Istio&#xff1f; Istio提供了一种更高级别的服务网格解决方案&#xff0c;它可以简化和加强 Kubernetes 集群中的服务间通信、流量管理、安全…

Unity制作马赛克效果

大家好&#xff0c;我是阿赵。   之前在玩怒之铁拳4里面&#xff0c;看到了马赛克场景转换的效果&#xff0c;觉得很有趣&#xff0c;于是也来做一下。 一、2D版本的马赛克转场效果 先看看视频效果&#xff1a; 马赛克转场 这里我是直接写shader实现的&#xff0c;我这里是把…

【2024-03-12】设计模式之模板模式的理解

实际应用场景&#xff1a;制作月饼 过程描述&#xff1a; 一开始&#xff0c;由人工制作月饼&#xff0c; 第一个&#xff1a;根据脑子里面月饼的形状&#xff0c;先涅出月饼的形状&#xff0c;然后放入面粉和馅料把开口合并起来。 第二个&#xff1a;根据脑子里面月饼的形状&…

Ajax (1)

什么是Ajax&#xff1a; 浏览器与服务器进行数据通讯的技术&#xff0c;动态数据交互 axios库地址&#xff1a; <script src"https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script> 如何使用呢&#xff1f; 我们现有个感性的认识 <scr…

GSEA -- 学习记录

文章目录 brief统计学原理部分其他注意事项转录组部分单细胞部分 brief 上一篇学习记录写了ORA&#xff0c;其中ORA方法只关心差异表达基因而不关心其上调、下调的方向&#xff0c;也许同一条通路里既有显著高表达的基因&#xff0c;也有显著低表达的基因&#xff0c;因此最后…

基于LSTM实现春联上联对下联

按照阿光的项目做出了学习笔记&#xff0c;pytorch深度学习实战项目100例 基于LSTM实现春联上联对下联 基于LSTM&#xff08;长短期记忆网络&#xff09;实现春联上联对下联是一种有趣且具有挑战性的任务&#xff0c;它涉及到自然语言处理&#xff08;NLP&#xff09;中的序列…

Stable diffusion(一)

Stable diffusion 原理解读 名词解释 正向扩散&#xff08;Fixed Forward Diffusion Process&#xff09;&#xff1a;反向扩散&#xff08;Generative Reverse Denoising Process&#xff09; VAE&#xff08;Variational AutoEncoder&#xff09;&#xff1a;一个用于压缩图…

Mysql/Redis缓存一致性

如何保证MySQL和Redis的缓存一致。从理论到实战。总结6种来感受一下。 理论知识 不好的方案 1.先写MySQL&#xff0c;再写Redis 图解说明: 这是一幅时序图&#xff0c;描述请求的先后调用顺序&#xff1b; 黄色的线是请求A&#xff0c;黑色的线是请求B&#xff1b; 黄色的…

智慧城市与绿色出行:共同迈向低碳未来

随着城市化进程的加速&#xff0c;交通拥堵、空气污染、能源消耗等问题日益凸显&#xff0c;智慧城市与绿色出行成为了解决这些问题的关键途径。智慧城市利用信息技术手段&#xff0c;实现城市各领域的智能化管理和服务&#xff0c;而绿色出行则强调低碳、环保的出行方式&#…