数据结构-栈和队列
文章目录
- 一、栈
- 1.概念与结构
- 2.数组栈的实现
- 2.1 栈的结构定义
- 2.2 栈的初始化
- 2.3 栈的销毁
- 2.4 栈的判空
- 2.5 栈的入栈
- 2.6 栈的出栈
- 2.7 查看栈顶元素
- 2.8 栈的大小
- 3.两种栈的图示结构
- 二、队列
- 1.概念与结构
- 2.链式队列的实现
- 2.1 队列的结构定义
- 2.2 队列的初始化
- 2.3 队列的销毁
- 2.4 队列的判空
- 2.5 队列的入队
- 2.6 队列的出队
- 2.7 查看队头元素
- 2.8 查看队尾元素
- 2.9 队列的大小
- 3.链式队列的图示结构
一、栈
1.概念与结构
栈:一种特殊的线性表,其只允许在固定的一端进行插入和删除元素操作。进行数据插入和删除操作的一端称为栈顶,另一端称为栈底。栈中的数据元素遵守后进先出LIFO(Last In First Out)的原则.
压栈: 栈的插入操作叫做进栈/压栈/入栈,入数据在栈顶。
出栈: 栈的删除操作叫做出栈。出数据也在栈顶。
栈底层结构选型
栈的实现一般可以使用数组或者链表实现,相对而言数组的结构实现更优一些。因为数组在尾上插入数据的代价比较小。
2.数组栈的实现
2.1 栈的结构定义
typedef int STDataType;
typedef struct Stack
{STDataType* arr;int top; int capacity; //空间容量
}ST;
arr就是待开辟空间的指针。top可以有两种选择:一种是指向栈顶元素,另一种就是指向栈顶元素的下一个位置。现在我们定义一个栈的变量:
ST st;
2.2 栈的初始化
void STInit(ST* pst)
{assert(pst != NULL);pst->arr = NULL;//pst->top = -1; //top指向栈顶元素pst->top = 0; //top指向栈顶元素的下一个位置pst->capacity = 0;
}
由于定义的是一个结构体变量st,要改变该结构体,就要传st的指针。所以要断言pst不能为空,开始先初始化数组的指针为空。对于top我们说过有两种定义方式:
当top初始化为-1时,说明top指向的是栈顶元素,top==-1时说明栈顶还没有存储元素。top==-1是数组第一个元素的前一个位置,是非法的:
当top初始化为0时,说明top指向的是栈顶元素的下一个位置,top==0时说明栈顶还没有数据:
capacity就是数组能存储的元素个数。
2.3 栈的销毁
void STDestroy(ST* pst)
{assert(pst != NULL);free(pst->arr);pst->arr = NULL;pst->top = pst->capacity = 0;
}
由于动态开辟的是一块连续的空间,所以释放空间很简单,直接free掉arr,再把arr置空,top和capacity赋值为0即可。pst仍然要断言不能为空。
2.4 栈的判空
bool STEmpty(ST* pst)
{assert(pst != NULL);return pst->top == 0;
}
判空就是判断栈顶是否有数据,初始化的top是为0的,说明top指向的是栈顶元素的下一个位置。所以如果表达式top==0为真,则返回true,否则返回false。
2.5 栈的入栈
void STPush(ST* pst,STDataType x)
{assert(pst != NULL);if (pst->top == pst->capacity){int newCapacity = pst->capacity == 0 ? 4 : pst->capacity * 2;STDataType* tmp = (STDataType*)realloc(pst->arr, newCapacity*sizeof(STDataType));if (tmp == NULL){perror("realloc fail!");return NULL;}pst->arr = tmp;pst->capacity = newCapacity;}pst->arr[pst->top++] = x;
}
由于top是指向栈顶元素的下一个位置,所以在压栈之前,要先判断数组是否满了,也就是当top==capacity时,要么是数组里还没有元素,要么就是数组存储满了。realloc就能实现空间的扩容。如果还没有开辟空间,那realloc的功能就相当于malloc。在压栈后,记得要把top往后挪一位,指向栈顶元素的下一个位置。
2.6 栈的出栈
void STPop(ST* pst)
{assert(pst != NULL);assert(!STEmpty(pst));pst->top--;
}
由于栈的特点是后进先出,所以栈里元素的出栈,要从栈顶出元素才行。直接让top往前挪一位即可。但在删除栈顶元素之前要先判空。因为如果栈里没有元素,则不能进行出栈操作。
2.7 查看栈顶元素
STDataType STTop(ST* pst)
{assert(pst != NULL);assert(!STEmpty(pst));return pst->arr[pst->top - 1];
}
在返回栈顶元素之前要先判断栈是否为空,不为空再返回栈顶的元素。注意:top是指向栈顶元素的下一个位置的,所以栈顶元素的位置是top-1。
2.8 栈的大小
int STSize(ST* pst)
{assert(pst != NULL);return pst->top;
}
栈的大小即数组中的有效元素个数。由于top是指向栈顶元素的下一个位置的,所以top刚好就可以表示数组中的有效元素个数。注意:如果一开始top是初始化为-1的话,那数组的有效元素个数就要返回top+1。
3.两种栈的图示结构

