C语言栈的含义与栈数据操作代码详解!

news2024/11/28 6:45:48

引言:在本篇博客中,我们将学到数据结构——栈,讲到栈的含义与关于栈的数据操作代码可以在顺序表、双向链表以及单链表的基础上实现,而于本篇博客中,我们选择在顺序表的基础上实现

更多有关C语言和数据结构知识详解可前往个人主页:计信猫

目录

 

一,栈的含义

二,栈的结构体的定义

三,栈数据操作函数

1,栈的初始化

2,栈的销毁

3,入栈

 

4,出栈

5,取栈顶的数据

6,获取栈中数据的个数

7,判断栈是否为空

四,结语


一,栈的含义

        是一种特殊的线性表,只允许在表中固定的一端进行插入和删除元素的操作。进行数据插入和删除操作的一端成为栈顶,另一端成栈底

压栈:栈的数据插入操作。

出栈:栈的数据删除操作。

        而因为特殊的数据插入和删除遵循LIFO(后进先出)的原则,使得可以被比作一个羽毛筒。(因为羽毛球里边的球都是从最上边开始使用的,类比于栈顶

二,栈的结构体的定义

        这次,我们仍然使用三文件操作法,分别创建stack.h、stack.c、test.c三个文件。

         因为前文提到,栈是一种特殊的顺序表,那么栈的定义应该和顺序表的定义方式极其相似,所以在stack.h中,我们如下定义栈:

//包含实现栈的操作函数所要用到的头文件
#include<stdio.h>
#include<assert.h>
#include<stdlib.h>
#include<stdbool.h>
typedef int STDataType;
//创建栈结构体
typedef struct Stack
{
	STDataType* a;//动态数组
	int top;//栈顶的下一位
	int capacity;//数组总空间大小
}ST;

        可能大家会不理解top的含义,那么请看如下的图片讲解吧。

 

        如果里边没有元素的时候,那么此时top便指向数组中下标为零的地方。 

三,栈数据操作函数

        因为是在顺序表的基础上实现的,所以的数据操作函数与顺序表及其类似,甚至更简单,好好听吧,一定可以听懂!

1,栈的初始化

        对于栈的初始化其实就是将栈结构体中的指针类型赋值为NULL整型类型赋值为0就可以了,我们直接上代码:

// 初始化栈 
void StackInit(ST* ps)
{
    //断言判断栈不为NULL
	assert(ps);
	ps->a = NULL;
	ps->capacity = ps->top = 0;//top指向栈顶数据的下一位
}

2,栈的销毁

        在该函数中,我们所需要做的就是释放掉动态数组所开辟的空间,再将指针置空防止野指针的出现,最后将整型类型改为0就可以了。代码如下:

// 销毁栈 
void StackDestroy(ST* ps)
{
	free(ps->a);//释放动态数组空间
	ps->a = NULL;//防止野指针的出现
	ps->capacity = ps->top = 0;
}

3,入栈

        入栈顾名思义,就是在栈顶插入数据

        而在插入数据之前,我们就需要先判断动态数组的空间是否足够,不够我们就使用realloc函数进行空间大小的修改。判断空间代码如下:

//判断空间是否足够
	if (ps->top == ps->capacity)//top==capacity说明空间不够
	{
		int newcapacity = ps->capacity == 0 ? 4 : ps->capacity * 2;//三目操作符
		STDataType* tmp = (STDataType*)realloc(ps->a,sizeof(STDataType) * newcapacity);
		if (tmp==NULL)//防止空间申请失败
		{
			perror("realloc fail!");
			return;
		}
		ps->a = tmp;
		ps->capacity = newcapacity;
	}

        于此段代码之中,有两个非常巧妙之处:1,空间是否足够的判断:让我们仔细想想,当top变量等于capacity变量时是什么情况?

         对,就是如上图所示,当两者相等的时候,也就意味着整个动态数就只有一个空间以供使用了,而这时,我们就需要进行空间的动态开辟了。 

         2,三目操作符的使用:仔细想想,以下两种代码有什么不一样的呢?

代码一:
int newcapacity = ps->capacity * 2;
代码二:
int newcapacity = ps->capacity == 0 ? 4 : ps->capacity * 2;

        其实答案十分简单,在我们对栈进行初始化的时候,我们将topcapacity变量都初始化为了0,那如果是代码一0*2就为0,则不就乱套了吗?所以我们便使用代码二用到了三目操作符来避免0*20的尴尬情况

        而之后的入栈函数就十分简单了,但千万别忘了要对top进行++处理!! 

// 入栈 
void StackPush(ST* ps, STDataType data)
{
	assert(ps);
	//判断空间是否足够
	if (ps->top == ps->capacity)
	{
		int newcapacity = ps->capacity == 0 ? 4 : ps->capacity * 2;
		STDataType* tmp = (STDataType*)realloc(ps->a,sizeof(STDataType) * newcapacity);
		if (tmp==NULL)
		{
			perror("realloc fail!");
			return;
		}
		ps->a = tmp;
		ps->capacity = newcapacity;
	}
	ps->a[ps->top] = data;//top处加入新的元素
	ps->top++;//栈顶的移动
}

4,出栈

        对于出栈函数,其实我们所需要做的就是删除掉栈顶的元素,并且将栈顶向后移动一位。而对于栈顶元素的删除,我们也无需像链表一样使用free函数,我们只需要将top1即可,十分的简单。直接上代码!

// 出栈 
void StackPop(ST* ps)
{
	assert(ps);
	assert(ps->top > 0);
	ps->top--;
}

5,取栈顶的数据

        因为栈顶是一个中及其特殊的位置,所以我们也就时不时会用到栈顶的数据,而这个函数就很好的帮我们解决了这个问题。

        在这个函数中,我们唯二需要注意的就是栈不可以为空指针,栈的数据个数不可以为零。代码走起!

// 获取栈顶元素 
STDataType StackTop(ST* ps)
{
	assert(ps);//栈不为空指针
	assert(ps->top > 0);//栈的数据个数不能为零
	STDataType tmp = ps->a[ps->top - 1];//top-1才为栈顶元素的下标
	return tmp;
}

6,获取栈中数据的个数

        这个函数是关于栈的数据操作函数中最简单的一个函数。栈中的数据个数不就是top的值吗,所以我们直接返回top就可以了。代码如下:

// 获取栈中有效元素个数 
int StackSize(ST* ps)
{
	assert(ps);
	return ps->top;
}

7,判断栈是否为空

        该函数比较特殊,它使用到的是布尔类型。如果栈为空,就返回true;反之则返回false。而对于是否为空的判断,我们只需要观察top是否为零就可以了。所以代码如下:

// 检测栈是否为空
bool StackEmpty(ST* ps)
{
	assert(ps);
	return ps->top == 0;//若top为零,则为true;反之则为false
}

四,结语

        这是有关数据结构中的讲解,是不是易如反掌呢?之后我也会接着更新数据结构中另一个知识点——队列的讲解。

        博客不仅是我记录所学习到的知识点的工具,也是我找到同样有学习编程爱好的人的朋友圈,希望我的博客可以对你有所帮助,也希望你可以留下你的鼓励,你的鼓励就是我最大的动力!!加油!

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

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

相关文章

大数据与会计专业主要学什么课程

大数据与会计专业是一个结合了传统会计知识与现代大数据技术的交叉学科&#xff0c;旨在培养既懂会计又熟悉大数据分析的复合型人才。该专业的学生将会学习以下主要课程内容&#xff1a; 会计基础课程&#xff1a;包括基础会计、财务会计、成本会计、管理会计等&#xff0c;这些…

如何搜索空文件夹_名称为(纯或含)中/英/数/符

首先&#xff0c;需要用到的这个工具&#xff1a; 度娘网盘 提取码&#xff1a;qwu2 蓝奏云 提取码&#xff1a;2r1z 打开工具&#xff0c;切换到批量文件复制版块&#xff0c;快捷键Ctrl5 点击右侧的搜索添加 设定要搜索的范围、指定为文件夹、包括子目录&#xff0c;勾选…

SSM整合-前后端分离-项目环境搭建 (上)

整合SSM 项目基础环境搭建项目介绍创建项目项目全局配置web.xmlSpringMVC配置配置Spring和MyBatis, 并完成整合创建表, 使用逆向工程生成Bean, XxxMapper和XxxMapper.xml注意事项和细节说明 实现功能01-搭建Vue前端工程需求分析/图解代码实现搭建Vue前端工程vue3项目目录结构梳…

宜选影票在线选座电影票小程序开发如何获取api接口?

要开发一个在线选座电影票小程序并获取API接口&#xff0c;你需要遵循几个关键步骤。以下是通常的流程&#xff1a; 明确需求和目标&#xff1a; 在开始之前&#xff0c;明确你的小程序需要哪些功能&#xff0c;例如电影查询、场次查询、在线选座、购票支付等。确定你需要从AP…

【智能优化算法】野狗智能优化算法(Dingo Optimization Algorithm DOA)

野狗智能优化算法(Dingo Optimization Algorithm DOA)是期刊“MATHEMATICAL PROBLEMS IN ENGINEERING”的2021年智能优化算法 01.引言 野狗智能优化算法(Dingo Optimization Algorithm DOA)该算法的灵感来自野狗的狩猎策略&#xff0c;即迫害攻击&#xff0c;分组策略和清除行…

VS Code中PlatformIO IDE的安装并开发Arduino

VS Code中PlatformIO IDE的安装并开发Arduino VS Code的安装 略 PlatformIO IDE的安装 PlatformIO IDE是是什么 PlatformIO IDE 是一个基于开源的跨平台集成开发环境&#xff08;IDE&#xff09;&#xff0c;专门用于嵌入式系统和物联网&#xff08;IoT&#xff09;开发。…

2009-2022年上市公司华证ESG评级评分数据(含细分项)

2009-2022年上市公司华证ESG评级评分数据&#xff08;含细分项&#xff09; 1、时间&#xff1a;2009-2022年 2、来源&#xff1a;华证ESG 3、指标&#xff1a;证券代码、证券简称、综合评级、年度、综合得分、E评级、E得分、S评级、S得分、G评级、G得分 4、范围&#xff1…

如何解决3D模型变黑或贴图不显示的问题---模大狮模型网

在进行3D建模和视觉渲染时&#xff0c;经常会遇到模型表面变黑或贴图不显示的问题&#xff0c;这可能严重影响最终视觉效果的质量。这些问题通常与材质设置、光照配置或文件路径错误有关。本文将探讨几种常见原因及其解决方法&#xff0c;帮助3D艺术家和开发者更有效地处理这些…

Portforge:一款功能强大的轻量级端口混淆工具

关于Portforge Portforge是一款功能强大的轻量级端口混淆工具&#xff0c;该工具使用Crystal语言开发&#xff0c;可以帮助广大研究人员防止网络映射&#xff0c;这样一来&#xff0c;他人就无法查看到你设备正在运行&#xff08;或没有运行&#xff09;的服务和程序了。简而言…

ubuntu20安装colmap

系统环境 ubuntu20 &#xff0c;cuda11.8 &#xff0c;也安装了anaconda。因为根据colmap的官方文档说的&#xff0c;如果根据apt-get安装的话&#xff0c;默认是非cuda版本的&#xff0c;而我觉得既然都安装了cuda11.8了&#xff0c;自然也要安装cuda版本的colmap。 安装步骤…

MySQL之聚合函数与应用

1. 前言 上文我们讲到了单行函数.实际上SQL还有一类叫做聚合函数, 它是对一组数组进行汇总的函数, 输入的是一组数据的集合, 输出的是单个值. 2. 聚合函数 用于处理一组数据, 并对一组数据返回一个值. 有如下几种聚合函数 : AVG(), SUM(), MAX(), MIN(), COUNT(). 3. AVG(…

[Scrcpy]数据线连接安卓手机投屏windows电脑[win控制安卓手机]比Samsung Dex好用

配置好&#xff0c;只需要两步即可完成安卓手机投屏windows 第一步&#xff1a;usb线连接windows电脑 第二步&#xff1a;cmd输入投屏命令srccpy 搞定 前言/背景 一些视频资料只能下载到手机&#xff0c;很不喜欢手机那么小屏幕播放&#xff0c;播放很不方便 在家的话可以投…

在做题中学习(50):搜索插入位置

35. 搜索插入位置 - 力扣&#xff08;LeetCode&#xff09; 解法&#xff1a;二分查找 思路&#xff1a;题目是有序的&#xff0c;时间复杂度O(logN),二分没跑了&#xff0c;题目说如果找不到target&#xff0c;返回它应该被插入位置的下标&#xff0c;所以可以分析一下示例2…

QT截图程序,可多屏幕截图

截图程序&#xff0c;支持多屏幕时跨屏幕截图。截图使用setMask达到镂空效果&#xff0c;截图后会有预览和保存功能。截图时按下Esc可退出。 mainwindow.ui mainwindow.cpp #include "mainwindow.h" #include "ui_mainwindow.h" #include <QDebug> …

暴雨发布大模型专用分布式全闪存储

近日&#xff0c;暴雨信息发布为大模型专门优化的分布式全闪存储AVERSE系列。该系列依托暴雨信息自研分布式文件系统&#xff0c;搭载新一代数据加速引擎Xdata&#xff0c;通过盘控协同、GPU直访存储、全局一致性缓存等技术为AI大模型数据归集、训练、数据归档与管理等阶段提供…

本机MySQL数据库服务启动了,但是cmd登录不上10061

注意&#xff1a;不建议安装MySQL8&#xff0c;建议直接使用phpstudy中自带的MySQL5.7 错误信息 ERROR 2003 (HY000): Cant connect to MySQL server on x.x.x.x (10061) 原因 可能是端口号错误。比如修改了my.ini中&#xff0c;或者phpstudy中数据库端口的配置&#xff0c;…

代码随想录算法训练营第十九天:二叉树go

代码随想录算法训练营第十九天&#xff1a;二叉树go 226.翻转二叉树 力扣题目链接(opens new window) 翻转一棵二叉树。 ​​ 这道题目背后有一个让程序员心酸的故事&#xff0c;听说 Homebrew的作者Max Howell&#xff0c;就是因为没在白板上写出翻转二叉树&#xff0c;最…

HarmonyOS实战开发-如何实现查询当前城市实时天气功能

先来看一下效果 本项目界面搭建基于ArkUI中TS扩展的声明式开发范式&#xff0c; 数据接口是和风&#xff08;天气预报&#xff09;&#xff0c; 使用ArkUI自带的网络请求调用接口。 我想要实现的一个功能是&#xff0c;查询当前城市的实时天气&#xff0c; 目前已实现的功能…

外贸企业邮箱哪家好?推荐三个国内好用的外贸企业邮箱

国内有许多企业邮箱的提供商&#xff0c;外贸公司在选择外贸企业邮箱时该选哪家&#xff1f;三个在国内排行前三的外贸企业邮箱&#xff0c;Zoho Mail企业邮箱、腾讯企业邮箱和阿里企业。这三款企业邮箱功能各有优势&#xff0c;今天我们具体来了解下。 一、Zoho Mail公司邮箱…

LibTorch入坑记--续2

一、安装faiss 我的faiss&#xff0c;用的是曾经安装过的 pip install faiss-gpu1.7 当时搞得环境名称是pni 二、配置环境 三、例子代码 #include <faiss/IndexFlat.h> #include <faiss/Index.h> #include <faiss/VectorTransform.h> #include <faiss/…