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. 运行截图

本人菜鸟一只,文章如有出错处,欢迎评论区指正!
相关文章:
C语言_数据结构总结5:顺序栈
纯C语言代码,不涉及C 想了解链式栈的实现,欢迎查看这篇文章:C语言_数据结构总结6:链式栈-CSDN博客 这里分享插入一下个人觉得很有用的习惯: 1. 就是遇到代码哪里不理解的,你就问豆包,C知道&a…...
人工智能之数学基础:正交矩阵
本文重点 正交矩阵是线性代数中一个重要的特殊矩阵,它在许多领域都有广泛的应用。 什么是正交矩阵 如图所示,当矩阵A满足如上所示的条件的时候,此时我们就可以认为是正交矩阵,需要注意一点矩阵A必为方阵。 正交矩阵的充要条件 …...
前端打包优化相关 Webpack
前端打包优化相关 Webpack 打包时间的优化(基于 Vue CLI 4 Webpack 5) 1. Webpack 配置减少打包时间 1.1 对 JS 配置:排除 node_modules 和 src 中的打包内容 在开发环境下,修改 Webpack 的 JS 规则,排除 /node_m…...
抓包分析工具介绍
什么是抓包分析工具? 抓包分析工具,也称为网络数据包嗅探器或协议分析器,用于捕获和检查网络上传输的数据包。这些数据包包含了网络通信的详细信息,例如请求的资源、服务器的响应、HTTP 头信息、传输的数据内容等等。通过分析这些…...
Linux第一课
一、Linux背景与发展 1. 发展史 1968年,研究人员开发了Multics操作系统,为后续发展奠定了基础。 1969−1970年,Ken Thompson和Dennis Ritchie在Multics基础上开发了UNIX系统。 1991年,Linus Torvalds发布了Linux操作系统&#…...
2025/3/8 第 27 场 蓝桥入门赛 题解
1. 38红包【算法赛】 签到题: 算倍数就行了 #include <bits/stdc.h> using namespace std; int main() {int ans0;for(int i1;i<2025;i){if(i % 3 0)ans;else if(i % 8 0)ans;else if(i % 38 0)ans;}cout<<ans<<endl;return 0; } 2. 祝福…...
使用Node.js从零搭建DeepSeek本地部署(Express框架、Ollama)
目录 1.安装Node.js和npm2.初始化项目3.安装Ollama4.下载DeepSeek模型5.创建Node.js服务器6.运行服务器7.Web UI对话-Chrome插件-Page Assist 1.安装Node.js和npm 首先确保我们机器上已经安装了Node.js和npm。如果未安装,可以通过以下链接下载并安装适合我们操作系…...
deepseek 3FS编译
3FS在ubuntu22.04下的编译(记录下编译过程,方便后续使用) 环境信息 OS ubuntu 22.04内核版本 6.8.0-52-genericlibfuse 3.16.1rust 1.75.0FoundationDB 7.1.66meson 1.0.0ninja 1.10.1 libfuse编译 以下建议均在root下执行 pip3 install…...
网安知识点
1.SQL注入漏洞产生的原因是? 前端传到后端的数据,没有经过任何处理,直接当作sql语句的一部分来执行 2.讲一下sql注入,写入webshell需要哪些前提条件 开启导入导出权限secure-file-priv 站点根目录位置/路径 mysql用户对站点根目…...
UniApp 运行的微信小程序如何进行深度优化
UniApp 运行的微信小程序如何进行深度优化 目录 引言性能优化 1. 减少包体积2. 优化页面加载速度3. 减少 setData 调用4. 使用分包加载 代码优化 1. 减少不必要的代码2. 使用条件编译3. 优化图片资源 用户体验优化 1. 优化交互体验2. 预加载数据3. 使用骨架屏 调试与监控 1. …...
leetcode-sql数据库面试题冲刺(高频SQL五十题)
题目: 577.员工奖金 表:Employee -------------------- | Column Name | Type | -------------------- | empId | int | | name | varchar | | supervisor | int | | salary | int | -------------------- empId 是该表中具有唯一值的列。 该表的每一行…...
图片分类实战:食物分类问题(含半监督)
食物分类问题 simple_class 1. 导入必要的库和模块 import random import torch import torch.nn as nn import numpy as np import os from PIL import Image #读取图片数据 from torch.utils.data import Dataset, DataLoader from tqdm import tqdm from torchvision impo…...
Java初级入门学习
JAVA学习 @[TOC](JAVA学习)**一、Java初级入门学习路径****1. Java基础语法****2. 面向对象编程(OOP)****3. 数据库与JDBC****4. Java Web基础****二、主流框架推荐与学习建议****1. Spring框架****2. Spring MVC****3. MyBatis****4. Spring Boot****三、后续学习建议****1.…...
每日一练之移除链表元素
题目: 画图解析: 方法:双指针 解答代码(注:解答代码带解析): //题目给的结构体 /*** Definition for singly-linked list.* struct ListNode {* int val;* struct ListNode *next;* }…...
BM25原理概述
1️⃣设定:对于查询 Q { q 1 , q 2 , . . . , q n } Q\text{}\{q_1,q_2,...,q_n\} Q{q1,q2,...,qn}和段落集 P { P ( 1 ) , P ( 2 ) , … , P ( N ) } \mathscr{P}\text{}\left\{P^{(1)},P^{(2)},\ldots,P^{(\text{N})}\right\} P{P(1),P(2),…,P(N)}&#…...
PAT乙级真题(2014·冬)
大纲 1031、查验身份证-(解析)-简单题 1032、挖掘机技术哪家强-(解析)-细节题(┬┬﹏┬┬),太抠细节了 1033、旧键盘打字-(解析)-输入格式!这才是重点(┬┬﹏┬┬),让…...
力大砖飞,纯暴力搜索——蓝桥p2110(写着玩的)
#include<bits/stdc.h>const int N1000000;using namespace std;bool mp[2][N];int cnt0; int n;void dfs(int row,int col){cntcnt%1000000007;if(coln && row2){cnt;return ;}if(row>2){ //下一列 dfs(0,col1);return;}if(mp[row][col]1){ //下一行 dfs(row…...
如何计算两个向量的余弦相似度
参考笔记: https://zhuanlan.zhihu.com/p/677639498 日常学习之:如何计算两个向量或者矩阵的余弦相似度-CSDN博客 1.余弦相似度定理 百度的解释:余弦相似度,又称为余弦相似性,是通过计算两个向量的夹角余弦值来评估…...
OkHttp:工作原理 拦截器链深度解析
目录 一、OKHttp 的基本使用 1. 添加依赖 2. 发起 HTTP 请求 3. 拦截器(Interceptor) 4. 高级配置 二、OKHttp 核心原理 1. 责任链模式(Interceptor Chain) 2. 连接池(ConnectionPool) 3. 请求调度…...
python: DDD+ORM using oracle 21c
sql script: create table GEOVINDU.School --創建表 ( SchoolId char(5) NOT NULL, -- SchoolName nvarchar2(500) NOT NULL, SchoolTelNo varchar(8) NULL, PRIMARY KEY (SchoolId) --#主鍵 );create table GEOVINDU.Teacher ( TeacherId char(5) NOT NULL , TeacherFirstNa…...
基于 LeNet 网络的 MNIST 数据集图像分类
1.LeNet的原始实验数据集MNIST 名称:MNIST手写数字数据集 数据类型:灰度图 (一通道) 图像大小:28*28 类别数:10类(数字0-9) 1.通过torchvision.datasets.MNIST下载并保存到本地…...
Day4 C语言与画面显示练习
文章目录 1. harib01a例程2. harib01b例程3. harib01e例程4. harib01f例程5. harib01h例程 1. harib01a例程 上一章主要是将画面搞成黑屏,如果期望做点什么图案,只需要再VRAM里写点什么就好了,使用nask汇编语言实现一个函数write_mem8&#…...
一周热点-OpenAI 推出了 GPT-4.5,这可能是其最后一个非推理模型
在人工智能领域,大型语言模型一直是研究的热点。OpenAI 的 GPT 系列模型在自然语言处理方面取得了显著成就。GPT-4.5 是 OpenAI 在这一领域的又一力作,它在多个方面进行了升级和优化。 1 新模型的出现 GPT-4.5 目前作为研究预览版发布。与 OpenAI 最近的 o1 和 o3 模型不同,…...
《UE5_C++多人TPS完整教程》学习笔记34 ——《P35 网络角色(Network Role)》
本文为B站系列教学视频 《UE5_C多人TPS完整教程》 —— 《P35 网络角色(Network Role)》 的学习笔记,该系列教学视频为计算机工程师、程序员、游戏开发者、作家(Engineer, Programmer, Game Developer, Author) Stephe…...
手写简易Tomcat核心实现:深入理解Servlet容器原理
目录 一、Tomcat概况 1. tomcat全局图 2.项目结构概览 二、实现步骤详解 2.1 基础工具包(com.qcby.util) 2.1.1 ResponseUtil:HTTP响应生成工具 2.1.2 SearchClassUtil:类扫描工具 2.1.3 WebServlet:自定义注解…...
ES Filter Query 区别
在 Elasticsearch(ES) 中,Filter 和 Query 是两种常用的数据检索方式,它们的主要区别在于 是否计算相关性分数(Score) 以及 是否使用缓存。以下是它们的详细区别和应用场景: 1. 核心区别 特性F…...
Java多线程与高并发专题——关于CopyOnWrite 容器特点
引入 在 CopyOnWriteArrayList 出现之前,我们已经有了 ArrayList 和 LinkedList 作为 List 的数组和链表的实现,而且也有了线程安全的 Vector 和Collections.synchronizedList() 可以使用。 首先我们来看看Vector是如何实现线程安全的 ,还是…...
春节面对大流量并发,系统该如何设计
基于6个层次进行系统设计以解决大流量瞬时并发问题:CDN层,Nginx层,服务层,缓存层,数据库层,全链路压测监控。以下为具体设计参考 1. CDN(内容分发网络) 作用:静态资源&…...
mac本地安装运行Redis-单机
记录一下我以前用的连接服务器的跨平台SSH客户端。 因为还要准备毕设...... 服务器又过期了,只能把redis安装下载到本地了。 目录 1.github下载Redis 2.安装homebrew 3.更新GCC 4.自行安装Redis 5.通过 Homebrew 安装 Redis 安装地址:https://git…...
77.ObservableCollection使用介绍1 C#例子 WPF例子
可观察集合ObservableCollection using System; using System.Collections.ObjectModel;class Program {static void Main(){// 创建一个可观察集合ObservableCollection<string> list new ObservableCollection<string>();// 注册集合变化事件list.CollectionCh…...
