【C语言】栈的实现(数据结构)
前言:
还是举一个生活中的例子,大家都玩过积木,当我们把积木叠起来的时候,如果要拿到最底部的积木,我们必须从顶端一个一个打出,最后才能拿到底部的积木,也就是后进先出(先进后出)的道理,今天分享栈的实现的本质也就是后进先出(先进后出)。
目录
前言:
栈的概念及结构
栈的实现
栈的结构定义
初始化栈
压栈(数据的添加)
出栈(数据的删除)
获取栈顶元素
获取栈中有效元素个数
判断栈是否为空
栈实现的总代码(vs2022)
头文件Stack.h
函数文件Stack.c
测试Text.c
栈的概念及结构
要去实现栈,我们要知道什么是 栈,栈的结构是什么,该从什么方向去实现。
如图我们会发现数据进栈出栈后的顺序倒置了,其实栈不只是可以将顺序导致,我们也可以先把A,B放进去,拿出来之后,再将C,D放进去,全部拿出来可以得到C,D,A,B,所以栈最后导致的结果是多种多样的,这取决你如何运用栈了。
栈的实现


栈的结构定义
typedef int STDataType;typedef struct Stack
{ STDataType* a;int top; //栈顶int capacity;//栈容量
}Stack;
栈只需要对栈顶进行操作,所以我们有一个变量top表示栈顶。后面需要判断栈是否为空,我们需要一个变量capacity表示栈容量。
初始化栈
void StackInit(Stack* ps)
{assert(ps);ps->a = (STDataType*)malloc(sizeof(STDataType) * 4);ps->top = 0;ps->capacity = 4;
}
这里我们创造了4个整型变量的空间,所以capacity给4。
压栈(数据的添加)
void StackPush(Stack* ps,STDataType x)
{assert(ps);if (ps->top == ps->capacity)//考虑到空间大小不够,使用realloc进行增容操作{STDataType* tmp = (STDataType*)realloc(ps->a, ps->capacity * 2 * sizeof(STDataType));if (tmp == NULL)//要注意tmp可能为空的情况。{printf("realloc fail!!!");exit(-1);}ps->a = tmp;//别忘了把指针a指向新开辟的空间ps->capacity *= 2;}ps->a[ps->top] = x;ps->top++;//注意个数的增加
}
在压栈的时候要注意几点:
1.压栈时要考虑空间的大小是否足够,不够时要进行增容操作。
2.增容操作后的原指针要指向新指针,保证数据不会丢失。
3.压栈过后要对将top往后移动一位,因为top的指向是数组最后元素的下一个位置。
出栈(数据的删除)
void StackPop(Stack* ps)
{assert(ps);assert(ps->top > 0);//top不能小于或等于0,因为top是指向栈顶元素的下一个位置ps->top--;
}
因为是用数组进行栈的实现,我们只需要把栈顶往前移动一位,就表示删除了数据。
获取栈顶元素
STDataType StackTop(Stack* ps)
{assert(ps);assert(ps->top > 0);return ps->a[ps->top - 1];//因为top是指向栈顶元素的下一个位置,所以要-1}
一定注意对ps->top>0进行断言,保证栈的元素不为空。
获取栈中有效元素个数
int StackSize(Stack* ps)
{assert(ps);return ps->top;}
top指向的数组尾部元素后一位,刚好是数组中有效元素的个数。
判断栈是否为空
bool StackEmpty(Stack* ps)//bool也可以使用 表示真假
{assert(ps);return ps->top == 0;
}
检查栈是否为空,如果不为空则返回0,如果为空则返回非零结果。
栈实现的总代码(vs2022)
头文件Stack.h
#pragma once#include<stdio.h>
#include<stdbool.h>
#include<stdlib.h>
#include<assert.h>
typedef int STDataType;typedef struct Stack
{ STDataType* a;int top; //栈顶int capacity;//栈容量
}Stack;
//初始化栈
void StackInit(Stack* ps);
//栈的销毁
void StackDestory(Stack* ps);
//压栈
void StackPush(Stack* ps,STDataType x);
//出栈
void StackPop(Stack* ps);
//获取栈顶元素
STDataType StackTop(Stack* ps);
//获取栈中有效元素的个数
int StackSize(Stack* ps);
//检查栈是否为空,如果不为空则返回0,如果为空则返回非零结果
bool StackEmpty(Stack* ps);//bool也可以使用 表示真假
函数文件Stack.c
#include"Stack.h"void StackInit(Stack* ps)
{assert(ps);ps->a = (STDataType*)malloc(sizeof(STDataType) * 4);ps->top = 0;ps->capacity = 4;
}
void StackDestory(Stack* ps)
{assert(ps);free(ps->a);ps->a = NULL;ps->top = ps->capacity = 0;}
//入栈
void StackPush(Stack* ps,STDataType x)
{assert(ps);if (ps->top == ps->capacity)//考虑到空间大小不够,使用realloc进行增容操作{STDataType* tmp = (STDataType*)realloc(ps->a, ps->capacity * 2 * sizeof(STDataType));if (tmp == NULL)//要注意tmp可能为空的情况。{printf("realloc fail!!!");exit(-1);}ps->a = tmp;//别忘了把指针a指向新开辟的空间ps->capacity *= 2;}ps->a[ps->top] = x;ps->top++;//注意个数的增加
}
void StackPop(Stack* ps)
{assert(ps);assert(ps->top > 0);//top不能小于或等于0,因为top是指向栈顶元素的下一个位置ps->top--;
}
STDataType StackTop(Stack* ps)
{assert(ps);assert(ps->top > 0);return ps->a[ps->top - 1];//因为top是指向栈顶元素的下一个位置,所以要-1}
int StackSize(Stack* ps)
{assert(ps);return ps->top;}
bool StackEmpty(Stack* ps)//bool也可以使用 表示真假
{assert(ps);return ps->top == 0;
}
测试Text.c
#include"Stack.h"void StackText()
{Stack st;StackInit(&st);StackPush(&st, 1);StackPush(&st, 2);StackPush(&st, 3);StackPush(&st, 4);StackPush(&st, 5);while (!StackEmpty(&st)){printf("%d ", StackTop(&st));StackPop(&st);}StackDestory(&st);
}int main()
{StackText();return 0;
}
好啦,这就是今天学习的分享啦!看到希望大家的三连呀!
如果有不当之处,欢迎大佬指正!
相关文章:
【C语言】栈的实现(数据结构)
前言: 还是举一个生活中的例子,大家都玩过积木,当我们把积木叠起来的时候,如果要拿到最底部的积木,我们必须从顶端一个一个打出,最后才能拿到底部的积木,也就是后进先出(先进后出&a…...
前端三大主流框架对比
在现代前端开发中,React、Vue和Angular是三大流行的框架/库。它们各自有独特的优缺点,适用于不同的开发需求和项目规模。下面是对这三者的详细比较: 一、 React 简介: 由Facebook开发和维护,是一个用于构建用户界面…...
AOP~面向切面编程介绍
AOP基础 概述 AOP:Aspect Oriented Programming(面向切面编程、面向方面编程),面向特定方法的编程。 动态代理是面向切面编程最主流的实现。 SpringAOP是Spring框架的高级技术,旨在管理bean对象的过程中,…...
Android SurfaceFlinger——GraphicBuffer的提交(三十三)
在 SurfaceFlinger 中,我们 dequeueBuffer 和 queueBuffer 是 Surface 控制接口中非常重要的两个函数,分别用于从 Surface 的 BufferQueue 中取出缓冲区和向 BufferQueue 提交(队列)缓冲区。这两个函数在生产者和消费者模型中扮演着核心角色,确保了图像数据的高效和有序传…...
创维汽车滁州永通体验中心开业仪式暨超充车型区域上市会圆满成功
2024年7月20日,创维汽车滁州永通体验中心盛大开业,当日,创维汽车市场部经理周世鹏、安徽大区总监王大明等领导参加本次开业盛典,共同见证创维汽车滁州永通体验中心成功落地。 2021年,新能源乘用车高速发展,…...
【PHP】系统的登录和注册
一、为什么要学习系统的登录和注册 系统的登录和注册可能存在多种漏洞,这些漏洞可能被恶意攻击者利用,从而对用户的安全和隐私构成威胁。通过学习系统的登录和注册理解整个登录和注册的逻辑方便后续更好站在开发的角度思考问题发现漏洞。以下是一些常见…...
2024.7.29 刷题总结
2024.7.29 **每日一题** 682.棒球比赛,这道题是一道简单的模拟题,用栈模拟题中的四个操作就可以了,操作一是将x加到列表末尾,操作二是将列表的后两项之和加到列表末尾,操作三是把列表最后一项的两倍加到列表末尾&#…...
WebSocket程序设计
协议说明 WebSocket 是一种在单个TCP连接上进行全双工通信的协议。WebSocket 使得客户端和服务器之间的数据交换变得更加简单,允许服务端主动向客户端推送数据。Websocket主要用在B/S架构的应用程序中,在 WebSocket API 中,浏览器和服务器只…...
ES(ElasticSearch)倒排索引
目录 正排与倒排索引 1.正排索引 作用: 优点: 缺点: 2.倒排索引 原理: 倒排索引的构建流程: 倒排索引的搜索流程: 优点: 缺点: 3. 应用场景 倒排索引中有几个非常重要的概念…...
Android Studio Build窗口出现中文乱码问题
刚安装成功的android studio软件打开工程,编译时下方build窗口中中文是乱码。 解决: 可点击studio状态栏的Help—>Edit Custom VM Options ,在打开的studio64.exe.vmoptions文件后面添加:(要注意不能有空格,否则st…...
java生成随机数
代码 startValue 开始值 endValue 结束值 per生成的位数也就是精度 /*** 随机数的生成* param startValue* param endValue* return*/private BigDecimal randomBigDecimal(String startValue, String endValue,int per) {BigDecimal min new BigDecimal(startValue);BigDeci…...
动态定制深度学习:Mojo模型与自定义训练算法的无缝切换
动态定制深度学习:Mojo模型与自定义训练算法的无缝切换 引言 在机器学习领域,算法的选择对模型的性能有着决定性的影响。随着研究的深入和技术的发展,开发者可能需要根据不同的数据特性和业务需求,动态地切换或自定义训练算法。…...
昇思25天学习打卡营第19天|DCGAN生成漫画头像
DCGAN生成漫画头像总结 实验概述 本实验旨在利用深度卷积生成对抗网络(DCGAN)生成动漫头像,通过设置网络、优化器以及损失函数,使用MindSpore进行实现。 实验目的 学习和掌握DCGAN的基本原理和应用。熟悉使用MindSpore进行图像…...
排序题目:按照频率将数组升序排序
文章目录 题目标题和出处难度题目描述要求示例数据范围 解法思路和算法代码复杂度分析 题目 标题和出处 标题:按照频率将数组升序排序 出处:1636. 按照频率将数组升序排序 难度 3 级 题目描述 要求 给定一个整数数组 nums \texttt{nums} nums&a…...
实分析与测度论问题的分类
实分析主要研究实数、实数序列、实数极限以及实值函数的分析,而度量空间则是一个具有距离函数的集合,其分类可以从多个角度进行。 实分析 实分析主要关注实数、实数序列、实数极限以及实值函数的分析。它涉及到多个重要的概念和理论,包括但…...
动态代理更改Java方法的返回参数(可用于优化feign调用后R对象的统一处理)
动态代理更改Java方法的返回参数(可用于优化feign调用后R对象的统一处理) 需求原始解决方案优化后方案1.首先创建AfterInterface.java2.创建InvocationHandler处理代理方法3. 调用 实际运行场景拓展 需求 某些场景,调用别人的方法࿰…...
Redis缓存数据库进阶——Redis与分布式锁(6)
分布式锁简介 1. 什么是分布式锁 分布式锁是一种在分布式系统环境下,通过多个节点对共享资源进行访问控制的一种同步机制。它的主要目的是防止多个节点同时操作同一份数据,从而避免数据的不一致性。 线程锁: 也被称为互斥锁(Mu…...
网络芯片(又称为PHY网络芯片)
Realtek RTL8152B是一种常见的主板集成网络芯片(又称为PHY网络芯片)。PHY芯片是指将网络控制芯片的运算部分交由处理器或南桥芯片处理,以简化线路设计,从而降低成本。 https://www.realtek.com/Download/List?cate_id585 Realt…...
01 Go Web基础_20240728 课程笔记
概述 如果您没有Golang的基础,应该学习如下前置课程。 基础不好的同学每节课的代码最好配合视频进行阅读和学习,如果基础比较扎实,则阅读本教程巩固一下相关知识点即可,遇到不会的知识点再看视频。 视频课程 最近发现越来越多…...
嵌入式学习Day12---C语言提升
目录 一、指针数组 1.1.什么是指针数组 2.2. 格式 2.3.存储 2.4.与字符型二维数组相比 2.5.什么时候使用指针数组 2.6.练习 二、数组指针 2.1.什么是数组指针 2.2.格式 2.3.一维数组 2.3.特点 2.4.什么时候使用 三、指针和数组的关系 3.1.一维数组和指针 …...
RocketMQ延迟消息机制
两种延迟消息 RocketMQ中提供了两种延迟消息机制 指定固定的延迟级别 通过在Message中设定一个MessageDelayLevel参数,对应18个预设的延迟级别指定时间点的延迟级别 通过在Message中设定一个DeliverTimeMS指定一个Long类型表示的具体时间点。到了时间点后…...
Java 语言特性(面试系列1)
一、面向对象编程 1. 封装(Encapsulation) 定义:将数据(属性)和操作数据的方法绑定在一起,通过访问控制符(private、protected、public)隐藏内部实现细节。示例: public …...
Robots.txt 文件
什么是robots.txt? robots.txt 是一个位于网站根目录下的文本文件(如:https://example.com/robots.txt),它用于指导网络爬虫(如搜索引擎的蜘蛛程序)如何抓取该网站的内容。这个文件遵循 Robots…...
【论文阅读28】-CNN-BiLSTM-Attention-(2024)
本文把滑坡位移序列拆开、筛优质因子,再用 CNN-BiLSTM-Attention 来动态预测每个子序列,最后重构出总位移,预测效果超越传统模型。 文章目录 1 引言2 方法2.1 位移时间序列加性模型2.2 变分模态分解 (VMD) 具体步骤2.3.1 样本熵(S…...
JavaScript基础-API 和 Web API
在学习JavaScript的过程中,理解API(应用程序接口)和Web API的概念及其应用是非常重要的。这些工具极大地扩展了JavaScript的功能,使得开发者能够创建出功能丰富、交互性强的Web应用程序。本文将深入探讨JavaScript中的API与Web AP…...
Ubuntu系统多网卡多相机IP设置方法
目录 1、硬件情况 2、如何设置网卡和相机IP 2.1 万兆网卡连接交换机,交换机再连相机 2.1.1 网卡设置 2.1.2 相机设置 2.3 万兆网卡直连相机 1、硬件情况 2个网卡n个相机 电脑系统信息,系统版本:Ubuntu22.04.5 LTS;内核版本…...
消息队列系统设计与实践全解析
文章目录 🚀 消息队列系统设计与实践全解析🔍 一、消息队列选型1.1 业务场景匹配矩阵1.2 吞吐量/延迟/可靠性权衡💡 权衡决策框架 1.3 运维复杂度评估🔧 运维成本降低策略 🏗️ 二、典型架构设计2.1 分布式事务最终一致…...
若依登录用户名和密码加密
/*** 获取公钥:前端用来密码加密* return*/GetMapping("/getPublicKey")public RSAUtil.RSAKeyPair getPublicKey() {return RSAUtil.rsaKeyPair();}新建RSAUti.Java package com.ruoyi.common.utils;import org.apache.commons.codec.binary.Base64; im…...
java高级——高阶函数、如何定义一个函数式接口类似stream流的filter
java高级——高阶函数、stream流 前情提要文章介绍一、函数伊始1.1 合格的函数1.2 有形的函数2. 函数对象2.1 函数对象——行为参数化2.2 函数对象——延迟执行 二、 函数编程语法1. 函数对象表现形式1.1 Lambda表达式1.2 方法引用(Math::max) 2 函数接口…...
深入浅出WebGL:在浏览器中解锁3D世界的魔法钥匙
WebGL:在浏览器中解锁3D世界的魔法钥匙 引言:网页的边界正在消失 在数字化浪潮的推动下,网页早已不再是静态信息的展示窗口。如今,我们可以在浏览器中体验逼真的3D游戏、交互式数据可视化、虚拟实验室,甚至沉浸式的V…...

