C语言数据结构篇——栈的顺序存储

article/2025/9/15 16:16:56

作者名:Demo不是emo 

主页面链接主页传送门
创作初心:对于计算机的学习者来说,初期的学习无疑是最迷茫和难以坚持的,中后期主要是经验和能力的提高,我也刚接触计算机1年,也在不断的探索,在CSDN写博客主要是为了分享自己的学习历程,学习方法,总结的经验等等,希望能帮助到大家
座右铭:不要让时代的悲哀成为你的悲哀
专研方向:网络安全,数据结构

每日emo你要一直做我的月亮,做那个照亮我的人
————————————————

  注:本文需要一定的顺序表基础,有想了解顺序表的小伙伴可以看一下我分享的关于顺序表的博客,点此链接可以直接进入: C语言数据结构篇——顺序表的理解,创建,插入和删除_Grande joie的博客-CSDN博客

目录

前言

初识栈

栈的创建

栈的初始化

判断栈为空 

获取栈顶元素 

弹出栈顶元素 

 压入栈顶元素

销毁栈 

完整代码  

前言

在学完顺序表和链表这两种最基本的数据结构之后就要进入我们的栈和队列的学习了,首先我们来学习栈,而栈的存储方式一样有两种,一种是顺序存储,一种是链式存储,储存结构的不同使实现栈的基本算法也不同,今天我要给大家分享的的就是栈的顺序存储。

初识栈

栈也属于线性表,但是栈是操作受限的线性表,操作受限,就是栈的特点特点之一,在前面线性表的学习中我们知道,链表可以在表的两端甚至任何位置进行插入,删除,等操作,但栈却只能在固定的一端进行操作,意思就是栈的插入,删除等操作都只能在表的一个固定端点上进行,如下图:

如上图,我们可以看到插入,删除等操作只能在一侧进行, 所以向一个栈中插入新元素又称为压栈,入栈;同样的,栈数据的删除又可以称为出栈,弹栈,能够进行压栈,弹栈的一端自称为栈顶,不能的一端称为栈底,下面我们就来看一看应该怎么实现栈的顺序存储;

栈的创建

栈的创建,我们同样以头结点结构体的形式创建栈,头结点的结构体中保存一个数组和一个整型top,如下:

#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#define maxsize 1024//栈的容量(自定义)
#define INFINITY 99999//随便定一个数,待会需要
typedef struct
{int data[maxsize];//该数组用来存放栈的数据int top;//数组中栈顶元素的下标(即最后一个元素下标)
}seqstack;//定义别名方便使用

这样一个栈就创建好了,下面就可以直接使用了 ;

栈的初始化

我们上面说了头结点中的top代表栈顶元素在数组中的下标 ,所以初始化时就不能把top赋值成自然数,所以我们把top赋值为-1,这样就完成了栈的初始化

void initstack(seqstack* stack)//初始化栈
{stack->top=-1;
}

判断栈为空 

判断栈是否为空也很简单,要判断栈为空就判断栈是否为初始状态,而上面我们也进行了栈的初始化,所以栈是否等于-1就可以作为判断栈是否为空的依据,具体代码如下:

int isempty(seqstack* stack)//判断栈为空
{if(stack->top==-1){return 1;//栈为空}return 0;//栈不为空
}

获取栈顶元素 

因为我们是用数组来存放栈的数据的,所以要获取栈顶元素,就是获取数组中位于栈顶元素的下标,由上面的结构示意图可以看出来,栈底指的就是数组的第一个元素的位置,栈底指的就是数组最后一个元素,而头结点结构体中的top正是数组中最后一个元素的下标,所以获取栈顶元素是不是也很简单了呢?具体代码如下:

int seqstack_top(seqstack* stack)//获取栈顶元素
{if(isempty(stack)==0)//栈不为空{return stack->data[stack->top];}return INFINITY;//返回无穷大,不能返回-1,有可能栈的顶端元素就是-1
}

弹出栈顶元素 

弹出栈顶元素就是我们的弹栈,压栈,意思就是弹出栈顶元素,使栈顶元素的后面一个元素成为栈顶元素,对应到数组中的实际操作其实就是删除数组的最后一个元素,所以也是比较简单的,具体代码如下:

int seqstack_pop(seqstack* stack)//弹出栈顶元素
{if(isempty(stack)==0){return stack->data[stack->top--];}return INFINITY;//与获取栈顶元素同理
}

 压入栈顶元素

压入栈顶元素就是我们称的压栈,入栈,即吧压入的数据放到栈顶的前面,使之称为新的栈顶,而数组上的意思就是在数组最后一个数据上再加一个数据,具体代码如下:

void seqstack_push(seqstack* stack,int val)//压栈(入栈)
{if(stack->top>=maxsize-1)栈已满则无法进行压栈{return;//退出程序}stack->top++;//此时栈顶改变,所以top指向新的栈顶下标stack->data[stack->top]=val;//入栈
}

销毁栈 

销毁栈就不多说了,直接上代码:

void seqstack_destory(seqstack* stack)
{if(isempty(stack)==0){free(stack);}
}

当然,为了方便使用,我们还可以建立一个遍历打印(即输出)栈的函数,代码如下:

void seqstack_print(seqstack* stack)
{for(int i=0;i<=stack->top;i++){if(i%5==0){printf("\n");}printf("%d ",stack->data[i]);}printf("\n");
}

以上就是栈的一些基本操作,我们都以函数的形式封装完了。

完整代码 

下面我们就随便写点数据将这些函数都用起来,就是完整代码啦,代码如下:

#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#define maxsize 1024//栈的容量
#define INFINITY 99999//随便定一个数
typedef struct
{int data[maxsize];//定义一个数组int top;//栈顶元素的下标
}seqstack;
void initstack(seqstack* stack)//初始化栈
{stack->top=-1;
}
int isempty(seqstack* stack)//判断栈为空
{if(stack->top==-1){return 1;//栈为空}return 0;//栈不为空
}
int seqstack_top(seqstack* stack)//获取栈顶元素
{if(isempty(stack)==0)//{return stack->data[stack->top];}return INFINITY;//返回无穷大,不能返回-1,有可能栈的顶端元素就是-1
}
int seqstack_pop(seqstack* stack)//弹出栈顶元素
{if(isempty(stack)==0){return stack->data[stack->top--];}return INFINITY;
}
void seqstack_push(seqstack* stack,int val)//压栈(入栈)
{if(stack->top>=maxsize-1){return;//退出程序}stack->top++;//指向栈顶stack->data[stack->top]=val;//入栈
}
void seqstack_destory(seqstack* stack)
{if(isempty(stack)==0){free(stack);}
}
void seqstack_print(seqstack* stack)
{for(int i=0;i<=stack->top;i++){if(i%5==0){printf("\n");}printf("%d ",stack->data[i]);}printf("\n");
}
int main()
{srand((unsigned)time(0));//以时间为种子获取随机数seqstack stack;initstack(&stack);printf("请输入栈的初始数据个数\n");int number;scanf("%d",&number);for(int i=0;i<number;i++)//将随机数压栈{seqstack_push(&stack,rand()%1000);//rand可以按顺序读取srand通过种子获得的随机数//“%1000”是因为我想将随机数的值控制在0到1000}//获取栈顶元素printf("栈顶元素:%d\n",seqstack_top(&stack));printf("栈中的元素");seqstack_print(&stack);seqstack_pop(&stack);//出栈printf("出栈后栈中的元素");seqstack_print(&stack);printf("请输入要压栈的元素\n");int input;scanf("%d",&input);seqstack_push(&stack,input);//入栈printf("压栈后栈中的元素");seqstack_print(&stack);seqstack_destory(&stack);return 0;
}

随便写点数据运行一下就是下面这个效果啦

请输入栈的初始数据个数
10
栈顶元素:629
栈中的元素
340 937 63 665 546
729 904 922 326 629
出栈后栈中的元素
340 937 63 665 546
729 904 922 326
请输入要压栈的元素
9999
压栈后栈中的元素
340 937 63 665 546
729 904 922 326 9999

大一学生,c语言学习半年,文章有什么不完善的地方还请见谅,欢迎大家对文章提出自己的看法,最后,感谢大家的阅读。 


http://chatgpt.dhexx.cn/article/nxyE9p86.shtml

相关文章

C语言数据结构之查找(顺序查找,折半查找)

C语言数据结构之查找&#xff08;顺序查找&#xff0c;折半查找&#xff09; tips&#xff1a;前些天已经学习了树和图的相关知识&#xff0c;今天来总结下两种常用的查找方式&#xff08;顺序查找&#xff0c;折半查找&#xff09;。 为了演示方便&#xff0c;顺序查找和折半…

【C语言数据结构7】--串的实现

串 一、什么是串 串就是我们常说的字符串&#xff0c;它同样是一个线性表。可能有人认为串就是元素为字符的线性表&#xff0c;但这种说法是不准确的。对于普通的线性表&#xff0c;它们关注的往往是单个元素&#xff0c;每个单独的元素都有独立的含义。比如我们用线性表存储…

C语言数据结构——查找(检索)

一、查找的基本概念 查找:查询某个关键字是否在(数据元素集合&#xff09;表中的过程。也称作检索。 查找表: 由同一类型的数据元素&#xff08;或记录&#xff09;构成的集合。 主关键字: 能够惟一区分各个不同数据元素的关键字 次关键字: 通常不能惟一区分各个不同数据元素的…

C语言数据结构——广义表

C语言数据结构中&#xff0c;广义表和数组一样&#xff0c;也是线性表的一种推广&#xff01; 广义表的定义&#xff1a; 广义表 LS 为n&#xff08;n≥0&#xff09;个元素的有穷序列&#xff0c;记作&#xff1a; LS &#xff08;d1, d2, … dn&#xff09; 其中&#xff1…

C语言数据结构——图

一、图的基本概念 图是由顶点集合及顶点间的关系集合组成的一种数据结构。vertex, edge 图G的定义是&#xff1a; G &#xff08;V&#xff0c;E&#xff09; 其中&#xff0c; V {x|x∈某个数据元素集合} E { (x&#xff0c;y)|x&#xff0c;y∈V} &#xff08;无向图&#…

数据结构(c语言版本)

1.基本概念 1.1数据 对客观事物的符号表示&#xff0c;在计算机与科学中是指所有能输入到计算机并被计算机程序处理的符号的总称。 1.2数据元素 是数据的基本单位&#xff0c;在计算机程序中作为一个整体进行考虑和处理 1.3数据对象 是相同性质数据元素的集合&#xff0c…

c语言数据结构

目录 一、数据结构构造概述 1.1、什么是数据结构 1.2、数据的逻辑结构的4种分类 二、线性表 2.1、线性表概述 2.2、顺序表 2.3、链表 2.3.1、链表节点的创建 2.3.2、链表结点遍历 2.3.3、链表结点删除 2.3.4、链表的插入 ​ 三、栈和队列 3.1、栈概述 3.2、栈…

C语言数据结构知识点小结(全)

Catologue C语言数据结构一、基本概念和术语二、时间、空间复杂度&#xff08;1&#xff09;时间复杂度&#xff08;2&#xff09;空间复杂度 三、类C语言有关操作补充1&#xff1a;数组定义补充2&#xff1a;动态内存分配补充3&#xff1a;C中的参数传递 四、线性表&#xff0…

七丶青龙nvjdc部署教程+短信验证登录对接傻妞

青龙nvjdc部署教程短信验证登录对接傻妞Nolanjdc 没有服务器的先自行购买&#xff0c;这里推荐腾讯云2H4G8M首年70–点击购买 青龙面板安装教程 傻妞机器人安装教程 XDD安装教程 QQ交流&#xff1a;1014549449 --------------点击跳转 注丶只能对接一个&#xff0c;要么对接…

手机短信验证

在项目中经常会用到手机短信验证注册&#xff0c;登录等功能&#xff0c;所以我想写一篇文章来给大家提供一个参考。 阿里大于-个人感觉比较好用的短信验证平台&#xff0c;下面是接入阿里大于sdk的步骤。 阿里大于官网&#xff1a;直通车, 进入官网需要注册&#xff0c;注册…

014_关于session实现短信验证登录的前端启动

014_关于session实现短信验证登录的前端启动 1、进入到nginx相对应的文件夹&#xff0c;shfit右键&#xff0c;进入PowerShell并且执行nginx 2、启动我们的nginx,嘿嘿&#xff0c;可以访问我们的前端网页啦&#xff01;&#xff01;&#xff01;它就是模仿我们的大众点评来着…

基于Redis的短信验证登录

基于Redis的短信验证登录 1、用户调用发送短信验证码接口2、用户调用登录/注册接口3、用户调用校验接口4、SpringMvc拦截器注册5、token刷新拦截器6、登录拦截器 1、用户调用发送短信验证码接口 用户调用sendCode()接口&#xff0c;把phone传到后端&#xff0c;后端对phone进行…

使用聚合数据短信API测试(短信验证登录)

搞一手聚合数据短信API测试&#xff08;之前用阿里云的搞过&#xff0c;今天我们用聚合&#xff09; 注册聚合账号&#xff01;聚合官网链接登陆后进入短信服务API&#xff08;免费提供十次&#xff09; 添加自定义模板&#xff08;审核速度看脸&#xff09; 审核成功后得…

android studio 实现短信验证 登录

登录 http://www.mob.com/ 注册 创建项目 加入依赖 贴代码 classpath “com.mob.sdk:MobSDK:2018.0319.1724” apply plugin: ‘com.mob.sdk’ // 在MobSDK的扩展中注册SMSSDK的相关信息 这里使用自己的 appKey appSecret MobSDK {appKey “2e2974aec0” appSecret “1d35b87…

Java简单实现短信验证登录(Session、Redis)

前端设计 <div class"login-form"><div style"display: flex; justify-content: space-between"><el-input style"width: 60%" placeholder"请输入手机号" v-model"form.phone" ></el-input><e…

Vue与Node.js实现手机短信验证登录

手机短信使用的第三方平台是联容云&#xff0c;注册就送8块钱体验费&#xff0c;足够自己用用了&#xff0c;注册完自己建一个应用就能拿到需要使用的配置了&#xff0c;如图 注册完之后1就可以使用了。 Node.js后端使用了Express框架 "js-base64": "^3.7.2&qu…

【青龙面板+诺兰2.0 网页短信验证登录+bot查询】

看这个之前&#xff0c;如果是没搭建过的先看下面这篇哈&#xff0c;如果是跟着下面的搭建完了&#xff0c;出现了机器人5次获取验证码失败&#xff0c;让你用Cookie方式登录的情况&#xff0c;看这篇哈。 前提&#xff1a;自己有服务器&#xff01;这里用的Centos7.6做演示&am…

Springboot实现短信登录验证

Springboot学习笔记——Java实现短信登录验证功能--Servlet/SSM/SpringBoot都可以用 小白记录一下短信验证登入的实现&#xff0c;方便以后可以拿来直接用。 发短信平台&#xff1a;互亿无线 官网地址 登入注册啥的就不说了&#xff0c;新人注册会送十条短信验证&#xff0c;想…

java WEB调用秒嘀科技短信验证接口(实现短信验证登录)

java WEB调用秒嘀科技短信验证接口&#xff08;实现短信验证登录&#xff09; 前言注册秒嘀云账号登录秒嘀云官网 代码 前言 短信验证登咱就不多说了&#xff0c;为什么推荐用秒嘀的呢&#xff0c;应为他会送你10元钱&#xff0c;对于新手来说10元钱&#xff0c;足够你玩了。但…

Android利用mob实现短信验证登录

首先要去官网申请一个应用&#xff0c;拿到对应的APPKEY以及APPSECRET 附上直通车链接MobTech 申请应用基本是秒批&#xff0c;然后就可以得到应用的APPKEY以及APPSECRET 然后就是查看官方的文档 直接跟着步骤走&#xff0c;可以不用手动下载sdk&#xff0c;导入这些它自动会帮…