【数据结构】栈的实现

 👑个人主页:啊Q闻       

🎇收录专栏:《数据结构》           

 🎉前路漫漫亦灿灿

前言 

栈是一种特殊的线性表,我们在有了顺序表和链表的知识的基础上,再来学习栈,掌握起来就更轻松了。

一.初识栈 

1.栈的概念

栈是一种特殊的线性表,它的特殊性体现在只允许在固定的一端进行插入和删除操作,其遵循先入后出的的规则。

我们将进行数据插入和数据删除操作的一端称为栈顶,另一端则称为栈底。

栈的插入操作叫做压栈(或者进栈或者入栈),栈的删除操作叫做出栈,这两种操作都是在栈顶进行。

2.栈的结构

入栈出栈示意图:

从入栈出栈示意图中,我们发现:1是最先进入栈中,却是最后出栈的,印证了栈的先入后出规则。

二.栈的实现 

栈的实现可以用链表也可以用数组,我们选择使用数组,因为数组在尾上插入删除更简单。stack.h

#pragma once
#include<stdio.h>
#include<assert.h>
#include<stdbool.h>
#include<stdlib.h>
typedef int STDataType;
typedef struct Stack
{STDataType* a;int top;//栈顶int capacity;//容量
}Stack;
//初始化栈
void StackInit(Stack* s);
//入栈
void StackPush(Stack* s,STDataType x);
//出栈
void StackPop(Stack* s);
//获取栈顶元素
STDataType StackTop(Stack* s);
//获取栈中有效元素个数
int StackSize(Stack* s);
//检测栈是否为空,为空返回0
bool StackEmpty(Stack* s);
//销毁栈
void StackDestroy(Stack* s);

stack.c

注意:我们入栈出栈均是在栈顶,所以在数组中就是实现在尾部的插入与删除。

#include"stack.h"
//初始化栈
void StackInit(Stack* s)
{assert(s);s->a = NULL;s->top = 0;s->capacity = 0;
}
//入栈
void StackPush(Stack* s,STDataType x)
{assert(s);if (s->top == s->capacity)//容量不够就进性扩容{int newcapacity = s->capacity == 0 ?  4 :s->capacity * 2;STDataType* tmp = (STDataType*)realloc(s->a, (newcapacity * sizeof(STDataType)));if (tmp == NULL){perror("realloc fail\n");return;}s->a = tmp;s->capacity = newcapacity;}s->a[s->top] = x;s->top++;
}
//检测栈是否为空,为空返回false
bool StackEmpty(Stack* s) 
{assert(s);return s->top == 0;
}
//出栈
void StackPop(Stack* s)
{assert(s);assert(!StackEmpty(s));s->top--;
}
//获取栈顶元素
STDataType StackTop(Stack* s)
{assert(s);assert(!StackEmpty(s));return s->a[s->top - 1];
}
//获取栈中有效元素个数
int StackSize(Stack* s)
{assert(s);return s->top;
}
//销毁栈
void StackDestroy(Stack* s)
{free(s->a);s->a = NULL;s->capacity = s->top = 0;
}

详解:

入栈:

容量不够时就进行扩容,数组的扩容我们首先要用一个三目操作判断原来的容量是否为               0,为0我们就给它赋值4,不为0就是直接扩容,一般是成二倍扩容。

利用realloc对原有的数组进行扩容。

扩容后在插入数据,top++指向尾部元素的下一位


 出栈

我们出栈前先判断栈是否为空,如果为空,就无法进行出栈操作。

出栈直接top--。


获取栈顶元素和栈顶中有效元素

获取栈顶元素之前,要保证栈顶不为空

因为top指向的是栈顶元素的下一个,所以我们用top-1.

获取栈中有效元素,因为数组下标是从0开始,所以最后下标会比实际有效元素少1。但是正好的是top是指向有效元素的下一个,所以top的值就是有效元素个数。

 


初始化栈和销毁栈

对于销毁栈,因为我们是在扩容时用realloc对数组a进行扩容,所以用free释放扩容的部分。

 


 test.c

#include"stack.h"
int main()
{Stack s;StackInit(&s);StackPush(&s, 1);StackPush(&s, 2);StackPush(&s, 3);StackPush(&s, 4);while(!StackEmpty(&s)){int top = StackTop(&s);printf("%d\n", top);StackPop(&s);}StackDestroy(&s);return 0;
}

 感谢阅读,如果对你有帮助的话,三连支持一下吧

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

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

