STL——stack和queue

news/2024/5/20 8:05:22/文章来源:https://blog.csdn.net/weixin_50601177/article/details/132378537

一、stack和queue

stl中提供了栈和队列配接器供我们使用,以后就可以直接使用了。不需要我们自己造轮子。

使用细节参考文档就可以,与之学过的容器并无二致。栈和队列的特性我们再学习数据结构时已经了解了。这里就不在赘述了。

stack - C++ Reference (cplusplus.com)

queue - C++ Reference (cplusplus.com)

这里有几个题可供我们练习一下:

力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台

栈的压入、弹出序列_牛客题霸_牛客网

力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台

在模拟实现stack和queue,我们先了解一下容器适配器;什么是适配器呢?

适配器是一种设计模式(设计模式是一套被反复使用的、多数人知晓的、经过分类编目的、代码设计经验的总结),该种模式是将一个类的接口转换成客户希望的另外一个接口。

stl标准库中stack和queue的底层结构就是使用了适配器模式;虽然stack和queue中也可以存放元素,但在STL中并没有将其划分在容器的行列,而是将其称为容器适配器,这是因为stack和队列只是对其他容器的接口进行了包装,STL中stack和queue默认使用deque(双端队列)下面介绍

stack的模拟实现

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

queue模拟实现

    //双端队列适合进行两端插入删除操作,不适合在中间插入。//相较于vector来说,扩容更好一点。//相较于list来说,支持随机访问template<class T, class Con = deque<T>>//默认类型是双端队列class queue{public:void push(const T& x){_con.push_back(x);}void pop(){//_con.erase(_con.begin());  //vector没有pop_front_con.pop_front();          }int size(){return _con.size();}T& front(){return _con.front();}T& back(){return _con.back();}bool empty(){return _con.empty();}private:Con _con;};

二、deque——双端队列

deque概念

deque(双端队列):是一种双开口的"连续"空间的数据结构,双开口的含义是:可以在头尾两端进行插入和删除操作,且时间复杂度为O(1),与vector比较,头插效率高,不需要搬移元素;与list比较,空间利用率比较高。

 需要注意的是:deque并不是真正连续的空间,而是由一段段连续的小空间拼接而成的,实际deque类似于一个动态的二维数组,其底层结构如下图所示:

双端队列底层是一段假象的连续空间,实际是分段连续的,为了维护其“整体连续”以及随机访问的假象,落在了deque的迭代器身上,因此deque的迭代器设计就比较复杂,如下图所示:

deque的缺陷:

  • 与vector相比,deque的优势是:头部插入和删除时,不需要搬移元素,效率高;而且在扩容时,也不需要搬移大量的元素,因此效率是比vector高。
  • 与list相比,deque底层是连续空间,空间利用率高,不需要存储额外字段。
  • deque的缺陷:不适合遍历,deque的迭代器要频繁的去检测其是否移动到某段小空间的边界,导致效率低下;而序列式场景中,可能需要经常遍历,因此在实际中,需要线性结构
    时,大多数情况下优先考虑vector和list,deque的应用并不多,而目前能看到的一个应用就是,STL用其作为stack和queue的底层数据结构。

为什么选择deque作为stack和queue的底层默认容器

  • stack和queue不需要遍历(因此stack和queue没有迭代器),只需要在固定的一端或两端操作。
  • 在stack中元素增长时,deque比vector效率高(扩容时不需要搬移大量数据),queue中的元素增长时,deque不仅效率高,而且内存使用率高。

三、priority_queue——优先级队列

priority_queue概念

priority_queue - C++ Reference (cplusplus.com)

priority_queue也是一个容器适配器,用vector实现的。

priority_queue底层采用的数据结构是堆(默认是大堆)。

 因为这里使用了仿函数,调用的是less这个类,所以是大堆。

练习: 力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台

什么是仿函数

仿函数就是使用起来类似于使用一个函数,但是它实际上不是调用函数,而是通过类的对象调用类中重载的括号运算符成员函数,从而达到我们的目的。

仿函数可以作为模板参数使用,因为每个仿函数都拥有自己的类型。

仿函数比一般函数更灵活。

