C语言_数据结构总结5:顺序栈

纯C语言代码,不涉及C++

想了解链式栈的实现,欢迎查看这篇文章:C语言_数据结构总结6:链式栈-CSDN博客

这里分享插入一下个人觉得很有用的习惯:

1. 就是遇到代码哪里不理解的,你就问豆包,C知道,Kimi等等AI工具,比如在这栈中你不能理解为什么有时候要传一级指针有时候又不用,你就询问AI“在进栈操作中是否可以不传入指针变量,而是直接传入结构体变量”;

2. 还有就是自己的代码报错了,又或是自己觉得自己的代码存在某种问题,而自己又不能解决时,你就直接复制自己的代码问AI,让AI对以下代码进行点评,并返回改善后的代码。

前言

:是只允许在一端进行插入或删除操作的线性表。
栈顶:允许进行插入或删除的那一端
栈底:固定的,不允许进行插入或删除的那一端
栈的特性后进先出
存储方式:1. 顺序存储(顺序栈)  2. 链式存储(链式栈)

       在顺序栈的基本操作中,决定是传入一级指针还是只传入栈的变量,主要取决于操作是否需要修改栈的内部状态
    1. 需要传入一级指针的情况
    当操作需要修改栈的内部状态,比如改变栈顶指针 top 的值或者修改栈中存储的数据时,就需要传入一级指针。
    这是因为在 C 语言里,函数参数传递是值传递,若直接传入栈的变量,函数内部对该变量的修改不会影响到原变量。
    而通过传入指针,函数可以直接访问和修改原变量所指向的内存。

    2. 只需要传入栈的变量的情况
    当操作不需要修改栈的内部状态,仅仅是读取栈的信息时,就可以只传入栈的变量。

以下是顺序栈实现
它利用一组地址连续的存储单元存放自栈底到栈顶的数据元素,同时附设一个指针top指示当前的栈顶元素的位置

0. 结构单元

#define MaxSize 50
typedef int ElemType;
typedef struct SqStack {
    ElemType data[MaxSize];  //存放栈中元素
    int top;  //栈顶指针
}SqStack;

!注意  :栈顶指针top,它不是实际意义上的指针变量,进行存放指针变量。这里说它是指针,意思是说,它指示了当前栈顶元素的位置,在第pos个位置。

1. 初始化

void InitSeqStack(SqStack* s) {s->top = -1;  //初始化栈顶的位置
}

这里设置初始栈顶指针s.top = -1,
栈空条件是s.top = -1;栈满条件是s.top = MaxSize - 1
则进栈时指针s.top+1,再将元素加入栈顶;出栈时先取出栈顶元素,后指针s.top - 1

但如果设置初始栈顶指针s.top = 0,
栈空条件是s.top = 0;栈满条件是s.top = MaxSize
则进栈时将元素加入栈顶,再指针s.top+1;出栈时先指针s.top - 1,后取出栈顶元素

2. 判空

int SqStackEmpty(SqStack s) {return s.top == -1;
}

3. 判满

int SqStackFull(SqStack s) {return s.top == MaxSize - 1;
}

4. 入栈

即:将元素加入到栈顶

int push(SqStack* s, ElemType value) {// 1. 判满if (SqStackFull(*s)){printf("栈满,无法入栈!\n");return -2;}// 2. 指针top + 1,再将值加入到栈顶s->top++;s->data[s->top] = value;return 0;  //入栈成功
}

5. 出栈

int pop(SqStack* s, ElemType* value) {//1. 判空if (SqStackEmpty(*s)){printf("栈空,无法有元素出栈!\n");return -1;}//2. 先取出栈顶元素,再指针top - 1*value = s->data[s->top];s->top--;return 0;  //出栈成功
}

6. 获取栈顶元素

int getTop(SqStack s,ElemType *value) {//1. 判空if (SqStackEmpty(s)){printf("栈空,无法有元素出栈!\n");return -1;}//2. 获取栈顶元素*value = s.data[s.top];return 0;  
}

7. 打印栈中元素