记住:栈的特点是后进先出(Last In First Out),所以链式栈的进栈出栈要在头结点处进行。
🧳🧳栈就像箱子一样:往箱子里放东西会从箱底放起,直到放满;然后从箱子里取东西就要从箱顶开始取,否则你取不到箱底的东西。 这就是后进先出的意思。
代码仓库:Stack
二、队列
1.概念与结构
概念: 只允许在一端进行插入数据操作,在另一端进行删除数据操作的特殊线性表,队列具有先进先出FlFO(First In First Out)的性质.
入队列: 进行插入操作的一端称为队尾
出队列: 进行删除操作的一端称为队头
队列底层结构选型
队列也可以使用数组或链表的结构实现,使用链表的结构实现更优一些,因为如果使用数组的结构,出队列要在数组头出数据,效率会比较低。
2.链式队列的实现
2.1 队列的结构定义
//1.节点结构
typedef int QDataType;
typedef struct QueueNode
{QDataType data;struct QueueNode* next;
}QNode;
//2.队列结构
typedef struct Queue
{QNode* phead;QNode* ptail;int size;
}Queue;
队列的结构中只有三个成员,phead是用来指向链表的头的,ptail是用来指向链表的尾的。因为队列是先进先出的特点,所以链式队列是在队头出数据,在队尾进数据。有了phead和ptail指针就方便我们管理链表。size是链表的元素个数(节点个数)。
若现在创建了一个结构体变量:
Queue q;
2.2 队列的初始化
void QueueInit(Queue* pq)
{assert(pq != NULL);pq->phead = NULL;pq->ptail = NULL;pq->size = 0;
}
注意:我们创建的是一个结构体变量q,所以要改变该变量,就要传该变量的地址才行。所以要对pq进行断言不能为空。
2.3 队列的销毁
void QueueDestroy(Queue* pq)
{assert(pq != NULL);QNode* cur = pq->phead;while (cur){QNode* next = cur->next;free(cur);cur = next;}pq->phead = pq->ptail = NULL;pq->size = 0;
}
队列的销毁就是释放链表中的所有节点,然后要记得把phead和ptail置为空,size赋值为0。链式队列的销毁就跟单链表的销毁是一样的。
2.4 队列的判空
bool QEmpty(Queue* pq)
{assert(pq != NULL);return pq->phead == NULL&& pq->ptail == NULL;
}
理论上如果链表为空,那phead和ptail都为空,但是两个一起判断更好,以免出啥bug。当然也可以通过判断size是否等于0来判断队列是否为空。
2.5 队列的入队
void QueuePush(Queue* pq, QDataType x)
{assert(pq != NULL);QNode* newnode = (QNode*)malloc(sizeof(QNode));if (newnode == NULL){perror("malloc fail!");return;}newnode->data = x;newnode->next = NULL;if (pq->ptail == NULL){assert(pq->phead == NULL);pq->phead = pq->ptail = newnode;}else{pq->ptail->next = newnode;pq->ptail = newnode;}pq->size++;
}
先创建一个新节点,然后需要判断此时队列是否为空,为空是一种情况,不为空也是一种情况。为空就让phead和ptail都指向newnode;不为空就要在尾结点ptail处进行尾插。数据入队后,记得要让size+1。
2.6 队列的出队
void QueuePop(Queue* pq)
{assert(pq != NULL);assert(!QEmpty(pq));if (pq->phead->next == NULL){free(pq->phead);pq->phead = pq->ptail = NULL;}else{QNode* next = pq->phead->next;free(pq->phead);pq->phead = next;}pq->size--;
}
元素出队也是需要分类讨论的,如果队列为空就不能进行出队操作,所以要先判空。如果是队列中只有一个节点,那phead和ptail此时都指向这个节点,所以直接释放掉phead即可,但是要记得把两个指针都置空,否则会出现野指针。如果队列中不止一个节点,那直接在头结点phead处进行头删。出队一个元素,记得要让size-1。
2.7 查看队头元素
QDataType QueueFront(Queue* pq)
{assert(pq != NULL);assert(!QEmpty(pq));return pq->phead->data;
}
如果队列为空,则链表为空,没有队头数据。所以要判先空。
2.8 查看队尾元素
QDataType QueueBack(Queue* pq)
{assert(pq != NULL);assert(!QEmpty(pq));return pq->ptail->data;
}
查看队尾元素也是要先判断队列是否为空,队列为空就没有队尾元素。
2.9 队列的大小
int QueueSize(Queue* pq)
{assert(pq != NULL);return pq->size;
}
队列的大小就是队列中的元素个数(节点个数)size,返回size即可。
3.链式队列的图示结构


