数据结构——栈(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.hqwc.cn/news/588750.html

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

相关文章

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

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

工业互联网网关软件分析与设计

一、 案例软件分析 一、总体目标 工业互联网是新一代信息技术与制造业深度融合形成的新兴业态和应用模式,其发展前景广阔。工业互联网网关是将各采集监测点的数据通过无线或有线传感网络进行数据汇集,进行统一有效的监管。在工业互联网体系架构中&…

分享几个可以免费使用的GPT网站吧

1. ChatGAI ChatGAI是一个界面简洁的AI平台,提供App和网页版,每日均有免费使用机会。 2. ChatGPT 本网站向大家开放了ChatGPT 3.5和4.0版本的免费体验,特别适合新用户。每天都有免费次数,响应迅速,注册便捷&#xff0…

刷题DAY43 | LeetCode 1049-最后一块石头的重量 II 494-目标和 474-一和零

1049 最后一块石头的重量 II(medium) 有一堆石头,用整数数组 stones 表示。其中 stones[i] 表示第 i 块石头的重量。 每一回合,从中选出任意两块石头,然后将它们一起粉碎。假设石头的重量分别为 x 和 y,且…

(2024)Ubuntu源码安装多个版本的opencv并切换使用

本人工作会用到x86_64的opencv和aarch64的opencv,所以写下来备忘自用 一、源码编译安装 依赖库安装: sudo apt-get install build-essential libgtk2.0-dev libgtk-3-dev libavcodec-dev libavformat-dev libjpeg-dev libswscale-dev libtiff5-dev o…

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

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

Harmony创建Page省事小技巧

在创建Page页面时,选择ArkTS File时,创建的文件不会自动生成基础代码,也不会自动在main_page.json中自动进行注册,如何解决问题呢,其实很简单创建Page页面时选择Page项后就会创建Page文件,创建完的页面会自…

【C语言】2048小游戏【附源码】

欢迎来到英杰社区https://bbs.csdn.net/topics/617804998 一、游戏描述: 2048是一款数字益智类游戏,玩家需要使用键盘控制数字方块的移动,合并相同数字的方块,最终达到数字方块上出现“2048”的目标。 每次移动操作,所…

掌握这些技巧:Flutter应用顺利登陆App Store的秘诀

引言 🚀 Flutter作为一种跨平台的移动应用程序开发框架,为开发者提供了便利,使他们能够通过单一的代码库构建出高性能、高保真度的应用程序,同时支持Android和iOS两个平台。然而,完成Flutter应用程序的开发只是第一步…

Python快速入门系列-8(Python数据分析与可视化)

第八章:Python数据分析与可视化 8.1 数据处理与清洗8.1.1 数据加载与查看8.1.2 数据清洗与处理8.1.3 数据转换与整理8.2 数据可视化工具介绍8.2.1 Matplotlib8.2.2 Seaborn8.2.3 Plotly8.3 数据挖掘与机器学习简介8.3.1 Scikit-learn8.3.2 TensorFlow总结在本章中,我们将探讨…

了解这些技术:Flutter应用顺利登陆iOS平台的步骤与方法

引言 🚀 Flutter作为一种跨平台的移动应用程序开发框架,为开发者提供了便利,使他们能够通过单一的代码库构建出高性能、高保真度的应用程序,同时支持Android和iOS两个平台。然而,完成Flutter应用程序的开发只是第一步…

Flash存储芯片:NOR Flash、NAND Flash、UFS和eMMC的比较与解析

前言 在数字化时代的今天,数据的存储和管理变得越来越重要。各种各样的存储技术应运而生,以满足不同的使用场景和需求。其中,Flash存储芯片以其非易失性、可擦写性和可编程性等优势,占据了重要地位。本博客将详细介绍Flash存储芯片…