【C++】STL库_stack_queue 的模拟实现
栈(Stack)、队列(Queue)是C++ STL中的经典容器适配器
容器适配器特性
- 不是独立容器,依赖底层容器(deque/vector/list)
- 通过限制基础容器接口实现特定访问模式
- 不支持迭代器操作(无法遍历元素)
- 时间复杂度:
- 栈/队列操作均为O(1)
- 底层容器影响性能:
- vector实现栈可能导致扩容拷贝
- list实现队列保证稳定性能
典型应用场景:
- 栈:函数调用栈、括号匹配、表达式求值
- 队列:消息队列、BFS算法、缓冲机制
(栈和队列前面C语言写过,这里直接贴C++代码)
双端队列:
(不常用,简单介绍和理解)

STL标准库里面默认适配器使用的是deque这个容器,
deque(双端队列)是C++标准库中的顺序容器,全称"double-ended queue",支持在头尾两端高效插入/删除元素。
- 分段连续存储:由多个固定大小的存储块(称为缓冲区buffer)构成
- 中控器结构:使用指针数组(map)管理存储块的地址
优势:
- 任意位置(头尾插入)插入删除
- 可以随机访问
缺陷:
- operator[],计算稍显复杂,大量使用,性能下降。
- 中间插入删除效率不高
- 底层角度选代器会很复杂

cur 表示当前数据
first 和 last 表示 buffer 的开始和结束
node 反向指向中控位置,方便遍历时找下一个buffer
栈:
template<class T,class Container=deque<T>>
class stack
{
public:void push(const T& x){_con.push_back(x);}void pop();T& top(){return _con.back();}bool empty()const{return _con.empty();}size_t size(){return _con.size();}private:Container _con;};template<class T, class Container>
inline void stack<T, Container>::pop()
{_con.pop_back();
}
队列:
template<class T, class Container = deque<T>>
class queue
{
public:void push(const T& x);void pop(){_con.pop_front();}T& back(){return _con.back();}T& front(){return _con.front();}bool empty()const{return _con.empty();}size_t size(){return _con.size();}private:Container _con;};template<class T, class Container>
inline void queue<T, Container>::push(const T& x)
{_con.push_back(x);
}
仿函数:
仿函数(Functor),也称为函数对象,是通过重载operator()运算符使得类对象可以像函数一样被调用的技术。它常用于STL算法中,提供灵活且可定制的操作逻辑。
仿函数设计出来是用来替代函数指针的。
template<class T>
struct greater
{bool operator()(const T& l, const T& r) const {return l > r;}
};template<class T>
struct less
{bool operator()(const T& l, const T& r) const {return l < r;}
};


优先级队列(priority_queue):
优先级队列(priority_queue)是C++标准库中的容器适配器,它基于堆数据结构实现,能够保证队列头部始终是最大(默认)或最小值的元素。
底层的数据结构实际为堆(Heap)。

