【C语言】栈的实现(数据结构)


前言:

还是举一个生活中的例子,大家都玩过积木,当我们把积木叠起来的时候,如果要拿到最底部的积木,我们必须从顶端一个一个打出,最后才能拿到底部的积木,也就是后进先出(先进后出)的道理,今天分享栈的实现的本质也就是后进先出(先进后出)。

目录

前言:

栈的概念及结构

栈的实现

栈的结构定义

初始化栈

压栈(数据的添加)

出栈(数据的删除)

获取栈顶元素

获取栈中有效元素个数

判断栈是否为空

栈实现的总代码(vs2022)

头文件Stack.h

函数文件Stack.c

测试Text.c


栈的概念及结构

要去实现栈,我们要知道什么是 栈,栈的结构是什么,该从什么方向去实现。

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

 

如图我们会发现数据进栈出栈后的顺序倒置了,其实栈不只是可以将顺序导致,我们也可以先把A,B放进去,拿出来之后,再将C,D放进去,全部拿出来可以得到C,D,A,B,所以栈最后导致的结果是多种多样的,这取决你如何运用栈了。

栈的实现

栈的实现一般可以使用数组或者链表实现,相对而言数组的结构实现更优一些。因为数组在尾上
插入数据的代价比较小。
我们在这里使用数组进行实现,如图所示我们把数组的尾部作为栈顶,这样可以轻松的进行压栈操作(增加数据),如果使用链表的话,我们找到尾节点需要进行遍历找尾(利用循环去找为节点),这样就增多了时间的消耗,这里使用数组来实现栈,可以提高算法效率。

栈的结构定义

typedef int STDataType;typedef struct Stack
{ STDataType* a;int top;     //栈顶int capacity;//栈容量
}Stack;

栈只需要对栈顶进行操作,所以我们有一个变量top表示栈顶。后面需要判断栈是否为空,我们需要一个变量capacity表示栈容量。

初始化栈

void StackInit(Stack* ps)
{assert(ps);ps->a = (STDataType*)malloc(sizeof(STDataType) * 4);ps->top = 0;ps->capacity = 4;
}

这里我们创造了4个整型变量的空间,所以capacity给4。

压栈(数据的添加)

void StackPush(Stack* ps,STDataType x)
{assert(ps);if (ps->top == ps->capacity)//考虑到空间大小不够,使用realloc进行增容操作{STDataType* tmp = (STDataType*)realloc(ps->a, ps->capacity * 2 * sizeof(STDataType));if (tmp == NULL)//要注意tmp可能为空的情况。{printf("realloc fail!!!");exit(-1);}ps->a = tmp;//别忘了把指针a指向新开辟的空间ps->capacity *= 2;}ps->a[ps->top] = x;ps->top++;//注意个数的增加
}

在压栈的时候要注意几点:

1.压栈时要考虑空间的大小是否足够,不够时要进行增容操作。

2.增容操作后的原指针要指向新指针,保证数据不会丢失。

3.压栈过后要对将top往后移动一位,因为top的指向是数组最后元素的下一个位置。

出栈(数据的删除)

void StackPop(Stack* ps)
{assert(ps);assert(ps->top > 0);//top不能小于或等于0,因为top是指向栈顶元素的下一个位置ps->top--;
}

因为是用数组进行栈的实现,我们只需要把栈顶往前移动一位,就表示删除了数据。

获取栈顶元素