相关文章

所有可能的真二叉树(Lc894)——记忆化搜索

给你一个整数 n &#xff0c;请你找出所有可能含 n 个节点的 真二叉树 &#xff0c;并以列表形式返回。答案中每棵树的每个节点都必须符合 Node.val 0 。 答案的每个元素都是一棵真二叉树的根节点。你可以按 任意顺序 返回最终的真二叉树列表。 真二叉树 是一类二叉树&#…

【24年物联网华为杯】赛题分析与初步计划

赛事介绍 官网链接&#xff1a;2024 年全国大学生物联网设计竞赛 (sjtu.edu.cn) 含金量&#xff1a;属于A类赛事 &#xff08;注意&#xff1a;很多搜索结果的序号是按照选入时间排列的&#xff0c;与含金量无关&#xff0c;华为杯是23年选入的&#xff09; Kimi Chat: 全国…

开源模型应用落地-LangChain试炼-CPU调用QWen1.5(一)

一、前言 尽管现在的大语言模型已经非常强大&#xff0c;可以解决许多问题&#xff0c;但在处理复杂情况时&#xff0c;仍然需要进行多个步骤或整合不同的流程才能达到最终的目标。然而&#xff0c;现在可以利用langchain来使得模型的应用变得更加直接和简单。 通过langchain框…

js处理long精度丢失

1、业务背景 调用接口返回数据实体&#xff0c;id是long类型&#xff0c;浏览器(谷歌&#xff09;进行访问返回的id最后两位变成0了&#xff0c;精度丢失。但是通过postman是正常的。 2、问题分析 这是因为在 JavaScript 中&#xff0c;数字类型默认会被转换为双精度浮点数&…

【学习笔记十二】EWM上架仓位确定逻辑及操作演示

一、前言 关于EWM上架仓位确定的过程&#xff0c;我在【学习笔记十一】EWM上架目标仓位确定过程及配置-CSDN博客中讲到了 EWM根据仓库类型&#xff08;storage type&#xff09;、仓库分区&#xff08;storage section&#xff09;和上架策略&#xff08;putaway strategies&…

机器学习算法快速入门

文章目录 0.简介1.常用术语1) 模型2) 数据集3) 样本&特征4) 向量5) 矩阵6)假设函数&损失函数7&#xff09;拟合&过拟合&欠拟合 2.线性回归3.梯度下降求极值4.Logistic回归算法&#xff08;分类问题&#xff09;5.KNN最邻近分类算法6.朴素贝叶斯分类算法7.决策树…

SAP 技巧篇:解决下拉菜单不显示前缀编码问题

事务代码 BP创建主数据选择组时&#xff0c;组前面不显示英文分组&#xff0c;或者其他界面不显示对应英文分组” 01 — 背景需求 BP等事务代码进来不显示前面系统英文分组 02 — 实现 返回SAP GUI找到选项>可视化1>控件全部打钩 先打钩&#xff1a;在下拉列表内显示…

Golang | Leetcode Golang题解之第29题两数相除

题目&#xff1a; 题解&#xff1a; func divide(dividend, divisor int) int {if dividend math.MinInt32 { // 考虑被除数为最小值的情况if divisor 1 {return math.MinInt32}if divisor -1 {return math.MaxInt32}}if divisor math.MinInt32 { // 考虑除数为最小值的情…

汽车抗疲劳驾驶测试铸铁试验底座技术要求有哪些

铸铁平台试验台底座的主要技术参数要求 1、 试验台底座设计制造符合JB/T794-1999《铸铁平板》标准。 2、 试验铁底板及所有附件的计量单位全部采用 单位&#xff08;SI&#xff09;标准。 3、铸铁平台平板材质&#xff1a;用细密的灰口铸铁HT250或HT200&#xff0c;强度符…

U盘怎么加密?U盘加密的方法有哪些?

U盘作为一种便携式的存储设备&#xff0c;广泛应用于日常生活和工作中。但由于其易于携带和使用的特性&#xff0c;U盘中的数据也面临着被未经授权访问的风险。因此&#xff0c;对U盘进行加密成为了保护数据安全的重要措施。本文将介绍几种常见的U盘加密方法&#xff0c;帮助用…

