stack和queue简单模拟实现

  • stack
  • reverse_iterator
  • queue
  • priority_queue
    • 仿函数
    • 具体代码

stack

Stacks are a type of container adaptor, specifically designed to operate in a LIFO context (last-in first-out), where elements are inserted and extracted only from one end of the container.

上述描述出自cplusplus.

重点是stack是一个container adaptor也就是容器适配器。
这意味着我们不需要也没有必要从0开始实现stack的方法,而可以通过一个模板,来调用其他容器来实现,以下是stack的部分从成员函数:

template<class T, class Container = deque<int>>
class stack
{
public:void push(const T& x){_con.push_back(x);}void pop(){_con.pop_back();}size_t size(){return _con.size();}bool empty(){return _con.empty();}const T& top(){return _con.back();}private:Container _con;
};

可以发现只需要调用传来的模板参数即可。

这里的默认容器是deque,这是一个均衡的容器,整体效率没有vector高,但是可以实现push_front。这是vector做不到的,或者说vector的头插效率是O(n),过低。

值得注意的是,所有容器适配器都不支持迭代器
就以stack举例,如果支持迭代器,那是否意味着破坏了他的FILO特性呢?是的。因此不支持迭代器。

reverse_iterator

上文提到容器适配器,那就不得不提到反向迭代器了。
之前我们实现vector和list的时候都没有实现反向迭代器,因为两者内容过于相似,现在了解了反向迭代器的机制后我们知道,是否可以通过穿入迭代器容器,然后实现反向迭代器。

这意味着,我们可以同时实现所有容器的反向迭代器,也就是实现他们的模板:

template<class Iterator,class Ref,class Ptr>
struct Reverse_iterator
{typedef Reverse_iterator<Iterator, Ref, Ptr> Self;Iterator _it;Reverse_iterator(Iterator it):_it(it){}Ref operator*(){Iterator tmp = _it;return *((--tmp));}Ptr operator->(){return &(operator*());}Self& operator++(){return --_it;}Self& operator--(){return ++_it;}bool operator!=(const Self& it){return _it != it;}};

需要注意的一点是,我们的operator*返回的是 *(--tmp),而不是 *(tmp).

原因是,我们的rbegin()和rend()返回的是end()和begin()。这是基于代码对称性考虑的,正常而言我们的rbegin()和rend()理应返回end()-1和begin()-1.

为了解决这个问题,就只能令operator*返回 *(--tmp)

注:以上实现是visual studio的实现方式。

queue

template<class T, class Container = deque<int>>
class queue
{
public:void push(const T& x){_con.push_back(x);}void pop(){_con.pop_front();}size_t size(){return _con.size();}bool empty(){return _con.empty();}const T& front(){return _con.front();}const T& back(){return _con.back();}private:Container _con;
};

priority_queue

priority_queue实质上就是一个堆,并且是默认大根堆。那么我们想要将其改变为小根堆改如何实现?
如果是C语言的话,我们会增加一个函数指针的参数来实现。
在C++中,我们通过传入一个仿函数来实现。

仿函数

所谓仿函数就是指能够像函数一样使用的对象,如下:

template<class T>
class less
{
public:bool operator()(const T& x, const T& y){return x < y;}
};
void test(int x,int y)
{less l;if(l(x,y))cout<<"x<y";else cout<<"x>=y";
}

本质上,我们重载了 (),因此能够将这个对象像函数一样使用。

具体代码

堆的实现,我们已经讲过,这里就不做赘述,感兴趣的读者可以翻阅我前面的文章。

template<class T,class Container=vector<T>,class Compare = less<T>>
class priority_queue
{
public://默认大堆void adjust_up(size_t child){size_t parent = (child - 1) / 2;Compare com;while (child >0){if (com(_con[parent], _con[child])){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){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;}}}void pop(){std::swap(_con[0], _con[_con.size() - 1]);_con.pop_back();adjust_down(0);}bool empty(){return _con.empty();}size_t size(){return _con.size();}const T& top(){return _con[0];}private:Container _con;
};

说起来这里比较奇怪的点是,默认传入less<T>是大根堆,而穿入greater<T>却是小根堆。
但sort穿入,less<T>却是升序排序:

int main()
{vector<int>v = { 1,5,4,3,2 };sort(v.begin(), v.end(),less<int>());//传入less的匿名对象for (auto& e : v)cout << e << ' ';cout << endl;return 0;
}

Output:1 2 3 4 5

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

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

相关文章

Linux内核可配置的参数

sysctl -a 命令会列出当前Linux内核所有可配置的参数及其当前值。这些参数允许你在系统运行时动态地调整内核的行为&#xff0c;而无需重新编译内核或重启系统。 内容非常多&#xff0c;因为内核有很多可调的方面。我们可以把它们大致分为几个主要类别&#xff1a; kernel.*: …

【背包dp-----分组背包】------(标准的分组背包【可以不装满的 最大价值】)

通天之分组背包 题目链接 题目描述 自 01 01 01 背包问世之后&#xff0c;小 A 对此深感兴趣。一天&#xff0c;小 A 去远游&#xff0c;却发现他的背包不同于 01 01 01 背包&#xff0c;他的物品大致可分为 k k k 组&#xff0c;每组中的物品相互冲突&#xff0c;现在&a…

操作系统:os概述

操作系统&#xff1a;OS概述 程序、进程与线程无极二级目录三级目录 程序、进程与线程 指令执行需要那些条件&#xff1f;CPU内存 需要数据和 无极 二级目录 三级目录

RAG文本分块

不论是向量化模型还是大语言模型&#xff0c;都存在输入长度的限制。对于超过限制的文本&#xff0c;模型会进行截断&#xff0c;造成语义缺失。分块可以确保每个文本片段都在模型的处理范围内&#xff0c;避免重要信息的丢失。 文本分块的核心原则 高质量分块的核心原则是&a…

2025 年九江市第二十三届中职学校技能大赛 (网络安全)赛项竞赛样题

2025 年九江市第二十三届中职学校技能大赛 &#xff08;网络安全&#xff09;赛项竞赛样题 &#xff08;二&#xff09;A 模块基础设施设置/安全加固&#xff08;200 分&#xff09;A-1 任务一登录安全加固&#xff08;Windows,Linux&#xff09;A-2 任务二 Nginx 安全策略&…

量子隧穿:PROFINET到Ethernet ip的无损耗协议转换方案转

在本季度的生产工作中&#xff0c;我们成功实现了仓储物流自动化分拣系统中的关键技术突破。我们面临的主要挑战是将采用EtherNet/IP协议的输送带控制器与PROFINET协议的上位系统进行有效通信。通过引入ethernet IP转PROFINET网关倍讯科技BX-606-EIP&#xff0c;我们实现了输送…

OpenCV CUDA模块中矩阵操作------降维操作

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 算法描述 cv::cuda::reduce 函数用于对 GPU 上的矩阵沿某个维度进行降维操作&#xff0c;例如求和、取最大值等。此函数支持多种降维操作&#xff0c;并允…

一分钟用 MCP 上线一个 贪吃蛇 小游戏(CodeBuddy版)

我正在参加CodeBuddy「首席试玩官」内容创作大赛&#xff0c;本文所使用的 CodeBuddy 免费下载链接&#xff1a;腾讯云代码助手 CodeBuddy - AI 时代的智能编程伙伴 你好&#xff0c;我是悟空。 背景 上篇我们用 MCP 上线了一个 2048 小游戏&#xff0c;这次我们继续做一个 …

简单神经网络(ANN)实现:从零开始构建第一个模型

本文将手把手带你用 Python Numpy 实现一个最基础的人工神经网络&#xff08;Artificial Neural Network, ANN&#xff09;。不依赖任何深度学习框架&#xff0c;适合入门理解神经网络的本质。 一、项目目标 构建一个三层神经网络&#xff08;输入层、隐藏层、输出层&#xf…

使用python进行人员轨迹跟踪

一、系统概述 该系统基于计算机视觉技术&#xff0c;实现对视频或摄像头画面中的人员进行检测、跟踪&#xff0c;并生成轨迹数据。支持透视变换校准&#xff08;鸟瞰图显示&#xff09;、多目标跟踪、轨迹存储及视频录制功能&#xff0c;适用于安防监控、行为分析等场景。 二…

