【C】初阶数据结构5 -- 栈
前面学习了两种最基本的数据结构 -- 顺序表和链表,接下来就可以基于这两种数据结构来实现其他数据结构了。其实,其他的数据结构的物理结构要么是数组,要么就是链表,所以学好顺序表和链表是学好其他数据结构的基础。接下里,我们就来看一个新的数据结构 -- 栈。
目录
1 栈的概念与特点
2 栈的结构
1) 逻辑结构
2) 物理结构
3 栈的基本操作的实现
1) 初始化和销毁
2) 入栈与出栈、
(1) 入栈
(2) 出栈
3) 取栈顶元素、判空、获取有效元素个数
4 代码
重点一 栈的特点
1 栈的概念与特点
栈:一种特殊的线性表,其只允许在一端进行插入和删除数据。插入和删除数据的一端叫做栈顶,另一端叫做栈底。
入栈(压栈):往栈中插入数据的操作叫做入栈。
出栈:栈中删除数据的操作叫做出栈。
特点:栈中的数据遵循LIFO原则(last in first out),也就是后进先出原则。
栈的特点特别重要,一般使用栈都是因为其后进先出的特点,下面来做一个题来理解一下其后进先出的特点:
假设有一个栈,数据入栈的先后顺序为 a b c d e ,请在以下选项中选出错误的出栈顺序()A. a b c d e B. c b d a eC. d b c a e D. e d c b a
该题的正确答案为 C,因为如果 d 先出栈的话,说明 a,b,c 均以入栈,如何要接着出栈的话,应是 c 先出栈,而不是 b 先出栈。
需要注意的一点就是,出栈顺序并不是等数据全部入栈之后才能出栈。比如 A 选项,就是入栈一个数据,然后出栈一个数据。
重点二 栈的结构
2 栈的结构
1) 逻辑结构
我们可以把栈想象成以下的一个结构:

2) 物理结构
栈的物理结构既可以选择用链式结构来实现,也可以选择用数组,也就是顺序表来实现。这里选择使用数组来实现,因为栈后进先出的特性,规定了其只能在尾部进行插入和删除数据,而对于顺序表来说,在尾部插入和删除数据又十分方便,所以这里选择使用顺序表来实现栈。
既然是使用顺序表来实现栈,所以栈的结构和顺序表十分相似,只不过就是把 size 变为了 top,用来表示栈的顶部元素的位置:
//将int定义为栈里面的数据类型
typedef int STDataType;
//栈的结构
typedef struct Stack
{STDataType* arr;//栈中的存放数据的数组int capacity;//栈的容量大小int top;//栈顶
}ST;
重点三 实现栈
3 栈的基本操作的实现
对于一个栈来说,其主要操作只有入栈、出栈、取栈顶元素、初始化、销毁、判空、获取有效元素个数。
1) 初始化和销毁
栈的初始化和销毁与顺序表可以说是一模一样,这里就不做多余讲解,可以去回顾一下顺序表(也可以看下面代码理解一下)。
2) 入栈与出栈、
(1) 入栈
入栈的操作就相当于顺序表中的尾差,其基本过程如图所示:

可以看到,就是顺序表的尾插操作,只不过就是把 size 变成了 capacity 而已。
(2) 出栈
出栈就是顺序表的尾删,所以只需要让 --top 就可以了。
3) 取栈顶元素、判空、获取有效元素个数
这3个操作的实现都很简单。取栈顶元素就是返回 arr 数组中 top - 1 下标的数据,但要注意栈要非空,才能返回栈顶元素,所以要先对栈是否为空断言;判空就是判断 top 是否等于0;获取有效元素个数就是返回 top 。
4 代码
Stack.h文件:
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include<stdbool.h>typedef int STDataType;
typedef struct Stack
{STDataType* arr;int capacity;int top;
}ST;//初始化
void STInit(ST* ps);
//销毁
void STDestroy(ST* ps);
//入栈
void STPush(ST* ps, STDataType x);
//出栈
void STPop(ST* ps);
//取栈顶元素
STDataType STTop(ST* ps);
//获取栈中有效元素个数
int STSize(ST* ps);
//栈是否为空
bool STEmpty(ST* ps);
Stack.c文件:
#include"Stack.h"//初始化
void STInit(ST* ps)
{assert(ps);ps->arr = NULL;ps->capacity = ps->top = 0;
}//销毁
void STDestroy(ST* ps)
{assert(ps);free(ps->arr);ps->arr = NULL;ps->capacity = ps->top = 0;
}//入栈
void STPush(ST* ps, STDataType x)
{//相当于顺序表的尾插assert(ps);//如果数组满了。需要增容if (ps->capacity == ps->top){int newCapacity = ps->capacity == 0 ? 4 : 2 * ps->capacity;STDataType* tmp = (STDataType*)realloc(ps->arr, sizeof(STDataType) * newCapacity);if (tmp == NULL){perror("realloc fail!\n");exit(1);}ps->arr = tmp;ps->capacity = newCapacity;}//不要忘记让top++ps->arr[ps->top++] = x;
}
//栈是否为空
bool STEmpty(ST* ps)
{assert(ps);//判断top是否为0就可以了return ps->top == 0;
}
//出栈
void STPop(ST* ps)
{//相当于顺序表的尾删assert(!STEmpty(ps));--ps->top;
}//取栈顶元素
STDataType STTop(ST* ps)
{assert(ps);//栈不能为空assert(!STEmpty(ps));//只取栈顶元素,不删除数据int pos = ps->top - 1;return ps->arr[pos];
}//获取栈中有效元素个数
int STSize(ST* ps)
{assert(ps);return ps->top;
}
test.c文件:
#include"Stack.h"
void Test4()
{ST st;STInit(&st);//测试入栈STPush(&st, 1);STPush(&st, 2);STPush(&st, 3);STPush(&st, 4);for (int i = 0; i < st.top; i++){printf("%d ", st.arr[i]);}printf("\n");//测试出栈与取栈顶元素STPop(&st);STPop(&st);STPop(&st);STPop(&st);//STPop(&st);/*int ret = STTop(&st);printf("%d ", ret);printf("\n");for (int i = 0; i < st.top; i++){printf("%d ", st.arr[i]);}printf("\n");*/bool ret1 = STEmpty(&st);if (ret1){printf("栈为空!\n");}else{printf("栈不为空!\n");}int ret = STSize(&st);printf("%d ", ret);STDestroy(&st);
}
int main()
{Test4();return 0;
}
可以看到实现栈,其实就是实现顺序表的部分接口,学好顺序表和链表是实现其他数据结构的基础。所以一定要把基础学扎实,才能越学越好。
相关文章:
【C】初阶数据结构5 -- 栈
前面学习了两种最基本的数据结构 -- 顺序表和链表,接下来就可以基于这两种数据结构来实现其他数据结构了。其实,其他的数据结构的物理结构要么是数组,要么就是链表,所以学好顺序表和链表是学好其他数据结构的基础。接下里…...
闭源大语言模型的怎么增强:提示工程 检索增强生成 智能体
闭源大语言模型的怎么增强 提示工程 检索增强生成 智能体 核心原理 提示工程:通过设计和优化提示词,引导大语言模型进行上下文学习和分解式思考,激发模型自身的思维和推理能力,使模型更好地理解和生成文本,增强其泛用性和解决问题的能力。检索增强生成:结合检索的准确…...
C语言-------结构体(1)
数据类型 (1)基本数据类型 整型 浮点型 字符型 (2)构造类型 数组 结构体 结构体: 用来处理,现实生活中,更复杂的数据的描述 用来 描述复杂数据的 一种用户自定义的数…...
org.apache.kafka.common.errors.TimeoutException
个人博客地址:org.apache.kafka.common.errors.TimeoutException | 一张假钞的真实世界 使用kafka-console-producer.sh向远端Kafka写入数据时遇到以下错误: $ bin/kafka-console-producer.sh --broker-list 172.16.72.202:9092 --topic test This is …...
Ceph集群搭建2025(squid版)
squid版本维护年限 apt install -y cephadmecho >> "deb http://mirrors.163.com/ceph/debian-squid/ bookworm main" echo >> "deb-src http://mirrors.163.com/ceph/debian-squid/ bookworm main"#安装源 cephadm install #开始初始化一个最…...
DeepSeek从入门到精通:提示词设计的系统化指南
目录 引言:AIGC时代的核心竞争力 第一部分 基础篇:提示词的本质与核心结构 1.1 什么是提示词? 1.2 提示词的黄金三角结构 第二部分 类型篇:提示词的六大范式 2.1 提示语的本质特征 2.2 提示语的类型 2.2.1 指令型提示词 …...
python后端调用Deep Seek API
python后端调用Deep Seek API 需要依次下载 ●Ollama ●Deepseek R1 LLM模型 ●嵌入模型nomic-embed-text / bge-m3 ●AnythingLLM 参考教程: Deepseek R1打造本地化RAG知识库:安装部署使用详细教程 手把手教你:deepseek R1基于 AnythingLLM API 调用本地…...
自有证书的rancher集群使用rke部署k8s集群异常
rancher使用自签域名,或者商业证书容易踩到的坑。 最开始的报错: docker logs kubelet‘s id E0214 13:04:14.590268 9614 pod_workers.go:1300] "Error syncing pod, skipping" err"failed to \"StartContainer\" for …...
【线性代数】1行列式
1. 行列式的概念 行列式的符号表示: 行列式的计算结果:一个数 计算模型1:二阶行列式 二阶行列式: 三阶行列式: n阶行列式: 🍎计算行列式 计算模型2:上三角形行列式 上三角形行列式特征:主对角线下皆为0。 上三角形行列式: 化上三角形通用方法:主对角线下,…...
DeepSeek免费部署到WPS或Office
部署到WPS - 通过OfficeAI插件接入: - 准备工作:安装最新版本的WPS Office软件;访问DeepSeek官网,点击右上角的“API开放平台”,登录账号(若无账号需先注册),登录成功后,…...
数据结构 二叉树
一、⼆叉树的定义 ⼆叉树是⼀种特殊的树型结构,它的特点是每个结点⾄多只有2棵⼦树(即⼆叉树中不存在度⼤于2的结点),并且⼆叉树的⼦树有左右之分,其次序不能任意颠倒。 ⼆叉的意思是这种树的每⼀个结点最多只有两个孩…...
鸿蒙开发:熟知@BuilderParam装饰器
前言 本文代码案例基于Api13。 在实际的开发中,我们经常会遇到自定义组件的情况,比如通用的列表组件,选项卡组件等等,由于使用方的样式不一,子组件是动态变化的,针对这一情况,就不得不让使用方把…...
光谱相机在天文学领域的应用
天体成分分析 恒星成分研究:恒星的光谱包含了其大气中各种元素的吸收和发射线特征。通过光谱相机精确测量这些谱线,天文学家能确定恒星大气中氢、氦、碳、氮、氧等元素的含量。如对太阳的光谱分析发现,太阳大气中氢元素占比约 71%࿰…...
不到1M的工具,使用起来非常丝滑!
今天给大家推荐两款电脑上超实用的小软件,分别是倒计时工具和关机助手,用起来特别顺手,希望能帮到大家。 关机助手 帮你自动关机 先说说关机助手。这款软件简直太方便了!它是一款免安装的小工具,体积超小,…...
软考高级《系统架构设计师》知识点(二)
操作系统知识 操作系统概述 操作系统定义:能有效地组织和管理系统中的各种软/硬件资源,合理地组织计算机系统工作流程,控制程序的执行,并且向用户提供一个良好的工作环境和友好的接口。操作系统有三个重要的作用: 管理…...
深入解析操作系统控制台:阿里云Alibaba Cloud Linux(Alinux)的运维利器
作为一位个人开发者兼产品经理,我的工作日常紧密围绕着云资源的运维和管理。在这个过程中,操作系统扮演了至关重要的角色,而操作系统控制台则成为了我们进行系统管理的得力助手。本文将详细介绍阿里云的Alibaba Cloud Linux操作系统控制台的功…...
云原生AI Agent应用安全防护方案最佳实践(上)
当下,AI Agent代理是一种全新的构建动态和复杂业务场景工作流的方式,利用大语言模型(LLM)作为推理引擎。这些Agent代理应用能够将复杂的自然语言查询任务分解为多个可执行步骤,并结合迭代反馈循环和自省机制࿰…...
Java Virtual Machine(JVM)
JVM跨平台原理 跨平台:一次编译,到处运行 本质:不同操作系统上运行的JVM不一样,只需要把java程序编译成一份字节码文件,JVM执行不同的字节码文件。 Java是高级语言,提前编译一下(变成字节码文件…...
vue前端可视化大屏页面适配方案
参考了其他博主的代码,但发现会有滚动条,并且居中的位置不太对,所以改了一下css,修复了这些问题,直接上代码 <template> <div class"ScaleBoxA"><divclass"ScaleBox"ref"Sca…...
Docker中安装MySql方法
使用Docker安装MySQL的详细步骤,涵盖单机部署、数据持久化、网络配置等内容: 1. 安装Docker 如果尚未安装Docker,请先安装: Windows/macOS:下载 Docker Desktop 并安装。 Linux: curl -fsSL https://get.docker.com | bash sudo systemctl start docker sudo system…...
C++:std::is_convertible
C++标志库中提供is_convertible,可以测试一种类型是否可以转换为另一只类型: template <class From, class To> struct is_convertible; 使用举例: #include <iostream> #include <string>using namespace std;struct A { }; struct B : A { };int main…...
ServerTrust 并非唯一
NSURLAuthenticationMethodServerTrust 只是 authenticationMethod 的冰山一角 要理解 NSURLAuthenticationMethodServerTrust, 首先要明白它只是 authenticationMethod 的选项之一, 并非唯一 1 先厘清概念 点说明authenticationMethodURLAuthenticationChallenge.protectionS…...
CMake 从 GitHub 下载第三方库并使用
有时我们希望直接使用 GitHub 上的开源库,而不想手动下载、编译和安装。 可以利用 CMake 提供的 FetchContent 模块来实现自动下载、构建和链接第三方库。 FetchContent 命令官方文档✅ 示例代码 我们将以 fmt 这个流行的格式化库为例,演示如何: 使用 FetchContent 从 GitH…...
Maven 概述、安装、配置、仓库、私服详解
目录 1、Maven 概述 1.1 Maven 的定义 1.2 Maven 解决的问题 1.3 Maven 的核心特性与优势 2、Maven 安装 2.1 下载 Maven 2.2 安装配置 Maven 2.3 测试安装 2.4 修改 Maven 本地仓库的默认路径 3、Maven 配置 3.1 配置本地仓库 3.2 配置 JDK 3.3 IDEA 配置本地 Ma…...
人机融合智能 | “人智交互”跨学科新领域
本文系统地提出基于“以人为中心AI(HCAI)”理念的人-人工智能交互(人智交互)这一跨学科新领域及框架,定义人智交互领域的理念、基本理论和关键问题、方法、开发流程和参与团队等,阐述提出人智交互新领域的意义。然后,提出人智交互研究的三种新范式取向以及它们的意义。最后,总结…...
音视频——I2S 协议详解
I2S 协议详解 I2S (Inter-IC Sound) 协议是一种串行总线协议,专门用于在数字音频设备之间传输数字音频数据。它由飞利浦(Philips)公司开发,以其简单、高效和广泛的兼容性而闻名。 1. 信号线 I2S 协议通常使用三根或四根信号线&a…...
关于uniapp展示PDF的解决方案
在 UniApp 的 H5 环境中使用 pdf-vue3 组件可以实现完整的 PDF 预览功能。以下是详细实现步骤和注意事项: 一、安装依赖 安装 pdf-vue3 和 PDF.js 核心库: npm install pdf-vue3 pdfjs-dist二、基本使用示例 <template><view class"con…...
水泥厂自动化升级利器:Devicenet转Modbus rtu协议转换网关
在水泥厂的生产流程中,工业自动化网关起着至关重要的作用,尤其是JH-DVN-RTU疆鸿智能Devicenet转Modbus rtu协议转换网关,为水泥厂实现高效生产与精准控制提供了有力支持。 水泥厂设备众多,其中不少设备采用Devicenet协议。Devicen…...
一些实用的chrome扩展0x01
简介 浏览器扩展程序有助于自动化任务、查找隐藏的漏洞、隐藏自身痕迹。以下列出了一些必备扩展程序,无论是测试应用程序、搜寻漏洞还是收集情报,它们都能提升工作流程。 FoxyProxy 代理管理工具,此扩展简化了使用代理(如 Burp…...
HTML中各种标签的作用
一、HTML文件主要标签结构及说明 1. <!DOCTYPE html> 作用:声明文档类型,告知浏览器这是 HTML5 文档。 必须:是。 2. <html lang“zh”>. </html> 作用:包裹整个网页内容,lang"z…...