【C++学习】C++4种类型转换详解

这里写目录标题 &#x1f680;C语言中的类型转换&#x1f680;为什么C需要四种类型转换&#x1f680;C强制类型转换&#x1f680;static_cast&#x1f680;**reinterpret_cast**&#x1f680;const_cast与volatile&#x1f680;dynamic_cast &#x1f680;C语言中的类型转换 在…

腾讯EdgeOne产品测评体验—Web服务全能一体化服务,主打一步到位

前言 现在网络Web攻击真的防不胜防啊&#xff0c;相信有很多独狼开发者自己建站&#xff0c;租个云服务器&#xff0c;一部署自己的服务&#xff0c;每隔一段时间内测和网站总有一个要崩。自己感觉难受不说&#xff0c;网站稍微有点要出头的时候&#xff0c;数不清的访问攻击就…

【让自己的U盘变得与众不同】

文章目录 今日座右铭&#xff1a;在心里种花&#xff0c;人生才不会荒芜。 文章目录 文章目录前言一、准备ICO图标二、插入U盘1.点击新建文本文档-输入代码-点击保存2.将代码文本文档名称修改为autorun.inf在这里插入图片描述3.将图标及代码文本文档放入U盘中在这里插入图片描述…

【从浅学到熟知Linux】进程控制上篇=>进程创建、进程终止与进程等待(含_exit与exit的区别、fork函数详解、wait与waitpid详解)

&#x1f3e0;关于专栏&#xff1a;Linux的浅学到熟知专栏用于记录Linux系统编程、网络编程等内容。 &#x1f3af;每天努力一点点&#xff0c;技术变化看得见 文章目录 进程创建fork函数写时拷贝 进程退出进程退出操作系统做了什么&#xff1f;进程退出场景进程退出的常见方法…

面经学习(湖北航信实习)

个人评价 比较简单的面试题&#xff0c;项目基本不问&#xff0c;全是八股文&#xff0c;mybatis中#{}和${}之前没有遇到过&#xff0c;算是长知识了。 1.Java的三大特性有了解过吗&#xff1f; java的三大特性就是&#xff1a;继承&#xff0c;多态&#xff0c;封装。 继承就…

广播变量在spark中的用法以及数据倾斜问题的解决方法

1. spark中的广播变量 应用场景&#xff1a;广播变量用于在集群的各个节点的executor 中高效的分发一个只读的变量副本 操作原理&#xff1a;创建一个广播变量时&#xff0c;spark会将变量序列化并发送到每一个executor&#xff0c;每一个executor存一个副本&#xff0c;而不需…

mysql表的底层存储是以b+树的形式存储的吗

MySQL 中的 InnoDB 存储引擎使用 B树作为其索引结构的基础。InnoDB 是 MySQL 默认的事务型存储引擎&#xff0c;它支持 ACID 事务、行级锁定和外键约束等特性。 InnoDB 的表数据和索引都被存储在一个称为聚簇索引&#xff08;clustered index&#xff09;的 B树结构中。 在聚簇…

linux系统USB/IP远程共享USB设备 —— 筑梦之路

概述 USB/IP 是一个开源项目&#xff0c;已合入 Kernel&#xff0c;在 Linux 环境下可以通过使用 USB/IP 远程共享 USB 设备。 USB Client&#xff1a;使用USB的终端&#xff0c;将server共享的usb设备挂载到本地。 USB Server&#xff1a;分享本地的usb设备至远程。 架构原理…

归并排序详解(附代码)

归并排序 数据科学家每天都在处理算法。 然而&#xff0c;数据科学学科作为一个整体已经发展成为一个不涉及复杂算法实现的角色。 尽管如此&#xff0c;从业者仍然可以从建立对算法的理解和知识库中受益。 在本文中&#xff0c;对排序算法归并排序进行了介绍、解释、评估和实…

vue3从精通到入门4:diff算法的实现

Vue 3 的 diff 算法相较于 Vue 2 有了一些改进和优化&#xff0c;主要是为了应对更复杂的组件结构和更高的性能需求。 以下是 Vue 3 diff 算法在处理列表更新时的大致步骤&#xff1a; 头头比较&#xff1a;首先&#xff0c;比较新旧列表的头节点&#xff08;即第一个节点&…