[强化学习的数学原理—赵世钰老师]学习笔记02-贝尔曼方程

本人为强化学习小白&#xff0c;为了在后续科研的过程中能够较好的结合强化学习来做相关研究&#xff0c;特意买了西湖大学赵世钰老师撰写的《强化学习数学原理》中文版这本书&#xff0c;并结合赵老师的讲解视频来学习和更深刻的理解强化学习相关概念&#xff0c;知识和算法技…

Docker入门指南:镜像、容器与仓库的核心概念解析

目录 前言&#xff1a;为什么需要Docker&#xff1f; 一、Docker能做什么&#xff1f; 二、核心概念解析 1. 镜像&#xff08;Image&#xff09;&#xff1a;应用的标准化打包 2. 容器&#xff08;Container&#xff09;&#xff1a;镜像的运行实例 3. 镜像仓库&#xff0…

大模型微调实战:基于GpuGeek平台的低成本高效训练方案

文章目录 引言一、GpuGeek平台使用入门1. 注册与账号设置2. 控制台功能概览3. 快速创建GPU实例3. 预置镜像与自定义环境 二、GpuGeek平台核心优势解析1. 显卡资源充足&#xff1a;多卡并行加速训练2. 镜像超多&#xff1a;开箱即用的开发环境3. 计费灵活&#xff1a;按需付费降…

Linux:计算机的层状结构

1.冯诺依曼体系结构 我们常见的计算机&#xff0c;如笔记本、台式机。我们不常见的计算机&#xff0c;如服务器&#xff0c;大部分都遵守冯诺依曼体系结构。 CPU&#xff1a;运算器和控制器组成。运算器主要工作是做算术运算和逻辑运算。控制器主要工作是协调设备之间信息流动的…

LangGraph(四)——加入人机交互控制

目录 1. 引言2. 添加Human Assistance工具3. 编译状态图4. 提示聊天机器人5. 恢复执行参考 1. 引言 智能体可能不可靠&#xff0c;甚至需要人工输入才能完成任务。同样&#xff0c;对于某些操作&#xff0c;你可能需要在运行前获得人工批准&#xff0c;以保证一切按预期运行。 …

数据结构【AVL树】

AVL树 1.AVL树1.AVL的概念2.平衡因子 2.AVl树的实现2.1AVL树的结构2.2AVL树的插入2.3 旋转2.3.1 旋转的原则 1.AVL树 1.AVL的概念 AVL树可以是一个空树。 它的左右子树都是AVL树&#xff0c;且左右子树的高度差的绝对值不超过1。AVL树是一颗高度平衡搜索二叉树&#xff0c;通…

JavaScript【5】DOM模型

1.概述&#xff1a; DOM (Document Object Model)&#xff1a;当页面被加载时&#xff0c;浏览器会创建页面的文档对象模型&#xff0c;即dom对象&#xff1b;dom对象会被结构化为对象树&#xff0c;如一个HTML文档会被分为head&#xff0c;body等部分&#xff0c;而每个部分又…

STM32烧录程序正常,但是运行异常

一、硬件配置问题 BOOT引脚设置错误 STM32的启动模式由BOOT0和BOOT1引脚决定。若设置为从RAM启动&#xff08;BOOT01&#xff0c;BOOT10&#xff09;&#xff0c;程序在掉电后无法保存&#xff0c;导致复位后无法正常运行。应确保BOOT00&#xff08;从Flash启动&#xff09;15。…

汽车二自由度系统模型以及电动助力转向系统模型

汽车二自由度系统模型与电动助力转向系统&#xff08;EPS&#xff09;的详细建模方案&#xff0c;包含理论推导、MATLAB/Simulink实现代码及参数说明&#xff1a; 一、二自由度汽车模型 1. 模型描述 包含以下两个自由度&#xff1a; 横向运动&#xff08;侧向加速度&#xf…

git提交库常用词

新功能 feat修改BUG fix文档修改 docs格式修改 style重构 refactor性能提升 perf测试 test构建系统 build对CI配置文件修改 ci修改构建流程、或增加依赖库、工具 chore回滚版本 revert