记住:队列的特点是先进先出(First In Fitst Out),所以链式队列的入队要在链表的尾结点处尾插,而出队要在链表的头节点处头删。
⬅️🚶🚶♂️🚶♀️⬅️队列就像排队打饭一样:先来的同学会排在队伍的前面,而后来的同学会排在队伍的后面。排在最前面的同学会先打到饭离开队伍,而排在队伍后面的同学需要等待前面的同学离开了才能打到饭。这就是先进先出的意思。
代码仓库:Queue

相关文章:
数据结构-栈和队列
文章目录 一、栈1.概念与结构2.数组栈的实现2.1 栈的结构定义2.2 栈的初始化2.3 栈的销毁2.4 栈的判空2.5 栈的入栈2.6 栈的出栈2.7 查看栈顶元素2.8 栈的大小 3.两种栈的图示结构 二、队列1.概念与结构2.链式队列的实现2.1 队列的结构定义2.2 队列的初始化2.3 队列的销毁2.4 队…...
RabbitMQ---TTL与死信
(一)TTL 1.TTL概念 TTL又叫过期时间 RabbitMQ可以对队列和消息设置TTL,当消息到达过期时间还没有被消费时就会自动删除 注:这里我们说的对队列设置TTL,是对队列上的消息设置TTL并不是对队列本身,不是说队列过期时间…...
第4章 Kafka核心API——Kafka客户端操作
Kafka客户端操作 一. 客户端操作1. AdminClient API 一. 客户端操作 1. AdminClient API...
Python爬虫学习前传 —— Python从安装到学会一站式服务
早上好啊,大佬们。我们的python基础内容的这一篇终于写好了,啪唧啪唧啪唧…… 说实话,这一篇确实写了很久,一方面是在忙其他几个专栏的内容,再加上生活学业上的事儿,确实精力有限,另一方面&…...
Lora理解QLoRA
Parameter-Efficient Fine-Tuning (PEFT) :节约开销的做法,fine-tune少量参数,而不是整个模型; Low-Rank Adaptation (LoRA) :是PEFT的一种;冻结原参数矩阵,只更新2个小参数矩阵。 原文经过对比…...
Linux测试处理fps为30、1920*1080、一分钟的视频性能
前置条件 模拟fps为30、1920*1080、一分钟的视频 项目CMakeLists.txt cmake_minimum_required(VERSION 3.30) project(testOpenGl)set(CMAKE_CXX_STANDARD 11)add_executable(testOpenGl main.cpptestOpenCl.cpptestOpenCl.hTestCpp.cppTestCpp.hTestCppThread.cppTestCppTh…...
Flink (六):DataStream API (三) 窗口
1. 窗口 窗口(Window)是处理无界流的关键所在。窗口可以将数据流装入大小有限的“桶”中,再对每个“桶”加以处理。 下面展示了 Flink 窗口在 keyed streams 和 non-keyed streams 上使用的基本结构。 我们可以看到,这两者唯一的…...
MYSQL学习笔记(二):基本的SELECT语句使用(基本、条件、聚合函数查询)
前言: 学习和使用数据库可以说是程序员必须具备能力,这里将更新关于MYSQL的使用讲解,大概应该会更新30篇,涵盖入门、进阶、高级(一些原理分析);这一篇是讲解SELECT语句使用,包括基本、条件、聚合函数查询,…...
PCL 点到面的ICP算法实现点云配准(C++详细过程版)
ICP算法 一、算法原理1、算法概述2、实现流程3、参考文献二、代码实现三、结果展示四、相关链接一、算法原理 1、算法概述 实现的算法与 PCL 点到面的ICP精配准(线性最小二乘优化)一文相同,使用C++代码复现线性优化的求解过程,求解过程如下所示,由于原版英文文献的计算过…...
MarsCode青训营打卡Day1(2025年1月14日)|稀土掘金-16.最大矩形面积问题
资源引用: 最大矩形面积问题 - MarsCode 打卡小记录: 今天是开营第一天,和小伙伴们组成了8人的团队,在接下来的数十天里相互监督,打卡刷题! 稀土掘金-16.最大矩形面积问题(16.最大矩形面积问题…...
我的世界-与门、或门、非门等基本门电路实现
一、红石比较器 (1) 红石比较器结构 红石比较器有前端单火把、后端双火把以及两个侧端 其中后端和侧端是输入信号,前端是输出信号 (2) 红石比较器的两种模式 比较模式 前端火把未点亮时处于比较模式 侧端>后端 → 0 当任一侧端强度大于后端强度时,输出…...
【FISCO BCOS】二十三、部署WeBASE-Node-Manager
WeBASE-Node-Manager是WeBASE的子组件之一,可以处理前端页面所有web请求,管理各个节点的状态,管理链上所有智能合约,对区块链的数据进行统计、分析,对异常交易的审计,私钥管理等,今天我们来部署WeBASE-Node-Manager。 环境:ubuntu 22 、已搭建单机四节点(节点已启动)…...
app版本控制java后端接口版本管理
java api version 版本控制 java接口版本管理 1 自定义 AppVersionHandleMapping 自定义AppVersionHandleMapping实现RequestMappingHandlerMapping里面的方法 public class AppVersionHandleMapping extends RequestMappingHandlerMapping {Overrideprotected RequestCondit…...
Go语言strings包与字符串操作:从基础到高级的全面解析
Go语言strings包与字符串操作:从基础到高级的全面解析 引言 Go语言以其简洁、高效和强大的标准库而闻名,其中strings包是处理字符串操作的核心工具。本文将深入探讨Go语言中strings包的功能及其在实际开发中的应用,帮助开发者更好地理解和使用这一工具。 1. strings包概述…...
使用redis-cli命令实现redis crud操作
项目场景: 线上环境上redis中的key影响数据展示,需要删除。但环境特殊没办法通过 redis客户端工具直连。只能使用redis-cli命令来实现。 操作步骤: 1、确定redis安装的服务器; 2、找到redis的安装目录下 ##找到redis安装目…...
Ubuntu升级Linux内核教程
本文作者CVE-柠檬i: CVE-柠檬i-CSDN博客 本文使用的方法是dpkg安装,目前版本为5.4.0-204,要升级成5.8.5版本 下载 下载网站:https://kernel.ubuntu.com/mainline/ 在该网站下载deb包,选择自己想要升级的版本,这里是5…...
5、docker-compose和docker-harbor
安装部署docker-compose 自动编排工具,可以根据dockerfile自动化的部署docker容器。是yaml文件格式,注意缩进。 1、安装docker-compose 2、配置compose配置文件docker-compose.yml 3、运行docker-compose.yml -f:指定文件,up&…...
Leetcode3097:或值至少为 K 的最短子数组 II
题目描述: 给你一个 非负 整数数组 nums 和一个整数 k 。 如果一个数组中所有元素的按位或运算 OR 的值 至少 为 k ,那么我们称这个数组是 特别的 。 请你返回 nums 中 最短特别非空 子数组的长度,如果特别子数组不存在,那么返…...
HTML应用指南:利用GET请求获取全国特斯拉充电桩位置
随着电动汽车的普及,充电基础设施的建设变得至关重要。作为电动汽车领域的先驱,特斯拉不仅在车辆技术创新上持续领先,还积极构建广泛的充电网络,以支持其不断增长的用户群体。为了提升用户体验和服务质量,开发人员和数…...
阿里云通义实验室自然语言处理方向负责人黄非:通义灵码2.0,迈入 Agentic AI
通义灵码是基于阿里巴巴通义大模型研发的AI 智能编码助手,在通义灵码 1.0 时代,我们针对代码的生成、补全和问答,通过高效果、低时延,研发出了国内最受欢迎的编码助手。 在通义灵码 2.0 发布会上,阿里云通义实验室自然…...
vscode里如何用git
打开vs终端执行如下: 1 初始化 Git 仓库(如果尚未初始化) git init 2 添加文件到 Git 仓库 git add . 3 使用 git commit 命令来提交你的更改。确保在提交时加上一个有用的消息。 git commit -m "备注信息" 4 …...
云原生核心技术 (7/12): K8s 核心概念白话解读(上):Pod 和 Deployment 究竟是什么?
大家好,欢迎来到《云原生核心技术》系列的第七篇! 在上一篇,我们成功地使用 Minikube 或 kind 在自己的电脑上搭建起了一个迷你但功能完备的 Kubernetes 集群。现在,我们就像一个拥有了一块崭新数字土地的农场主,是时…...
PHP和Node.js哪个更爽?
先说结论,rust完胜。 php:laravel,swoole,webman,最开始在苏宁的时候写了几年php,当时觉得php真的是世界上最好的语言,因为当初活在舒适圈里,不愿意跳出来,就好比当初活在…...
深入理解JavaScript设计模式之单例模式
目录 什么是单例模式为什么需要单例模式常见应用场景包括 单例模式实现透明单例模式实现不透明单例模式用代理实现单例模式javaScript中的单例模式使用命名空间使用闭包封装私有变量 惰性单例通用的惰性单例 结语 什么是单例模式 单例模式(Singleton Pattern&#…...
测试markdown--肇兴
day1: 1、去程:7:04 --11:32高铁 高铁右转上售票大厅2楼,穿过候车厅下一楼,上大巴车 ¥10/人 **2、到达:**12点多到达寨子,买门票,美团/抖音:¥78人 3、中饭&a…...
VTK如何让部分单位不可见
最近遇到一个需求,需要让一个vtkDataSet中的部分单元不可见,查阅了一些资料大概有以下几种方式 1.通过颜色映射表来进行,是最正规的做法 vtkNew<vtkLookupTable> lut; //值为0不显示,主要是最后一个参数,透明度…...
vue3 定时器-定义全局方法 vue+ts
1.创建ts文件 路径:src/utils/timer.ts 完整代码: import { onUnmounted } from vuetype TimerCallback (...args: any[]) > voidexport function useGlobalTimer() {const timers: Map<number, NodeJS.Timeout> new Map()// 创建定时器con…...
C++ 求圆面积的程序(Program to find area of a circle)
给定半径r,求圆的面积。圆的面积应精确到小数点后5位。 例子: 输入:r 5 输出:78.53982 解释:由于面积 PI * r * r 3.14159265358979323846 * 5 * 5 78.53982,因为我们只保留小数点后 5 位数字。 输…...
今日科技热点速览
🔥 今日科技热点速览 🎮 任天堂Switch 2 正式发售 任天堂新一代游戏主机 Switch 2 今日正式上线发售,主打更强图形性能与沉浸式体验,支持多模态交互,受到全球玩家热捧 。 🤖 人工智能持续突破 DeepSeek-R1&…...
QT: `long long` 类型转换为 `QString` 2025.6.5
在 Qt 中,将 long long 类型转换为 QString 可以通过以下两种常用方法实现: 方法 1:使用 QString::number() 直接调用 QString 的静态方法 number(),将数值转换为字符串: long long value 1234567890123456789LL; …...


