【C++】STL库_stack_queue 的模拟实现

       栈(Stack)、队列(Queue)是C++ STL中的经典容器适配器

容器适配器特性

  1. 不是独立容器,依赖底层容器(deque/vector/list)
  2. 通过限制基础容器接口实现特定访问模式
  3. 不支持迭代器操作(无法遍历元素)
  4. 时间复杂度:
    • 栈/队列操作均为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],则变成了数据上面大,下面小的结构,会建成大堆。


    本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/74515.shtml

    如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

    相关文章

    LangChain核心解析:掌握AI开发的“链“式思维

    0. 思维导图 1. 引言 🌟 在人工智能快速发展的今天,如何有效地利用大语言模型(LLM)构建强大的应用成为众多开发者关注的焦点。前面的课程中,我们学习了正则表达式以及向量数据库的相关知识,了解了如何处理文档并将其附加给大模型。本章我们将深入探讨LangChain中的核心概…

    Error:java: 程序包lombok不存在

    使用Maven package打包项目发现报错 一、Maven配置文件修改 1.找到本地 maven的配置文件settings.xml 2.修改配置文件中&#xff0c;指向本地仓库的地址使用 ‘’ \ \ ‘’ 隔开&#xff0c; 要么使用 正斜线 / 隔开 不要使用 反斜线 \ windows OS 电脑&#xff0c;使用 \ …

    WordPress 未授权本地文件包含漏洞(CVE-2025-2294)(附脚本)

    免责申明: 本文所描述的漏洞及其复现步骤仅供网络安全研究与教育目的使用。任何人不得将本文提供的信息用于非法目的或未经授权的系统测试。作者不对任何由于使用本文信息而导致的直接或间接损害承担责任。如涉及侵权,请及时与我们联系,我们将尽快处理并删除相关内容。 0x0…

    基于 C# 开发视觉检测系统项目全解析

    引言 在当今高度自动化的制造业领域,视觉检测系统的重要性愈发凸显。它凭借高速、高精度的特性,在产品外观缺陷检测、尺寸测量等环节发挥着关键作用,显著提升了生产效率和产品质量。C# 作为一种功能强大且易于学习的编程语言,结合.NET 框架丰富的类库以及 Windows Forms、…

    GISBox:核心功能免费的一站式三维GIS处理平台

    大家好&#xff0c;今天为大家介绍的软件是GISBox&#xff1a;一款核心功能免费的一站式三维GIS处理平台&#xff0c;主要是适用于数字孪生。下面&#xff0c;我们将从软件的主要功能、支持的系统、软件官网等方面对其进行简单的介绍。 软件官网&#xff1a;http://www.gisbox.…

    Ubuntu 24 云服务器上部署网站_详细版_1

    从零开始&#xff0c;在 Ubuntu 24 云服务器上部署一个支持登录和权限的网站&#xff0c;用 Python Django 实现&#xff0c;适合新手跟着操作。 &#x1f527; 第一步&#xff1a;更新服务器并安装基础环境 请使用 SSH 登录你的 Ubuntu 24 云服务器&#xff08;用 MobaXterm…

    单片机学习之定时器

    定时器是用来定时的机器&#xff0c;是存在于STM32单片机中的一个外设。STM32一般总共有8个定时器&#xff0c;分别是2个高级定时器&#xff08;TIM1、TIM8&#xff09;&#xff0c;4个通用定时器&#xff08;TIM2、TIM3、TIM4、TIM5&#xff09;和2个基本定时器&#xff08;TI…

    AIGC6——AI的哲学困境:主体性、认知边界与“天人智一“的再思考

    引言&#xff1a;当机器开始"思考" 2023年&#xff0c;Google工程师Blake Lemoine声称对话AI LaMDA具有"自我意识"&#xff0c;引发轩然大波。这一事件将古老的哲学问题重新抛回公众视野&#xff1a;​**机器能否拥有主体性&#xff1f;**从东方"天人…

    从内核到应用层:Linux缓冲机制与语言缓冲区的协同解析

    系列文章目录 文章目录 系列文章目录前言一、缓冲区1.1 示例11.2 缓冲区的概念 二、缓冲区刷新方案三、缓冲区的作用及存储 前言 上篇我们介绍了&#xff0c;文件的重定向操作以及文件描述符的概念&#xff0c;今天我们再来学习一个和文件相关的知识-----------用户缓冲区。 在…

    高通camx IOVA内存不足,导致10-15x持续拍照后,点击拍照键定屏无反应,过一会相机闪退

    定屏闪退问题分析思路&#xff1a; 定屏问题如果是相机问题&#xff0c;一般会出现返帧&#xff0c;导致预览卡死。当然还有其他情况&#xff0c;我们先看返帧情况&#xff0c;发现request和result开始都正常&#xff0c;到12:53:05.443038就没有返帧了&#xff0c;定屏了。往…

    AI知识补全(十五):AI可解释性与透明度是什么?

    名人说&#xff1a;一笑出门去&#xff0c;千里落花风。——辛弃疾《水调歌头我饮不须劝》 创作者&#xff1a;Code_流苏(CSDN)&#xff08;一个喜欢古诗词和编程的Coder&#x1f60a;&#xff09; 上一篇&#xff1a;AI知识补全&#xff08;十四&#xff09;&#xff1a;零样本…

    CentOS 7安装hyperscan

    0x00 前言 HyperScan是一款由Intel开发的高性能正则表达式匹配库&#xff0c;专为需要快速处理大量数据流的应用场景而设计。它支持多平台运行&#xff0c;包括Linux、Windows和macOS等操作系统&#xff0c;并针对x86架构进行了优化&#xff0c;以提供卓越的性能表现。HyperSc…

    机器学习的一百个概念(9)学习曲线

    前言 本文隶属于专栏《机器学习的一百个概念》&#xff0c;该专栏为笔者原创&#xff0c;引用请注明来源&#xff0c;不足和错误之处请在评论区帮忙指出&#xff0c;谢谢&#xff01; 本专栏目录结构和参考文献请见[《机器学习的一百个概念》 ima 知识库 知识库广场搜索&…

    macvlan 和 ipvlan 实现原理及设计案例详解

    一、macvlan 实现原理 1. 核心概念 macvlan 允许在单个物理网络接口上创建多个虚拟网络接口&#xff0c;每个虚拟接口拥有 独立的 MAC 地址 和 IP 地址。工作模式&#xff1a; bridge 模式&#xff08;默认&#xff09;&#xff1a;虚拟接口之间可直接通信&#xff0c;类似交…

    linux文件上传下载lrzsz

    lrzsz 是一个在 Linux 系统中用于通过串行端口(如 ZMODEM、XMODEM、YMODEM 等协议)进行文件上传和下载的工具集。它通常用于在终端环境中通过串口或 SSH 连接传输文件。 安装 lrzsz 在大多数 Linux 发行版中,你可以使用包管理器来安装 lrzsz。 Debian/Ubuntu: sudo apt-ge…

    单片机学习之SPI

    物理层 串行全双工总线 需要四根线&#xff1a;SCLK&#xff08;时钟线&#xff09;&#xff0c;CS&#xff08;片选线&#xff09;、MOSI(主设备输出、从设备输入)&#xff0c;MISO&#xff08;主设备输入&#xff0c;从设备输出&#xff09;。 片选信号 片选信号CS是用来…

    大模型应用初学指南

    随着人工智能技术的快速发展&#xff0c;检索增强生成&#xff08;RAG&#xff09;作为一种结合检索与生成的创新技术&#xff0c;正在重新定义信息检索的方式&#xff0c;RAG 的核心原理及其在实际应用中的挑战与解决方案&#xff0c;通用大模型在知识局限性、幻觉问题和数据安…

    docker-compose部署prometheus+grafana+node_exporter+alertmanager规则+邮件告警

    目录 一.docker-compose文件 二.配置文件 三.文件层级关系&#xff0c;docker-compose和配置文件位于同级目录 四.node_exporter页面json文件 五.效果展示 prometheusalertmanager邮件告警 grafana面板效果 六.涉及离线包 一.docker-compose文件 [rootsulibao prometh…

    AI设计再现新引擎,科技创新又添新动能——广东省首家行业AI设计工程中心获批成立

    近期&#xff0c;大捷智能科技&#xff08;广东&#xff09;有限公司&#xff08;以下简称“大捷智能”&#xff09;凭借其在人工智能与智能制造领域的突出研发实力与创新科技成果&#xff0c;由广东省科技厅批准设立“广东省模具智能设计与智能制造工程技术研究中心”。 广东省…

    【MongoDB + 向量搜索引擎】MongoDB Atlas 向量搜索 提供全托管解决方案

    在代码审计项目中&#xff0c;MongoDB可以用于存储元数据和部分结构化信息&#xff0c;但要高效处理向量相似性搜索&#xff0c;需结合其他工具。以下是具体分析&#xff1a; 1. MongoDB 的适用场景 元数据存储&#xff1a; 存储代码片段的文件路径、行号、语言类型等结构化信…