STDataType StackTop(Stack* ps)
{assert(ps);assert(ps->top > 0);return ps->a[ps->top - 1];//因为top是指向栈顶元素的下一个位置,所以要-1}

一定注意对ps->top>0进行断言,保证栈的元素不为空。

获取栈中有效元素个数

int StackSize(Stack* ps)
{assert(ps);return ps->top;}

top指向的数组尾部元素后一位,刚好是数组中有效元素的个数。

判断栈是否为空

bool StackEmpty(Stack* ps)//bool也可以使用 表示真假
{assert(ps);return ps->top == 0;
}

检查栈是否为空,如果不为空则返回0,如果为空则返回非零结果。

栈实现的总代码(vs2022)

头文件Stack.h

#pragma once#include<stdio.h>
#include<stdbool.h>
#include<stdlib.h>
#include<assert.h>
typedef int STDataType;typedef struct Stack
{ STDataType* a;int top;     //栈顶int capacity;//栈容量
}Stack;
//初始化栈
void StackInit(Stack* ps);
//栈的销毁
void StackDestory(Stack* ps);
//压栈
void StackPush(Stack* ps,STDataType x);
//出栈
void StackPop(Stack* ps);
//获取栈顶元素
STDataType StackTop(Stack* ps);
//获取栈中有效元素的个数
int StackSize(Stack* ps);
//检查栈是否为空,如果不为空则返回0,如果为空则返回非零结果
bool StackEmpty(Stack* ps);//bool也可以使用 表示真假

函数文件Stack.c

#include"Stack.h"void StackInit(Stack* ps)
{assert(ps);ps->a = (STDataType*)malloc(sizeof(STDataType) * 4);ps->top = 0;ps->capacity = 4;
}
void StackDestory(Stack* ps)
{assert(ps);free(ps->a);ps->a = NULL;ps->top = ps->capacity = 0;}
//入栈
void StackPush(Stack* ps,STDataType x)
{assert(ps);if (ps->top == ps->capacity)//考虑到空间大小不够,使用realloc进行增容操作{STDataType* tmp = (STDataType*)realloc(ps->a, ps->capacity * 2 * sizeof(STDataType));if (tmp == NULL)//要注意tmp可能为空的情况。{printf("realloc fail!!!");exit(-1);}ps->a = tmp;//别忘了把指针a指向新开辟的空间ps->capacity *= 2;}ps->a[ps->top] = x;ps->top++;//注意个数的增加
}
void StackPop(Stack* ps)
{assert(ps);assert(ps->top > 0);//top不能小于或等于0,因为top是指向栈顶元素的下一个位置ps->top--;
}
STDataType StackTop(Stack* ps)
{assert(ps);assert(ps->top > 0);return ps->a[ps->top - 1];//因为top是指向栈顶元素的下一个位置,所以要-1}
int StackSize(Stack* ps)
{assert(ps);return ps->top;}
bool StackEmpty(Stack* ps)//bool也可以使用 表示真假
{assert(ps);return ps->top == 0;
}

测试Text.c

#include"Stack.h"void StackText()
{Stack st;StackInit(&st);StackPush(&st, 1);StackPush(&st, 2);StackPush(&st, 3);StackPush(&st, 4);StackPush(&st, 5);while (!StackEmpty(&st)){printf("%d ", StackTop(&st));StackPop(&st);}StackDestory(&st);
}int main()
{StackText();return 0;
}

好啦,这就是今天学习的分享啦!看到希望大家的三连呀!

如果有不当之处,欢迎大佬指正!


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

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

相关文章

硬件厂家行业进销存系统开发之门票预约,源码解析css样式

采用技术未来之窗web行业应用弹窗对话框artDialog 未来之窗web行业应用弹窗对话框artDialog: 网页弹窗&#xff0c;独立使用单文件版本&#xff0c;可指定位置&#xff0c;左上&#xff0c;左下&#xff0c;中间&#xff0c;右侧&#xff0c;下册&#xff0c;左侧&#xff0c;…

微信小程序结合后端php发送模版消息

前端&#xff1a; <view class"container"><button bindtap"requestSubscribeMessage">订阅消息</button> </view> // index.js Page({data: {tmplIds: [UTgCUfsjHVESf5FjOzls0I9i_FVS1N620G2VQCg1LZ0] // 使用你的模板ID},requ…

vue+canvas音频可视化

1.代码 <template><div class"subGuide"><canvas id"canvas"></canvas><br><audio id"audio" src"./audio.mp3" controls></audio></div> </template><script> export…

48、PHP 实现冒泡排序法

题目&#xff1a; PHP 实现冒泡排序法 描述&#xff1a; /** 第1趟&#xff1a;3, 6, …2, 6, 3, …2, 6, 3, 4, …2, 6, 3, 4, 10, …1, 6, 3, 4, 10, 2, …1, 6, 3, 4, 10, 2, 9, …1, 6, 3, 4, 10, 2, 9, 8, …1, 6, 3, 4, 10, 2, 9, 8, 5, …1, 6, 3, 4, 10, 2, 9, 8, 5…

音乐曲谱软件Guitar Pro 8.2 for Mac 中文破解版

Guitar Pro 8.2 for Mac 中文破解版是一款功能强大的音乐曲谱软件&#xff0c;非常适合学习如何玩&#xff0c;改进技巧&#xff0c;重现喜爱的歌曲或陪伴自己。 Guitar Pro for Mac 是一款功能强大的音乐曲谱软件&#xff0c;非常适合学习如何玩&#xff0c;改进技巧&#xf…

做一个能和你互动玩耍的智能机器人之一

2024年被很多人称为AI元年&#xff0c;其实AI元年的叫法由来以久&#xff0c;近年来每一次AI技术的进步&#xff0c;都有很多圈内人大呼AI元年&#xff0c;但不仅一直风声不大&#xff0c;雨点也偏小&#xff0c;都是小范围交流。 得益于软硬件的进步&#xff0c;AI今年开始侵…

深度学习系列70:模型部署torchserve

1. 流程说明 ts文件夹下&#xff0c; 从launcher.py进入&#xff0c;执行jar文件。 入口为model_server.py的start()函数。内容包含&#xff1a; 读取args&#xff0c;创建pid文件 找到java&#xff0c;启动model-server.jar程序&#xff0c;同时读取log-config文件&#xff…

数据库表结构创建

一、原型图 二、分析 1、天气&#xff0c;值字段只有实测值&#xff0c;可用一个字段表示&#xff08;单位、来源同上&#xff09; 2、气温有默认值与实测值两个选项&#xff0c;一个字段无法表示默认值与实测值&#xff08;单位&#xff0c;来源同上&#xff09; 3、因为有…

【Kettle实现神通(数据库)MPP增量、全量数据ETL,同步任务Linux运行(通用)】

1、背景介绍 具体Kettle操作步骤不做过多介绍&#xff0c;主要技术方案说明&#xff0c;Kettle8.2版本放在底部链接提取&#xff0c;本次采用Kettle实现源端&#xff1a;神通数据通用库、目标端&#xff1a;神通MPP增量数据同步&#xff0c;并在服务器端运行Job。 2、windows…

【AIGC】构建自己的谷歌搜索引擎服务并使用

一、谷歌 谷歌的搜索引擎需要自己创建服务才能启用检索api。&#xff08;需自行翻墙和创建自己的谷歌账号&#xff09; 1.1 API服务创建 1&#xff09;登陆https://console.cloud.google.com/: 2&#xff09; 选择新建项目&#xff0c;取号项目名即可&#xff08;比如:Olin…

在 Windows 搭建 flink 运行环境并模拟流数据处理

一、引入 在大数据场景中,开发者追求高效与灵活,Linux 系统以其稳定性成为众多组件的首选,但在资源有限的情况下,在本机搭建一个 Linux 虚拟机集群却显得过于笨重,启动、运行占资源,需要配置网络,无法和windows共享资源,尤其是对只有 8GB 内存的 Windows 系统用户来说…

钙成像数据建模为行为事件

摘要 我在触摸屏盒中记录了小鼠在进行行为学习任务时的钙映像数据。 我想找到一种方法来整合神经数据&#xff08;100 个个体细胞随时间的活动&#xff08;约 30,000 x 约 30 毫秒时间段&#xff09;&#xff09;和行为数据&#xff08;动物在行为任务期间做出的时间戳动作和决…

2.4 openCv -- 对图像操作

处理图像 从文件加载图像: Cpp 1Mat img = imread(filename); 如果读取的是 JPG 文件,默认会创建一个三通道的图像。如果你需要灰度图像,可以使用: Cpp 1Mat img = imread(filename, IMREAD_GRAYSCALE); 注意 文件的格式由其内容(前几个字节)决定。要将图像保存到文…

[Mysql-视图和存储过程]

视图 视图是从一个或者几个基本表&#xff08;或视图&#xff09;导出的表。它与基 本表不同&#xff0c;是一个虚表。 创建使用视图 # 视图 -- 视图只能用来查询&#xff0c;不能做增删改 -- 创建视图 -- create view 视图名【view_xxx / v_xxx】 -- as 查询语句 create view…

电脑如何进行录屏?电脑录屏无压力!

在数字时代&#xff0c;屏幕录制已成为我们日常生活和工作中不可或缺的一部分。无论你是想要制作教程、记录游戏过程&#xff0c;还是捕捉在线会议的精彩瞬间&#xff0c;掌握屏幕录制的方法都显得尤为重要。本文将为你详细介绍电脑如何进行录屏&#xff0c;帮助你轻松捕捉屏幕…

MySql 触发器、存储器练习

一&#xff1a; 触发器 1、建立两个表:goods(商品表)、orders(订单表) 查看数据库&#xff1a;mysql> show databases; 使用数据库&#xff1a;mysql> use mydb16_trigger; 创建goods表&#xff1a; mysql> create table goods(gid char(8) not null primary key, …

免费【2024】springboot 畅游游戏销售平台

博主介绍&#xff1a;✌CSDN新星计划导师、Java领域优质创作者、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和学生毕业项目实战,高校老师/讲师/同行前辈交流✌ 技术范围&#xff1a;SpringBoot、Vue、SSM、HTML、Jsp、PHP、Nodejs、Python、爬虫、数据可视化…

AnyMP4 Data Recovery for Mac v1.5.8免激活版:高效数据恢复新选择

AnyMP4 Data Recovery for Mac是一款专为Mac用户设计的高效数据恢复软件&#xff0c;凭借其强大的功能和简洁的操作界面&#xff0c;为用户提供了快速、安全的数据恢复体验。 该软件支持恢复多种文件类型&#xff0c;包括照片、视频、音频、文档等&#xff0c;无论是常见的图片…

pytorch-梯度下降

梯度下降 y x 2 ∗ s i n ( x ) y ′ 2 x s i n x x 2 c o s x x 1 x − Δ y ′ ( x ) 其中 Δ 表示学习率&#xff0c; y ′ ( x ) 代表 y 在 x 点处关于 x 的梯度。 y x^2 * sin(x) \\ y 2xsinxx^2cosx \\ x_1 x - \Delta y(x) \\ 其中 \Delta 表示学习率&#xff0c…

【1.0】drf初识

【1.0】drf初识 【一】前后端开发模式 【1】前后端混合开发 【示例】flask混合、django混合【案例】bbs项目 模板&#xff1a;dtl语法&#xff08;django template language)模板语法 {{}} /{% %}后端渲染 qs对象–遍历循环到模板中–使用模板语法渲染渲染完成后 得到纯粹的…