数据结构——栈和队列

目录

1.栈(stack)

[1.1 模拟实现](#1.1 模拟实现)

[1.1.1 定义栈](#1.1.1 定义栈)

[1.1.2 初始化栈](#1.1.2 初始化栈)

[1.1.3 销毁栈](#1.1.3 销毁栈)

​编辑

[1.1.4 入栈----栈顶](#1.1.4 入栈----栈顶)

​编辑

[1.1.5 判栈空](#1.1.5 判栈空)

[1.1.6 出栈------栈顶](#1.1.6 出栈——栈顶)

​编辑

[1.1.7 取栈顶数据](#1.1.7 取栈顶数据)

​编辑

[1.1.8 取栈的有效数据个数](#1.1.8 取栈的有效数据个数)

​编辑

2.队列(queue)

[2.1 模拟实现](#2.1 模拟实现)

[2.1.1 定义队列](#2.1.1 定义队列)

[2.1.2 初始化队列](#2.1.2 初始化队列)

​编辑

[2.1.3 销毁队列](#2.1.3 销毁队列)

[2.1.4 插入数据](#2.1.4 插入数据)

​编辑

[2.1.5 判断队列是否为空](#2.1.5 判断队列是否为空)

[2.1.6 出队列](#2.1.6 出队列)

[2.1.7 取队头数据](#2.1.7 取队头数据)

[2.1.8 取队尾数据](#2.1.8 取队尾数据)

​编辑

[2.1.9 有效元素个数](#2.1.9 有效元素个数)

​编辑


1.栈(stack)

栈:⼀种特殊的线性表,其只允许在固定的⼀端进行插⼊和删除元素操作。进行数据插入和删除操作 的⼀端称为栈顶,另⼀端称为栈底。栈中的数据元素遵守后进先出LIFO(LastInFirstOut)的原则。

压栈:栈的插⼊操作叫做进栈/压栈/入栈,入数据在栈顶。

出栈:栈的删除操作叫做出栈。出数据也在栈顶。

1.1 模拟实现

对于栈来说,咱们选择数组作为他的底层实现逻辑,原因如下:

1.栈只需要对一端进行输入输出,也就是说只需要确保输入输出那一端的实现的时间复杂度最小即可,咱们又知道数组与链表对于一端的输入输出,时间复杂度都是O(1),但是呢,比如:由于数组空间是连续的,所以说,数组直接top--,top++,即可。

2.而你的链表还需要考虑申请新结点,释放的时候别忘了将已释放的结点置为空(性能损耗)。

3.并且,数组实现可以确保cpu缓存命中率高,起码比链表要高。链表还可能出现缓存污染等问题。

所以,结合以上观点,用数组去实栈确实很方便。

1.1.1 定义栈

1.1.2 初始化栈

1.1.3 销毁栈

1.1.4 入栈----栈顶

别忘了将栈顶的位置更新一下。

1.1.5 判栈空

1.1.6 出栈------栈顶

同样,直接top--即可,也算是更新了栈顶的元素位置。

1.1.7 取栈顶数据

1.1.8 取栈的有效数据个数

栈的实现也是非常的简单,接下来看队列。

2.队列(queue)

概念:只允许在⼀端进⾏插⼊数据操作,在另⼀端进行删除数据操作的特殊线性表,队列具有先进先 出FIFO(First In First Out)

⼊队列:进行插入操作的⼀端称为队尾

出队列:进行删除操作的⼀端称为队头

所以说队列是个两头操作的。

2.1 模拟实现

那么队列的实现咱们是用链表还是数组呢?咱们先来分析一下:

1.如果说使用数组:队列是两头操作的,对于插入那一头来说好办,时间复杂度是O(1),但是对于出队列的那一头呢?就是不太友好了,因为你得删除数据后,挪动数据,挪动数据的时间复杂度是O(n),不是我们想要的。

2.单链表:跟数组一样的,对于删除操作,时间复杂度是O(1),但是对于插入操作,得找到链表的尾部,又因为这是个单向链表,所以说又得循环遍历,找出链表的尾部,再进行插入,那这个时间复杂度是不是就是O(n)了,也不是咱们想要的。

3.哎,那么这个时候,就有人想到了,咱们用两头带指针的链表不就可以了吗?聪明,就是这样的,这样的话,对于两头的操作时间复杂度都是O(1),就是咱们想要的。

4.那么底层使用链表实现的,链表是由一个一个的结点构成的,这下子脑中就有清晰的思路了吧。

2.1.1 定义队列

2.1.2 初始化队列

2.1.3 销毁队列

看这个销毁代码熟悉不,没错,这个就是咱们单链表也用的销毁代码,循环销毁。

2.1.4 插入数据

  • 若队列为空(phead == NULL),新节点同时作为队头和队尾。

  • 否则,将新节点链接到队尾,并更新 ptail

2.1.5 判断队列是否为空

2.1.6 出队列

  • 检查队列是否为空(size == 0phead == NULL),避免空指针访问。
    • 若出队后队列为空,需将 ptail 置为 NULL,防止野指针。

    • 更新size。

2.1.7 取队头数据

2.1.8 取队尾数据

2.1.9 有效元素个数

这个实现是不是也跟咱们的链表有异曲同工之妙。

OK,本篇完..................

本篇为C++的stack与queue打基础。

相关推荐
iCxhust几秒前
微机原理实践教程(C语言篇)---A002流水灯
c语言·开发语言·单片机·嵌入式硬件·51单片机·课程设计·微机原理
Morwit7 分钟前
QML组件之间的通信方案(暴露子组件)
c++·qt·职场和发展
qeen8719 分钟前
【数据结构】建堆的时间复杂度讨论与TOP-K问题
c语言·数据结构·c++·学习·
图码30 分钟前
如何用多种方法判断字符串是否为回文?
开发语言·数据结构·c++·算法·阿里云·线性回归·数字雕刻
handler0138 分钟前
Linux 内核剖析:进程优先级、上下文切换与 O(1) 调度算法
linux·运维·c语言·开发语言·c++·笔记·算法
zhouwy11343 分钟前
Linux进程与线程编程详解
linux·c++
我星期八休息1 小时前
IT疑难杂症诊疗室:AI时代工程师Superpowers进化论
linux·开发语言·数据结构·人工智能·python·散列表
热心网友俣先生1 小时前
2026年第二十三届五一数学建模竞赛C题超详细解题思路+各问题可用模型推荐+部分模型结果展示
c语言·开发语言·数学建模
漂流瓶jz1 小时前
UVA-1152 和为0的4个值 题解答案代码 算法竞赛入门经典第二版
数据结构·算法·二分查找·题解·aoapc·算法竞赛入门经典·uva
A7bert7772 小时前
【YOLOv8pose部署至RDK X5】模型训练→转换bin→Sunrise 5部署
c++·python·深度学习·yolo·目标检测