#include <queue>
priority_queue<int> pq; // 默认大顶堆
priority_queue<int, vector<int>, greater<int>> min_pq; // 小顶堆
PS:
- Compare 进行比较的仿函数 less->大堆
- Compare 进行比较的仿函数 greater->小堆
//compare进行比较的仿函数 less->大堆
template<class T, class Container = vector<T>, class Compare=std::less<T>>
class priority_queue
{
public:priority_queue(){}template<class InputIterator>priority_queue(InputIterator first, InputIterator last){while (first!=last){_con.push_back(*first);++first;}//建堆for (int i = (_con.size()-1-1)/2;i>=0;--i){adjust_down(i);}}void adjust_up(size_t child){Compare com;size_t parent = (child - 1) / 2;while (child > 0){if (com(_con[parent] ,_con[child])) { //默认less 向上调整建大堆std::swap(_con[child] , _con[parent]);child = parent;parent = (child - 1) / 2;}else {break;}}}void push(const T& x){_con.push_back(x);adjust_up(_con.size()-1);}void adjust_down(size_t parent){Compare com;size_t child = parent * 2 + 1;while (child < _con.size()) {//选出左右孩子大的那一个 默认less 向下调整建小堆if (child + 1 < _con.size() && com(_con[child],_con[child+1])) {++child;}if (com(_con[parent], _con[child])) {std::swap(_con[child] , _con[parent]);parent = child; child = parent * 2 + 1;}else {break;}}}void pop(){std::swap(_con[0], _con[_con.size() - 1]);_con.pop_back();adjust_down(0);}const T &top()const{return _con[0];}private:Container _con;
};
代码几乎都是前面写过的,关键是C++让其封装起来了。
代码还是有几个要注意的点:
STL库里面priority用greater(大于) 比较建立小堆,less(小于)比较建立小堆。所以这里要跟标准库里面保持一致,所以要注意比较时,代码的顺序。
而这里影响位置顺序的地方在向上调整和向下调整的函数上。
void adjust_up(size_t child)
{Compare com;size_t parent = (child - 1) / 2;while (child > 0){if (com(_con[parent] ,_con[child])) { std::swap(_con[child] , _con[parent]);child = parent;parent = (child - 1) / 2;}else {break;}}
}void adjust_down(size_t parent)
{Compare com;size_t child = parent * 2 + 1;while (child < _con.size()) {if (child + 1 < _con.size() && com(_con[child],_con[child+1])) {++child;}if (com(_con[parent], _con[child])) {std::swap(_con[child] , _con[parent]);parent = child; child = parent * 2 + 1;}else {break;}}
}
构建堆的复杂度差异:
- 自底向上建堆:时间复杂度为 O(n),因为大多数节点位于低层。
- 自顶向下建堆:时间复杂度为 O(n log n),因为每个元素插入时都可能需要 O(log n) 调整。
所以这里使用自底向上建堆。
_con[parent] > _con[child]
等价于
_con[child] < _con[parent] _con[parent] < _con[child]
等价于
_con[child] > _con[parent]
这里写法顺序的不同,会导致代码的意思不同。这里要跟库里面最好保持一直。库里面是greater(大于)建立小堆,所以这里 > 保持不变的情况下,_con[parent] 要放在左边, _con[child] 要放在右边 (自顶向下建堆) 。
根据代码的意思就可以知道,如果 _con[parent] > _con[child],则交换父子节点的数据,那么一直到根节点,数据变成了上面下,下面大的结构,就建成了小堆。同理 如果是 _con[child] > _con[parent],则变成了数据上面大,下面小的结构,会建成大堆。
相关文章:
【C++】STL库_stack_queue 的模拟实现
栈(Stack)、队列(Queue)是C STL中的经典容器适配器 容器适配器特性 不是独立容器,依赖底层容器(deque/vector/list)通过限制基础容器接口实现特定访问模式不支持迭代器操作(无法遍历…...
前端对接下载文件接口、对接dart app
嵌套在dart app里面的前端项目 1.前端调下载接口 ->后端返回 application/pdf格式的文件 ->前端将pdf处理为blob ->blob转base64 ->调用dart app的 sdk saveFile ->保存成功 async download() {try {// 调用封装的 downloadEContract 方法获取 Blob 数据const …...
一周学会Pandas2 Python数据处理与分析-编写Pandas2 HelloWord项目
锋哥原创的Pandas2 Python数据处理与分析 视频教程: 2025版 Pandas2 Python数据处理与分析 视频教程(无废话版) 玩命更新中~_哔哩哔哩_bilibili 我们首先准备一个excel文件,用来演示pandas操作数据集(数据的集合)。excel文件属于数据集的一种…...
【易订货-注册/登录安全分析报告】
前言 由于网站注册入口容易被机器执行自动化程序攻击,存在如下风险: 暴力破解密码,造成用户信息泄露,不符合国家等级保护的要求。短信盗刷带来的拒绝服务风险 ,造成用户无法登陆、注册,大量收到垃圾短信的…...
AI赋能股票:流通股本与总股本:定义、区别及投资意义解析
一、基本定义 总股本(Total Shares Outstanding) 指一家公司已发行的所有股票数量,包括流通股和非流通股(如限售股、员工持股计划股票等)。总股本反映公司的整体股权结构,是计算市值(总股本 股…...
如何在Windows上找到Python安装路径?两种方法快速定位
原文:如何在Windows上找到Python安装路径?两种方法快速定位 | w3cschool笔记 在 Windows 系统上找到 Python 的安装路径对于设置环境变量或排查问题非常重要。本文将介绍两种方法,帮助你找到 Python 的安装路径:一种是通过命令提…...
第五课:高清修复和放大算法
文章目录 Part.01 高清修复(Hi-Res Fix)Part.02 SD放大(SD Upscale)Part.03 附加功能放大Part.01 高清修复(Hi-Res Fix) 文生图中的高清修复/高分辨率修复/超分辨率修复先低分辨率抽卡,再高分辨率修复。不能突破显存限制放大重绘幅度安全范围是0.3-0.5,如果想让AI更有想象力0…...
lvgl避坑记录
一、log调试 #if LV_USE_LOG && LV_LOG_LEVEL > LV_LOG_LEVEL_INFOswitch(src_type) {case LV_IMG_SRC_FILE:LV_LOG_TRACE("lv_img_set_src: LV_IMG_SRC_FILE type found");break;case LV_IMG_SRC_VARIABLE:LV_LOG_TRACE("lv_img_set_src: LV_IMG_S…...
Java 8 的流(Stream API)简介
Java 8 引入的 Stream API 是一个强大的工具,用于处理集合(如 List、Set)中的元素。它支持各种操作,包括过滤、排序、映射等,并且能够以声明式的方式表达复杂的查询操作。流操作可以是中间操作(返回流以便进…...
液态神经网络技术指南
一、引言 1.从传统神经网络到液态神经网络 神经网络作为深度学习的核心工具,在图像识别、自然语言处理、推荐系统等领域取得了巨大成功。尤其是卷积神经网络(CNN)、循环神经网络(RNN)、长短期记忆网络(LS…...
element-plus中,表单校验的使用
目录 一.案例1:给下面的表单添加校验 1.目的要求 2.步骤 ①给需要校验的el-form-item项,添加prop属性 ②定义一个表单校验对象,里面存放了每一个prop的检验规则 ③给el-form组件,添加:rules属性 ④给el-form组件࿰…...
PyTorch复现线性模型
【前言】 本专题为PyTorch专栏。从本专题开始,我将通过使用PyTorch编写基础神经网络,带领大家学习PyTorch。并顺便带领大家复习以下深度学习的知识。希望大家通过本专栏学习,更进一步了解人更智能这个领域。 材料来源:2.线性模型_…...
Kafka+Zookeeper从docker部署到spring boot使用完整教程
文章目录 一、Kafka1.Kafka核心介绍:核心架构核心特性典型应用 2.Kafka对 ZooKeeper 的依赖:3.去 ZooKeeper 的演进之路:注:(本文采用ZooKeeper3.8 Kafka2.8.1) 二、Zookeeper1.核心架构与特性2.典型…...
RK3568驱动 SPI主/从 配置
一、SPI 控制器基础配置(先说主的配置,后面说从的配置) RK3568 集成高性能 SPI 控制器,支持主从双模式,最高传输速率 50MHz。设备树配置文件路径通常为K3568/rk356x_linux_release_v1.3.1_20221120/kernel/arch/arm64/boot/dts/rockchip。 …...
【全队项目】智能学术海报生成系统PosterGenius--风格个性化调整
🌈 个人主页:十二月的猫-CSDN博客 🔥 系列专栏🏀大模型实战训练营 💪🏻 十二月的寒冬阻挡不了春天的脚步,十二点的黑夜遮蔽不住黎明的曙光 1.前言 PosterGenius致力于开发一套依托DeepSeek…...
【系统移植】(六)第三方驱动移植
【系统移植】(六)第三方驱动移植 文章目录 【系统移植】(六)第三方驱动移植1.编译驱动进内核方法一:编译makefile方法二:编译kconfig方法三:编译成模块 2.字符设备框架 编译驱动进内核a. 选择驱…...
STM32实现一个简单电灯
新建工程的步骤 建立工程文件夹,Keil中新建工程,选择型号工程文件夹里建立Start、Library、User等文件夹,复制固件库里面的文件到工程文件夹工程里对应建立Start、Library、User等同名称的分组,然后将文件夹内的文件添加到工程分组…...
【shiro】shiro反序列化漏洞综合利用工具v2.2(下载、安装、使用)
1 工具下载 shiro反序列化漏洞综合利用工具v2.2下载: 链接:https://pan.baidu.com/s/1kvQEMrMP-PZ4K1eGwAP0_Q?pwdzbgp 提取码:zbgp其他工具下载: 除了该工具之外,github上还有其他大佬贡献的各种工具,有…...
vue进度条组件
<div class"global-mask" v-if"isProgress"><div class"contentBox"><div class"progresstitie">数据加载中请稍后</div><el-progress class"progressStyle" :color"customColor" tex…...
【C++游戏引擎开发】《线性代数》(2):矩阵加减法与SIMD集成
一、矩阵加减法数学原理 1.1 定义 逐元素操作:运算仅针对相同位置的元素,不涉及矩阵乘法或行列变换。交换律与结合律: 加法满足交换律(A + B = B + A)和结合律( ( A + B ) + C = A + ( B + C ) )。 减法不满足交换律(A − B ≠ B − A)。1.2 公式 C i j = …...
UE5Actor模块源码深度剖析:从核心架构到实践应用
UE5 Actor模块源码深度剖析:从核心架构到实践应用 a. UE5 Actor模块架构概述 在UE5引擎中,Actor扮演着至关重要的角色,它是整个游戏世界中各类可交互对象的基础抽象。从本质上来说,所有能够被放置到关卡中的对象都属于Actor的范畴,像摄像机、静态网格体以及玩家起始位置…...
【3.软件工程】3.6 W开发模型
W模型全解析:开发与测试并行的质量保障框架 ⚡ 一、W模型核心流程图 #mermaid-svg-YfU8WQvqa6iDUKz3 {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-YfU8WQvqa6iDUKz3 .error-icon{fill:#552222;}#merm…...
基于大模型的主动脉瓣病变预测及治疗方案研究报告
目录 一、引言 1.1 研究背景 1.2 研究目的 1.3 研究意义 二、大模型预测主动脉瓣病变原理 2.1 大模型介绍 2.2 数据收集与处理 2.3 模型训练与优化 三、术前预测与评估 3.1 主动脉瓣病变类型及程度预测 3.2 患者整体状况评估 3.3 手术风险预测 四、术中应用与监测…...
CSRF跨站请求伪造——入门篇【DVWA靶场low级别writeup】
CSRF跨站请求伪造——入门篇 0. 前言1. 什么是CSRF2. 一次完整的CSRF攻击 0. 前言 本文将带你实现一次完整的CSRF攻击,内容较为基础。需要你掌握的基础知识有: 了解cookie;已经安装了DVWA的靶场环境(本地的或云的)&am…...
拦截、限流,针对场景详细信息(一)
以下是一个基于Java Spring Boot Redis 的完整限流实现案例,针对同一接口前缀(如 /one/ )的IP访问频率控制: 场景:用户不用登录即可访问接口,网站会有被攻击的风险 URL:one/two/three one/…...
Qt基础:主界面窗口类QMainWindow
QMainWindow 1. QMainWindow1.1 菜单栏添加菜单项菜单项信号槽 1.2 工具栏添加工具按钮工具栏的属性设置 1.3 状态栏1.4 停靠窗口(Dock widget) 1. QMainWindow QMainWindow是标准基础窗口中结构最复杂的窗口, 其组成如下: 提供了菜单栏, 工具栏, 状态…...
第十四届蓝桥杯大赛软件赛省赛Python 研究生组:4.互质数的个数
题目1 互质数的个数 给定 a,b,求 1≤x<ab 中有多少个 x 与 ab 互质。 由于答案可能很大,你只需要输出答案对 998244353 取模的结果。 输入格式 输入一行包含两个整数分别表示 a,b,用一个空格分隔。 输出格式 输出一行包含一个整数表…...
32f4,usart2fifo,2025
usart2fifo.h #ifndef __USART2FIFO_H #define __USART2FIFO_H#include "stdio.h" #include "stm32f4xx_conf.h" #include "sys.h" #include "fifo_usart2.h"//extern u8 RXD2_TimeOut;//超时检测//extern u8 Timer6_1ms_flag;exte…...
激光模拟单粒子效应试验如何验证CANFD芯片的辐照阈值?
在现代航天电子系统中,CANFD(Controller Area Network with Flexible Data-rate)芯片作为关键的通信接口元件,其可靠性与抗辐射性能直接关系到整个系统的稳定运行。由于宇宙空间中存在的高能粒子辐射,芯片可能遭受单粒…...
从零构建大语言模型全栈开发指南:第五部分:行业应用与前沿探索-5.2.1模型偏见与安全对齐(Red Teaming实践)
👉 点击关注不迷路 👉 点击关注不迷路 👉 点击关注不迷路 文章大纲 大语言模型全栈开发指南:伦理与未来趋势 - 第五部分:行业应用与前沿探索5.2.1 模型偏见与安全对齐(Red Teaming实践)一、模型偏见的来源与影响1. 偏见的定义与分类2. 偏见的实际影响案例二、安全对齐…...

