数据结构——栈(C语言版)

前言:

在学习完数据结构顺序表和链表之后,其实我们就可以做很多事情了,后面的栈和队列,其实就是对前面的顺序表和链表的灵活运用,今天我们就来学习一下栈的原理和应用。

准备工作:本人习惯将文件放在test.c、SeqList.c、SeqList.h三个文件中来实现,其中test.c用来放主函数,SeqList.c用来放调用的函数,SeqList.h用来放头文件和函数声明

目录

什么是队列?

栈的节点结构

栈的基本操作

1、初始化

2、销毁

3、插入元素

4、判断栈顶元素是否为空

5、删除元素

6、返回栈顶元素

7、栈中元素个数

完整的栈实例

总结


什么是队列?

队列中的数据是按照先进后出的顺序的,也就是说先进去的数字后出来

因为栈的这种性质,所以栈我们用顺序表来实现比链表方便很多,顺序表就可以实现尾插尾出,所以我们一般就采用顺序表来实现

栈的节点结构

队列采用的顺序表的结构,所以与顺序表差异不大

typedef int STDataType;
typedef struct stack
{STDataType* a;int top;         //指向栈元素下一位int capacity;
}ST;

栈的结构很简单,定义一个整形指针,一个表示容量和一个表示尾部元素的整形变量即可

栈的基本操作

//初始化
void STInit(ST* pst);
//销毁
void STDestroy(ST* pst);
//插入元素
void STPush(ST* pst, STDataType x);
//删除元素
void STPop(ST* pst);
//判断栈顶元素是否为空
bool STEmpty(ST* pst);
//找栈顶元素
STDataType STTop(ST* pst);
//栈中元素个数
STDataType STSize(ST* pst);

看上面的函数声明部分我们就可以看到我们每一步要实现的内容,接下来,我们就来一步一步进行实现

1、初始化

//初始化
void STInit(ST* pst)
{pst->a = NULL;pst->capacity = 0;pst->top = 0;
}

2、销毁

//销毁
void STDestroy(ST* pst)
{assert(pst);free(pst->a);pst->capacity = pst->top = 0;
}

3、插入元素

插入元素时要先检查空间是否够用,如果不够用要先进行扩容

//插入元素
void STPush(ST* pst, STDataType x)
{if (pst->top == pst->capacity){int newcapacity = pst->capacity == 0 ? 4 : pst->capacity * 2;STDataType* newnode = (STDataType*)realloc(pst->a, sizeof(STDataType) * newcapacity);if (newnode == NULL){perror("STPush");return;}pst->a = newnode;pst->capacity = newcapacity;}pst->a[pst->top] = x;pst->top++;
}

4、判断栈顶元素是否为空

这一步在下面有用到,例如当删除栈顶元素时,如果栈顶元素为空就无法操作,所以需要判断栈顶元素是否为空

//判断栈顶元素是否为空
bool STEmpty(ST* pst)
{assert(pst);return pst->top == 0;
}

5、删除元素

这里删除元素是删除栈顶元素,因为栈的特性是即出即删

//删除元素
void STPop(ST* pst)
{assert(pst);assert(!STEmpty(pst));pst->top--;
}

6、返回栈顶元素

//找栈顶元素
STDataType STTop(ST* pst)
{assert(pst);assert(!STEmpty(pst));return pst->a[pst->top - 1];
}

7、栈中元素个数

//栈中元素个数
STDataType STSize(ST* pst)
{assert(pst);return pst->capacity;
}

完整的栈实例

SeqList.h

//实现栈
typedef int STDataType;
typedef struct stack
{STDataType* a;int top;         //指向栈元素下一位int capacity;
}ST;//初始化
void STInit(ST* pst);
//销毁
void STDestroy(ST* pst);
//插入元素
void STPush(ST* pst, STDataType x);
//删除元素
void STPop(ST* pst);
//判断栈顶元素是否为空
bool STEmpty(ST* pst);
//找栈顶元素
STDataType STTop(ST* pst);
//栈中元素个数
STDataType STSize(ST* pst);

test.c

//实现栈
void test()
{ST st;STInit(&st);STPush(&st,1);STPush(&st, 2);STPush(&st, 3);STPush(&st, 4);while (!STEmpty(&st)){printf("%d ", STTop(&st));STPop(&st);}STDestroy(&st);
}
int main()
{test();return 0;
}

SeqList.c