void printSqStack(SqStack s) {if (SqStackEmpty(s)){printf("栈空!\n");return;  //提前结束该函数}printf("栈中的元素(从栈底到栈顶)为: ");for (int i = 0; i <= s.top; i++) {printf("%d ", s.data[i]);}printf("\n");
}

8. 销毁

void destroySqStack(SqStack* s) {// 由于顺序栈使用的是静态数组,不需要显式释放内存// 只需要将栈顶指针置为 -1 表示栈为空s->top = -1;
}

9. 测试

int main() {SqStack s;InitSeqStack(&s);// 测试入栈操作push(&s, 11);push(&s, 22);push(&s, 33);printSqStack(s);  // 栈中的元素(从栈底到栈顶)为: 11 22 33// 获取栈顶元素ElemType value;if (getTop(s,&value) == 0){printf("当前栈顶元素为:%d\n", value); // 当前栈顶元素为:33}//测试出栈操作if (pop(&s,&value) == 0){printf("出栈的元素为:%d\n", value);  // 出栈的元素为:33}printSqStack(s);  // 栈中的元素(从栈底到栈顶)为: 11 22//销毁栈destroySqStack(&s);printSqStack(s);  // 栈空!return 0;
}

10. 完整代码

#include<stdio.h>
#include<stdlib.h>
/*栈:是只允许在一端进行插入或删除操作的线性表。栈顶:允许进行插入或删除的那一端栈底:固定的,不允许进行插入或删除的那一端栈的特性:后进先出存储方式:1. 顺序存储(顺序栈)  2. 链式存储(链式栈)
*//*在顺序栈的基本操作中,决定是传入一级指针还是只传入栈的变量,主要取决于操作是否需要修改栈的内部状态。1. 需要传入一级指针的情况当操作需要修改栈的内部状态,比如改变栈顶指针 top 的值或者修改栈中存储的数据时,就需要传入一级指针。这是因为在 C 语言里,函数参数传递是值传递,若直接传入栈的变量,函数内部对该变量的修改不会影响到原变量。而通过传入指针,函数可以直接访问和修改原变量所指向的内存。2. 只需要传入栈的变量的情况当操作不需要修改栈的内部状态,仅仅是读取栈的信息时,就可以只传入栈的变量。*//*以下是顺序栈实现它利用一组地址连续的存储单元存放自栈底到栈顶的数据元素,同时附设一个指针top指示当前的栈顶元素的位置
*/#define MaxSize 50
typedef int ElemType;
typedef struct SqStack {ElemType data[MaxSize];  //存放栈中元素int top;  //栈顶指针(注意,它不是实际意义上的指针变量,进行存放指针变量。这里说它是指针,意思是说,它指示了当前栈顶元素的位置,在第pos个位置。
}SqStack;// 操作1——初始化
void InitSeqStack(SqStack* s) {s->top = -1;  //初始化栈顶的位置
}/*这里设置初始栈顶指针s.top = -1,栈空条件是s.top = -1;栈满条件是s.top = MaxSize - 1则进栈时指针s.top+1,再将元素加入栈顶;出栈时先取出栈顶元素,后指针s.top - 1但如果设置初始栈顶指针s.top = 0,栈空条件是s.top = 0;栈满条件是s.top = MaxSize则进栈时将元素加入栈顶,再指针s.top+1;出栈时先指针s.top - 1,后取出栈顶元素	
*/// 操作2——判空
int SqStackEmpty(SqStack s) {return s.top == -1;
}// 操作3——判满
int SqStackFull(SqStack s) {return s.top == MaxSize - 1;
}// 操作4——入栈,将元素加到栈顶
int push(SqStack* s, ElemType value) {// 1. 判满if (SqStackFull(*s)){printf("栈满,无法入栈!\n");return -2;}// 2. 指针top + 1,再将值加入到栈顶s->top++;s->data[s->top] = value;return 0;  //入栈成功
}// 操作5——出栈
int pop(SqStack* s, ElemType* value) {//1. 判空if (SqStackEmpty(*s)){printf("栈空,无法有元素出栈!\n");return -1;}//2. 先取出栈顶元素,再指针top - 1*value = s->data[s->top];s->top--;return 0;  //出栈成功
}// 操作6——获取栈顶元素
int getTop(SqStack s,ElemType *value) {//1. 判空if (SqStackEmpty(s)){printf("栈空,无法有元素出栈!\n");return -1;}//2. 获取栈顶元素*value = s.data[s.top];return 0;  
}// 操作7——打印栈中元素
void printSqStack(SqStack s) {if (SqStackEmpty(s)){printf("栈空!\n");return;  //提前结束该函数}printf("栈中的元素(从栈底到栈顶)为: ");for (int i = 0; i <= s.top; i++) {printf("%d ", s.data[i]);}printf("\n");
}// 操作8——销毁栈
void destroySqStack(SqStack* s) {// 由于顺序栈使用的是静态数组,不需要显式释放内存// 只需要将栈顶指针置为 -1 表示栈为空s->top = -1;
}int main() {SqStack s;InitSeqStack(&s);// 测试入栈操作push(&s, 11);push(&s, 22);push(&s, 33);printSqStack(s);  // 栈中的元素(从栈底到栈顶)为: 11 22 33// 获取栈顶元素ElemType value;if (getTop(s,&value) == 0){printf("当前栈顶元素为:%d\n", value); // 当前栈顶元素为:33}//测试出栈操作if (pop(&s,&value) == 0){printf("出栈的元素为:%d\n", value);  // 出栈的元素为:33}printSqStack(s);  // 栈中的元素(从栈底到栈顶)为: 11 22//销毁栈destroySqStack(&s);printSqStack(s);  // 栈空!return 0;
}

11. 运行截图

本人菜鸟一只,文章如有出错处,欢迎评论区指正!

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

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

相关文章

STM32之ADC

逐次逼近式ADC&#xff1a; 左边是8路输入通道&#xff0c;左下是地址锁存和译码&#xff0c;可将通道的地址锁存进ADDA&#xff0c;ADDB&#xff0c;ADDC类似38译码器的结构&#xff0c;ALE为锁存控制键&#xff0c;通道选择开关可控制选择单路或者多路通道&#xff0c;DAC为…

Magento2根据图片文件包导入产品图片

图片包给的图片文件是子产品的图片&#xff0c;如下图&#xff1a;A104255是主产品的sku <?php/*** 根据图片包导入产品图片&#xff0c;包含子产品和主产品* 子产品是作为主图&#xff0c;主产品是作为附加图片*/use Magento\Framework\App\Bootstrap;include(../app/boot…

初学STM32之简单认识IO口配置(学习笔记)

在使用51单片机的时候基本上不需要额外的配置IO&#xff0c;不过在使用特定的IO的时候需要额外的设计外围电路&#xff0c;比如PO口它是没有内置上拉电阻的。因此若想P0输出高电平&#xff0c;它就需要外接上拉电平。&#xff08;当然这不是说它输入不需要上拉电阻&#xff0c;…

图像生成-ICCV2019-SinGAN: Learning a Generative Model from a Single Natural Image

图像生成-ICCV2019-SinGAN: Learning a Generative Model from a Single Natural Image 文章目录 图像生成-ICCV2019-SinGAN: Learning a Generative Model from a Single Natural Image主要创新点模型架构图生成器生成器源码 判别器判别器源码 损失函数需要源码讲解的私信我 S…

STM32之I2C硬件外设

注意&#xff1a;硬件I2C的引脚是固定的 SDA和SCL都是复用到外部引脚。 SDA发送时数据寄存器的数据在数据移位寄存器空闲的状态下进入数据移位寄存器&#xff0c;此时会置状态寄存器的TXE为1&#xff0c;表示发送寄存器为空&#xff0c;然后往数据控制寄存器中一位一位的移送数…

Git - 补充工作中常用的一些命令

Git - 补充工作中常用的一些命令 1 一些场景1.1 场景11.2 场景21.3 场景31.4 场景41.5 场景51.6 场景61.7 场景71.8 场景81.9 场景91.10 场景101.11 场景111.12 场景121.13 场景131.14 场景141.15 场景15 2 git cherry-pick \<commit-hash\> 和 git checkout branch \-\-…

AI 驱动的软件测试革命:从自动化到智能化的进阶之路

&#x1f680;引言&#xff1a;软件测试的智能化转型浪潮 在数字化转型加速的今天&#xff0c;软件产品的迭代速度与复杂度呈指数级增长。传统软件测试依赖人工编写用例、执行测试的模式&#xff0c;已难以应对快速交付与高质量要求的双重挑战。人工智能技术的突破为测试领域注…

Unity--Cubism Live2D模型使用

了解LIVE2D在unity的使用--前提记录 了解各个组件的作用 Live2D Manuals & Tutorials 这些文件都是重要的控制动画参数的 Cubism Editor是编辑Live2D的工具&#xff0c;而导出的数据的类型&#xff0c;需要满足以上的条件 SDK中包含的Cubism的Importer会自动生成一个Pref…

Windows 系统 Docker Desktop 入门教程:从零开始掌握容器化技术

文章目录 前言一、Docker 简介二、Docker Desktop 安装2.1 系统要求2.2 安装步骤 三、Docker 基本概念四、Docker 常用命令五、实战&#xff1a;运行你的第一个容器5.1 拉取并运行 Nginx 容器5.2 查看容器日志5.3 停止并删除容器 六、总结 前言 随着云计算和微服务架构的普及&…

Lab17_ Blind SQL injection with out-of-band data exfiltration

文章目录 前言&#xff1a;进入实验室构造 payload 前言&#xff1a; 实验室标题为&#xff1a; 带外数据泄露的 SQL 盲注 简介&#xff1a; 本实验包含一个SQL盲目注入漏洞。应用程序使用跟踪Cookie进行分析&#xff0c;并执行包含提交的Cookie值的SQL查询。 SQL查询是异…

Vue 框架深度解析:源码分析与实现原理详解

文章目录 一、Vue 核心架构设计1.1 整体架构流程图1.2 模块职责划分 二、响应式系统源码解析2.1 核心类关系图2.2 核心源码分析2.2.1 数据劫持实现2.2.2 依赖收集过程 三、虚拟DOM与Diff算法实现3.1 Diff算法流程图3.2 核心Diff源码 四、模板编译全流程剖析4.1 编译流程图4.2 编…

Linux基本指令

一&#xff1a;Xshell相关快捷键 1.AltEnter进入Xshell全屏模式&#xff0c;再按一次AltEnter退出Xshell全屏模式 2.Ctrl Insert复制 3.Shift Insert粘粘 二&#xff1a;Linux基本指令 1.clear&#xff1a; 清屏&#xff1a;即将屏幕框上的所有内容删除 2.pwd&#xf…

Python基于Django的医用耗材网上申领系统【附源码、文档说明】

博主介绍&#xff1a;✌Java老徐、7年大厂程序员经历。全网粉丝12w、csdn博客专家、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专栏推荐订阅&#x1f447;&…

计算机视觉|3D卷积网络VoxelNet:点云检测的革新力量

一、引言 在科技快速发展的背景下&#xff0c;3D 目标检测技术在自动驾驶和机器人领域中具有重要作用。 在自动驾驶领域&#xff0c;车辆需实时、准确感知周围环境中的目标物体&#xff0c;如行人、车辆、交通标志和障碍物等。只有精确检测这些目标的位置、姿态和类别&#x…

【AD】5-13 特殊粘贴使用

同等间距复制很多过孔 复制之后进行特殊性粘贴&#xff0c;选择阵列粘贴 将元件带位号、带网络从PCB复制粘贴到另一个PCB 全选PCB并复制&#xff0c;来到另一个PCB&#xff0c;点击特殊性粘贴

Unity自定义区域UI滑动事件

自定义区域UI滑动事件 介绍制作1.创建一个Image2.创建脚本 总结 介绍 一提到滑动事件联想到有太多的插件了比如EastTouchBundle&#xff0c;今天想单纯通过UI去做一个滑动事件而不是基于Box2d或者Box去做滑动事件。 制作 1.创建一个Image 2.创建脚本 using UnityEngine; us…

报表DSL优化,享元模式优化过程,优化效果怎么样?

报表DSL优化与享元模式应用详解 一、报表DSL优化 1. 问题背景 报表系统通常使用领域特定语言&#xff08;DSL&#xff09;定义模板结构、数据绑定规则及样式配置。随着复杂度提升&#xff0c;DSL可能面临以下问题&#xff1a; 冗余配置&#xff1a;重复定义样式、布局或数据源…

Python —— pow()函数

一、示例1 # 计算 2 的 3 次幂 result1 pow(2, 3) print(result1) # 输出: 8# 计算 2.5 的 2 次幂 result2 pow(2.5, 2) print(result2) # 输出: 6.25 二、示例2 # 计算 (2 ** 3) % 5 result3 pow(2, 3, 5) print(result3) # 输出: 3 三、示例3 ntxt input("请输…

STM32——GPIO介绍

GPIO(General-Purpose IO ports,通用输入/输出接口)模块是STM32的外设接口的核心部分,用于感知外界信号(输入模式)和控制外部设备(输出模式),支持多种工作模式和配置选项。 1、GPIO 基本结构 STM32F407 的每个 GPIO 引脚均可独立配置,主要特性包括: 9 组 GPIO 端口…

3月8号(信息差)

🌍“星际之门”首个数据中心重磅启航!料部署6.4万块英伟达GB200 🎄全球AI大混战升温!超越Sora的阿里万相大模型开源 家用显卡都能跑 ✨重磅!阿里深夜推出全新推理模型,仅1/20参数媲美DeepSeek R1 1.7B级形式化推理与验证小模型,媲美满血版DeepSeek-R1,全面开源! 研…