priority_queue模拟实现

    template<class T>struct Less{bool operator()(const T& x, const T& y){return x < y;}};template<class T>struct Greater{bool operator()(const T& x, const T& y){return x > y;}};    template<class T, class Con = vector<T>, class Compare = Less<T>>class priority_queue{private://向下调整建堆,建大堆void Adjust_down(int parent){Compare com;int 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])){swap(_con[parent], _con[child]);parent = child;child = parent * 2 + 1;}else{break;}}}void Adjust_up(int child){Compare com;int parent = (child - 1) / 2;while (child > 0){if (com(_con[parent], _con[child])){swap(_con[parent], _con[child]);child = parent;parent = (child - 1) / 2;}else{break;}}}public: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);}}priority_queue(){}void push(const T& x){_con.push_back(x);Adjust_up(_con.size() - 1);}void pop(){swap(_con[0], _con[_con.size() - 1]);_con.pop_back();Adjust_down(0);}size_t size() const {return _con.size();}bool empty() const{return _con.empty();}const T& top(){return _con[0];}private:Con _con;};

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

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

相关文章

new String创建几个对象

在java17中 &#xff1a; 问题1&#xff1a;new String("abc")会产生多少个对象&#xff1f; 分两种情况&#xff1a; 情况1&#xff1a; 如果”abc”这个字符串常量不存在&#xff0c;则创建两个对象&#xff0c;分别是“abc”这个字符串常量&#xff0c;以及ne…

C# 设置、获取程序,产品版本号

右键&#xff0c;程序属性。打开“程序集信息” 选择需要设置的版本信息。下面的代码&#xff0c;获取不同的设置内容。 string 其他 Assembly.GetExecutingAssembly().FullName; string 程序集版本 Assembly.GetExecutingAssembly().G…

从头预训练大模型实践经验

前言 如何从头训练一个基座大模型&#xff1f; 今天介绍一篇文章&#xff0c;其没有更多的理论依据&#xff0c;一切都是一些实践经验。Weights & Biases是一个强大的用于深度学习可视化的工具&#xff0c;可以实现对深度学习各项参数的可视化&#xff0c;本篇介绍的文章…

el-table根据容器大小自适应滚动条-修改滚动条样式

需求&#xff1a;父容器里有多个容器为上下级&#xff0c;之后浏览器在缩放的时候&#xff0c;上面容器高度改变了&#xff0c;所以el-table被挤压&#xff0c;如果el-table设置的是固定的高度&#xff0c;那么挤压后内容超出父容器&#xff0c;本文章就是解决这个问题 不自适…

pytorch 入门1-tensor 广播 view reshape

tensor 的四则运算broadcast import torch import numpy as np # 张量tensor 随机初始化 x torch.rand(4,3) print(x) y torch.randn(4,3) print(y)# 初始化全零 张量 a torch.zeros((4,4),dtypetorch.long) print(a) #初始化全一 张量 b torch.ones(4,4) print(b) c tor…

【MyBatis面试题(20道)】

文章目录 MyBatis 面试题&#xff08;20道&#xff09;基础1.说说什么是MyBatis&#xff1f;2.Hibernate和MyBatis有什么区别&#xff1f;3.MyBatis使用过程&#xff1f;生命周期&#xff1f;4.在mapper中如何传递多个参数&#xff1f;5.实体类属性名和表中字段名不一样&#x…

LeetCode863. 二叉树中所有距离为 K 的结点(相关话题:深度遍历,广度遍历)

题目描述 给定一个二叉树(具有根结点 root), 一个目标结点 target ,和一个整数值 k 。 返回到目标结点 target 距离为 k 的所有结点的值的列表。 答案可以以 任何顺序 返回。 示例 1: 输入:root = [3,5,1,6,2,0,8,null,null,7,4], target = 5, k = 2 输出:[7,4,1] 解释…

5种做法实现table表格中的斜线表头效果(HTML+CSS+JS+Canvas+SVG)

table表格&#xff0c;这个东西大家肯定都不陌生&#xff0c;代码中我们时常都能碰到&#xff0c;那么给table加一个斜线的表头有时是很有必要的&#xff0c;但是到底该怎么实现这种效果呢&#xff1f; 我总结了以下几种方法&#xff1a; 1、最最最简单的做法 直接去找公司的…

c语言每日一练(10)

前言&#xff1a;每日一练系列&#xff0c;每一期都包含5道选择题&#xff0c;2道编程题&#xff0c;博主会尽可能详细地进行讲解&#xff0c;令初学者也能听的清晰。每日一练系列会持续更新&#xff0c;暑假时三天之内必有一更&#xff0c;到了开学之后&#xff0c;将看学业情…

【Linux】Centos安装 mariadb 并授权远程登陆

&#x1f468;‍&#x1f393;博主简介 &#x1f3c5;云计算领域优质创作者   &#x1f3c5;华为云开发者社区专家博主   &#x1f3c5;阿里云开发者社区专家博主 &#x1f48a;交流社区&#xff1a;运维交流社区 欢迎大家的加入&#xff01; &#x1f40b; 希望大家多多支…

ubuntu 20.04 安装 高版本cuda 11.7 和 cudnn最新版

一、安装显卡驱动 参考另一篇文章&#xff1a;Ubuntu20.04安装Nvidia显卡驱动教程_ytusdc的博客-CSDN博客 二、安装CUDA 英伟达官网&#xff08;最新版&#xff09;&#xff1a;CUDA Toolkit 12.2 Update 1 Downloads | NVIDIA Developer CUDA历史版本下载地址&#xff1a;C…

干货!一文告诉你SCRM和CRM有什么区别和联系?

在现代商业领域&#xff0c;我们经常听到两个缩写词&#xff0c;即"SCRM"和"CRM"。它们都与客户关系管理有关&#xff0c;但具体是什么意思&#xff1f;本文将用通俗易懂的方式解释这两个概念&#xff0c;以实例分析SCRM和CRM的功能并探讨它们之间的区别和…

【搭建WebDAV服务手机ES文件浏览器远程访问】

文章目录 1. 安装启用WebDAV2. 安装cpolar3. 配置公网访问地址4. 公网测试连接5. 固定连接公网地址6. 使用固定地址测试连接 有时候我们想通过移动设备访问群晖NAS 中的文件,以满足特殊需求,我们在群辉中开启WebDav服务,结合cpolar内网工具生成的公网地址,通过移动客户端ES文件…

一种新型的4H-SiC超结共模场效应晶体管(UMOSFET),具有异质结二极管,以提高反向恢复特性

标题&#xff1a;A novel 4H-SiC super junction UMOSFET with heterojunction diode for enhanced reverse recovery characteristics 摘要 摘要—本文提出并通过数值模拟研究了一种新型的碳化硅&#xff08;SiC&#xff09;超结共模场效应晶体管&#xff08;UMOSFET&#xf…

发布python模仿2023年全国职业的移动应用开发赛项样式开发的开源的新闻api,以及安卓接入案例代码

python模仿2023年全国职业的移动应用开发赛项样式开发的开源的新闻api&#xff0c;以及原生安卓接入案例代码案例 源码地址:keyxh/newsapi: python模仿2023年全国职业的移动应用开发赛项样式开发的开源的新闻api&#xff0c;以及安卓接入案例代码 (github.com) 目录 1.环境配…

WSL2和本地windows端口互通

众所周知 WSL 默认安装后&#xff0c;只允许windows访问 Windows Subsystem for Linux&#xff0c;而WSL是不能反之访问本地windows。我之前用vmware的思路认为是nat的网络模式&#xff0c;于是改成了桥接&#xff0c;结果wsl的桥接模式被我改的能访问本地&#xff0c;但是却不…

Jmeter 接口测试总结

背景介绍 对于 Android 项目来说&#xff0c;使用的是 Java 开发&#xff0c;网络请求接口的数量庞大且复杂&#xff0c;测试人员无法很直观的判断、得出网络请求是否存在问题。另一方面&#xff0c;为了验证请求接口是否能够在大负荷条件下&#xff0c;长时间、稳定、正常的运…

3、Spring之底层架构核心概念解析

BeanDefinition BeanDefinition表示Bean定义,BeanDefinition中存在很多属性用来描述一个Bean的特点。比如: class,表示Bean类型scope,表示Bean作用域,单例或原型等lazyInit:表示Bean是否是懒加载initMethodName:表示Bean初始化时要执行的方法destroyMethodName:表示Be…

善于打仗的人,没有特别大的名气和勇功

善于打仗的人&#xff0c;没有特别大的勇功 【安志强趣讲《孙子兵法》第15讲】 【原文】 见胜不过众人之所知&#xff0c;非善之善者也&#xff1b;战胜而天下曰善&#xff0c;非善之善者也。 【趣讲白话】 预判胜负没有超出常人的见识&#xff0c;算不上高明中最高明的&#x…

简单认识Docker的资源控制

文章目录 一、CPU资源限制1.设置CPU使用率上限2.设置CPU资源占用比&#xff08;设置多个容器才有效&#xff09;3.设置容器与CPU绑核 二、内存资源限制三、对磁盘I/O配额的限制 一、CPU资源限制 1.设置CPU使用率上限 Linux通过CFS&#xff08;Completely Fair Scheduler&#…