//实现栈
//初始化
void STInit(ST* pst)
{pst->a = NULL;pst->capacity = 0;pst->top = 0;
}
//销毁
void STDestroy(ST* pst)
{assert(pst);free(pst->a);pst->capacity = pst->top = 0;
}
//插入元素
void STPush(ST* pst, STDataType x)
{if (pst->top == pst->capacity){int newcapacity = pst->capacity == 0 ? 4 : pst->capacity * 2;STDataType* newnode = (STDataType*)realloc(pst->a, sizeof(STDataType) * newcapacity);if (newnode == NULL){perror("STPush");return;}pst->a = newnode;pst->capacity = newcapacity;}pst->a[pst->top] = x;pst->top++;
}
//判断栈顶元素是否为空
bool STEmpty(ST* pst)
{assert(pst);return pst->top == 0;
}
//删除元素
void STPop(ST* pst)
{assert(pst);assert(!STEmpty(pst));pst->top--;
}
//找栈顶元素
STDataType STTop(ST* pst)
{assert(pst);assert(!STEmpty(pst));return pst->a[pst->top - 1];
}
//栈中元素个数
STDataType STSize(ST* pst)
{assert(pst);return pst->capacity;
}

总结

总之,其实栈就是对顺序表的应用,熟练栈和队列,对我们巩固顺序表和链表帮助很大,当然,栈在一些场景下很实用,后面我会出一个专门的习题讲解篇章,讲数据结构的一些经典题型,感兴趣的可以点赞关注一下

创作不易,还请各位大佬点赞支持一下!!!

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

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

相关文章

ubuntu22.04@Jetson Orin Nano安装配置VNC服务端

ubuntu22.04Jetson Orin Nano安装&配置VNC服务端 1. 源由2. 环境3. VNC安装Step 1: update and install xserver-xorg-video-dummyStep 2: Create config for dummy virtual displayStep3: Add the following contents in xorg.conf.dummyStep 4: Update /etc/X11/xorg.con…

WPF-基础及进阶扩展合集(持续更新)

目录 一、基础 1、GridSplitter分割线 2、x:static访问资源文件 3、wpf触发器 4、添加xaml资源文件 5、Convert转换器 6、多路绑定与多路转换器 二、进阶扩展 1、HierarchicalDataTemplate 2、XmlDataProvider从外部文件获取源 3、TextBox在CellTemplate中的焦点问题…

Python基础之pandas:文件读取与数据处理

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 一、文件读取1.以pd.read_csv()为例:2.数据查看 二、数据离散化、排序1.pd.cut()离散化,以按范围加标签为例2. pd.qcut()实现离散化3.排序4.…

stream使用

stream流式计算 在Java1.8之前还没有stream流式算法的时候&#xff0c;我们要是在一个放有多个User对象的list集合中&#xff0c;将每个User对象的主键ID取出&#xff0c;组合成一个新的集合&#xff0c;首先想到的肯定是遍历&#xff0c;如下&#xff1a; List<Long> u…

通过pymysql读取数据库中表格并保存到excel(实用篇)

本篇文章是通过pymysql将本地数据库中的指定表格保存到excel的操作。 这里我们假设本地已经安装了对应的数据库管理工具&#xff0c;里面有一个指定的表格&#xff0c;现在通过python程序&#xff0c;通过调用pymysql进行读取并保存到excel中。 关于数据库管理工具是Navicat P…

Android Studio学习7——常用控件view

Android控件 双击shift键——>搜索想要找的文件 Ctrlshift回车——>补全“&#xff1b;”号 CtrlX——>删除一行&#xff0c;只需把鼠标放在那一行 windows自带字体

LC 111.二叉树的最小深度

111. 二叉树的最小深度 给定一个二叉树&#xff0c;找出其最小深度。 最小深度是从根节点到最近叶子节点的最短路径上的节点数量。 说明&#xff1a; 叶子节点是指没有子节点的节点。 示例 1&#xff1a; 输入&#xff1a; root [3,9,20,null,null,15,7] 输出&#xff1a;…

mongodb的简单操作

文章目录 前言数据库的创建和删除集合的创建和删除文档的插入和查询异常处理更新数据局部修改符合条件的批量更新加操作 删除文档删除全部数据删除符合条件的数据 统计count统计有多少条数据统计特定条件有多少条数据 分页查询排序查询正则查询比较查询包含查询条件连接查询索引…

Docker 哲学 - push 本机镜像 到 dockerhub

注意事项&#xff1a; 1、 登录 docker 账号 docker login 2、docker images 查看本地镜像 3、注意的是 push镜像时 镜像的tag 需要与 dockerhub的用户名保持一致 eg&#xff1a;本地镜像 express:1 直接 docker push express:1 无法成功 原因docker不能识别 push到哪里 …

轻松上手 Tanssi:应用链开发与部署终极指南

随着 Polkadot 2.0 的推进&#xff0c;一个既强大又用户友好的技术支撑成为推动生态进步的关键&#xff0c;目的是为了降低应用链启动的成本和复杂度。在这个转折点上&#xff0c;Tanssi 逐渐成为应用链开发的首选解决方案。Tanssi 是一个旨在简化应用链部署流程的模块化基础设…

kubernetes-Pod基于污点、容忍度、亲和性的多种调度策略(二)

Pod调度策略 一.污点-Taint二.容忍度-Tolerations三.Pod常见状态和重启策略1.Pod常见状态2.Pod的重启策略2.1测试Always重启策略2.2测试Never重启策略2.3测试OnFailure重启策略&#xff08;生产环境中常用&#xff09; 一.污点-Taint 在 Kubernetes 中&#xff0c;污点&#x…

采用大语言模型进行查询重写——Query Rewriting via Large Language Models

文章&#xff1a;Query Rewriting via Large Language Models&#xff0c;https://arxiv.org/abs/2403.09060 摘要 查询重写是在将查询传递给查询优化器之前处理编写不良的查询的最有效技术之一。 手动重写不可扩展&#xff0c;因为它容易出错并且需要深厚的专业知识。 类似地…

codeforces Edu 142 D. Fixed Prefix Permutations 【思维、字典树求LCP】

D. Fixed Prefix Permutations 题意 给定 n n n 个长度为 m m m 的排列 a 1 , a 2 , . . . a n a_1,a_2,...a_n a1​,a2​,...an​ 定义一个排列 p p p 的 价值 为 最大顺序长度 k k k&#xff1a; p 1 1 , p 2 2 , p 3 3 , . . . p k k p_1 1,p_2 2, p_3 3, ...…

CLIP网络结构解析 openai/CLIP (Contrastive Language-Image Pre-Training)

1、简单介绍 CLIP是openai公司提出的网络&#xff0c;可以处理文本和图像&#xff0c;是一个多模态网络&#xff0c;对多模态的研究具有一定的推动作用。作为学习&#xff0c;记录一下对CLIP的理解。 clip的官方网站&#xff1a; https://openai.com/research/clip clip的GitH…

优于五大先进模型,浙江大学杜震洪团队提出 GNNWLR 模型:提升成矿预测准确性

卡塔尔世界杯自 2010 年荣膺举办权&#xff0c;直至 2022 年辉煌成功举办&#xff0c;累计投入资金高达约 2,290 亿美元。相较之下&#xff0c;此前七届世界杯的总花费仅约 400 多亿美元。这场体育盛事展现出奢华无度的风采&#xff0c;归根结底源于卡塔尔这个国度的深厚底蕴。…

nginx配置多vue项目

1. 找到linux docker安装好的nginx目录文件 进入nginx内 把打包好的vue项目放在html文件下 如上 三个文件夹下对应着三个不同的vue项目 2. 配置default.conf的配置文件&#xff0c; 一个nginx配置文件可以多个项目进行代理 进入到conf 找到conf.d下面的default.conf 文件…

SV学习笔记(二)

接口 什么是接口&#xff1f; 接口 主要用作验证 &#xff0c;国外有些团队会使用sv进行设计&#xff0c;那么接口就会用作设计。验证环境中&#xff0c;接口可以 使连接变得简洁而不易出错 。interface和module的使用性质很像&#xff0c; 可以定义端口&#xff0c;也可以定…

[C/C++] -- 二叉树

1.简介 二叉树是一种每个节点最多有两个子节点的树结构&#xff0c;通常包括&#xff1a;根节点、左子树、右子树。 满二叉树&#xff1a; 如果一棵二叉树只有度为0的结点和度为2的结点&#xff0c;并且度为0的结点在同一层上&#xff0c;则这棵二叉树为满二叉树。深度为k&a…

如何备份极狐GitLab 信任域名证书

本文作者&#xff1a;徐晓伟 GitLab 是一个全球知名的一体化 DevOps 平台&#xff0c;很多人都通过私有化部署 GitLab 来进行源代码托管。极狐GitLab 是 GitLab 在中国的发行版&#xff0c;专门为中国程序员服务。可以一键式部署极狐GitLab。 本文主要讲述了如何使用极狐GitLa…

WebCopilot:一款功能强大的子域名枚举和安全漏洞扫描工具

关于WebCopilot WebCopilot是一款功能强大的子域名枚举和安全漏洞扫描工具&#xff0c;该工具能够枚举目标域名下的子域名&#xff0c;并使用不同的开源工具检测目标存在的安全漏洞。 工具运行机制 WebCopilot首先会使用assetsfinder、submaster、subfinder、accumt、finddom…