C++stack,queue,priority_queue容器(个人笔记)

C++栈队列优先级队列

    • 1.熟悉stack接口以及使用
      • 1.1stack的接口
      • 1.2stack的模拟实现
      • 1.3stack的一些笔试题
    • 2.熟悉queue接口以及使用
      • 2.1queue的接口
      • 2.2queue的模拟实现
      • 2.3queue的笔试题
    • 3.熟悉priority_queue的接口以及使用(底层堆)
      • 3.1priority_queue的接口
      • 3.2priority_queue的模拟实现
      • 3.3priority_queue的笔试题
    • 4.容器适配器
      • 4.1deque(了解)(双端队列)
        • 4.1.1deque的优缺点
        • 4.1.2为什么选择deque作为stack和queue的底层默认容器

1.熟悉stack接口以及使用

stack的C++官方文档

1.1stack的接口

函数说明接口说明
stack()构造空的栈
empty()检测stack是否为空
size()返回stack中元素个数
top()返回栈顶元素的引用
push()将元素val压入stack中
pop()将stack中尾部的元素弹出

1.2stack的模拟实现

//STL下的stack实现
#include<deque>
namespace ljh
{template<class T,class container=std::deque<T>>class stack{stack(){}void push(const T& x){_c.push_back(x);}void pop(){_c.pop_back();}T& top(){return _c.back();}const T& top() const{return _c.back();}size_t size() const{return _c.size();}bool empty() const{return _c.empty();}private:container _c;};
}

1.3stack的一些笔试题

最小栈
在这里插入图片描述

class MinStack {
public:stack<int> _st;stack<int> _minst;MinStack(){}void push(int val){_st.push(val);if(_minst.empty()||val<=_minst.top()){_minst.push(val);}}void pop(){int val=_st.top();_st.pop();if(val==_minst.top()){_minst.pop();}}int top(){return _st.top();}int getMin(){return _minst.top();}
};

栈的压入、弹出序列
在这里插入图片描述

class Solution {
public:bool IsPopOrder(vector<int>& pushV, vector<int>& popV){stack<int> st;size_t pushi=0;size_t popi=0;while(pushi<pushV.size()){st.push(pushV[pushi++]);while(!st.empty()&&st.top()==popV[popi]){st.pop();popi++;}}return st.empty();}
};

逆波兰表达式
在这里插入图片描述

class Solution {
public:int evalRPN(vector<string>& tokens){stack<int> st;for(auto &str:tokens){if(str=="+"||str=="-"||str=="*"||str=="/"){int right=st.top();st.pop();int left=st.top();st.pop();switch(str[0]){case '+':st.push(left+right);break;case '-':st.push(left-right);break;case '*':st.push(left*right);break;case '/':st.push(left/right);break;}}else{st.push(stoi(str));}}return st.top();}
};

栈实现队列
在这里插入图片描述

class MyQueue {
public:MyQueue(){}void push(int x){_pushst.push(x);}int pop(){int ret=this->peek();_popst.pop();return ret;}int peek(){if(_popst.empty()){while(!_pushst.empty()){_popst.push(_pushst.top());_pushst.pop();}}return _popst.top();}bool empty(){return _pushst.empty()&&_popst.empty();}stack<int> _pushst;stack<int> _popst;
};

2.熟悉queue接口以及使用

queue的C++官方文档

2.1queue的接口

函数声明接口说明
queue()构造空的队列
empty()检测队列是否为空,是返回true,否则返回false
size()返回队列中有效元素的个数
front()返回队头元素的引用
back()返回队尾元素的引用
push()在队尾将元素val入队列
pop()将队头元素出队列

2.2queue的模拟实现

//STL下queue的实现
#include<queue>
#include<list>
namespace ljh
{template<class T,class container=std::deque<T>>//template<class T,class container=std::list<T>>class queue{public:queue(){}void push(const T& x){_c.push_back(x);}void pop(){_c.pop_front();}T& back(){return _c.back();}const T& back()const{return _c.back();}T& front(){return _c.front();}const T& front()const{return _c.front();}size_t size()const{return _c.size();}bool empty()const{return _c.empty();}private:container _c;};
}

2.3queue的笔试题

队列实现栈
在这里插入图片描述

class MyStack {
public:MyStack(){}void push(int x){if(!q1.empty()){q1.push(x);}else{q2.push(x);}}int pop(){if(!q1.empty()){while(q1.size()>1){q2.push(q1.front());q1.pop();}int ret=q1.front();q1.pop();return ret;}else{while(q2.size()>1){q1.push(q2.front());q2.pop();}int ret=q2.front();q2.pop();return ret;}}int top(){if(!q1.empty()){return q1.back();}else{return q2.back();}}bool empty(){return q1.empty()&&q2.empty();}queue<int> q1;queue<int> q2; 
};

3.熟悉priority_queue的接口以及使用(底层堆)

priority_queueC++官方文档
以下稍微看看就行:

  1. 优先队列是一种容器适配器,根据严格的弱排序标准,它的第一个元素总是它所包含的元素中最大的。
  2. 此上下文类似于堆,在堆中可以随时插入元素,并且只能检索最大堆元素(优先队列中位于顶部的元素)。
  3. 优先队列被实现为容器适配器,容器适配器即将特定容器类封装作为其底层容器类,queue提供一组特定的成员函数来访问其元素。元素从特定容器的“尾部”弹出,其称为优先队列的顶部。
  4. 底层容器可以是任何标准容器类模板,也可以是其他特定设计的容器类。容器应该可以通过随机访问迭代器访问,并支持以下操作:
    empty():检测容器是否为空
    size():返回容器中有效元素个数
    front():返回容器中第一个元素的引用
    push_back():在容器尾部插入元素
  5. 标准容器类vector和deque满足这些需求。默认情况下,如果没有为特定的priority_queue类实例化指
    定容器类,则使用vector。
  6. 需要支持随机访问迭代器,以便始终在内部保持堆结构。容器适配器通过在需要时自动调用算法函数
    make_heap、push_heap和pop_heap来自动完成此操作

3.1priority_queue的接口

优先级队列默认使用vector作为其底层存储数据的容器,在vector上又使用了堆算法将vector中元素构造成
堆的结构,因此priority_queue就是堆,所有需要用到堆的位置,都可以考虑使用priority_queue。注意:
默认情况下priority_queue是大堆。

函数声明接口说明
priority_queue()/priority_queue(first,last)构造一个空的优先级队列和迭代器区间构造的优先级队列
empty()检测优先级队列是否为空,是返回true,否则返回false
top()返回优先级队列中最大(最小元素),即堆顶元素
push(x)在优先级队列中插入元素x
pop()删除优先级队列中最大(最小)元素,即堆顶元素

注意:

  1. 默认情况下,priority_queue是大堆
#include <vector>
#include <queue>
#include <functional> // greater算法的头文件
void TestPriorityQueue()
{// 默认情况下,创建的是大堆,其底层按照小于号比较vector<int> v{3,2,7,6,0,4,1,9,8,5};priority_queue<int> q1(v.begin(),v.end());cout << q1.top() << endl;// 如果要创建小堆,将第三个模板参数换成greater比较方式priority_queue<int, vector<int>, greater<int>> q2(v.begin(), v.end());cout << q2.top() << endl;
}
  1. 如果在priority_queue中放自定义类型的数据,用户需要在自定义类型中提供> 或者< 的重载。
class Date
{
public:Date(int year = 1900, int month = 1, int day = 1): _year(year), _month(month), _day(day){}bool operator<(const Date& d)const{return (_year < d._year) ||(_year == d._year && _month < d._month) ||(_year == d._year && _month == d._month && _day < d._day);}bool operator>(const Date& d)const{return (_year > d._year) ||(_year == d._year && _month > d._month) ||(_year == d._year && _month == d._month && _day > d._day);}friend ostream& operator<<(ostream& _cout, const Date& d){_cout << d._year << "-" << d._month << "-" << d._day;return _cout;}
private:int _year;int _month;int _day;
};void TestPriorityQueue()
{// 大堆,需要用户在自定义类型中提供<的重载priority_queue<Date> q1;q1.push(Date(2018, 10, 29));q1.push(Date(2018, 10, 28));q1.push(Date(2018, 10, 30));cout << q1.top() << endl;// 如果要创建小堆,需要用户提供>的重载priority_queue<Date, vector<Date>, greater<Date>> q2;q2.push(Date(2018, 10, 29));q2.push(Date(2018, 10, 28));q2.push(Date(2018, 10, 30));cout << q2.top() << endl;
}

3.2priority_queue的模拟实现

#pragma once
#include<iostream>
using namespace std;#include<vector>
//priority_queue->堆
namespace ljh
{template<class T>struct less{bool operator()(const T& left, const T& right){return left < right;}};template<class T>struct greater{bool operator()(const T& left, const T& right){return left > right;}};template<class T,class Container=std::vector<T>,class Compare=less<T>>class priority_queue{public:priority_queue(){}template<class InputIterator>priority_queue(InputIterator first, InputIterator last):_con(first, last){for (int i = (_con.size() - 2) / 2;i >= 0;i--){adjust_down(i);}}void adjust_up(int child){Compare com;int parent = (child - 1) / 2;while (child > 0){if (com(_con[parent], _con[child])){swap(_con[child], _con[parent]);child = parent;parent = (child - 1) / 2;}else{break;}}}void adjust_down(int 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])){swap(_con[child], _con[parent]);parent = child;child = child * 2 + 1;}else{break;}}}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);}const T& top(){return _con[0];}bool empty(){return _con.empty();}size_t size(){return _con.size();}private:Container _con;};
}

3.3priority_queue的笔试题

数组中第k个最大元素
在这里插入图片描述

class Solution {
public:int findKthLargest(vector<int>& nums, int k){priority_queue<int> q(nums.begin(),nums.end());while(--k){q.pop();}return q.top();}
};

4.容器适配器

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

实际上STL标准库中stack和queue是容器适配器
在这里插入图片描述
在这里插入图片描述

4.1deque(了解)(双端队列)

deque(双端队列):是一种双开口的"连续"空间的数据结构,双开口的含义是:可以在头尾两端进行插入和
删除操作,且时间复杂度为O(1),与vector比较,头插效率高,不需要搬移元素;与list比较,空间利用率比
较高。
在这里插入图片描述
如果说中控数组满了,则需要扩容,但扩容的代价低

中间位置插入删除数据是整体挪动数据还是对单个buff数组扩容,实际上两种都行,第一种的buff是一样大,则[]访问会快很多
整体挪动优势:
x=i/10 确认在第几个buff
y=i%10 确认在这个buff数组的第几个位置
劣势:挪动数据代价大

单个buff数组扩容优势:
扩容代价小
劣势:数组访问[]比较麻烦

4.1.1deque的优缺点

优点:
与vector比较,deque的优势是:头部插入和删除时,不需要搬移元素,效率特别高,而且在扩容时,也不
需要搬移大量的元素
与list比较,其底层是连续空间,空间利用率比较高,不需要存储额外字段。

缺点:不适合遍历,因为在遍历时,deque的迭代器要频繁的去检测其是否移动到某段小空间的边界,导致效率低下,而序列式场景中,可能需要经常遍历,因此在实际中,需要线性结构时,大多数情况下优先考虑vector和list,deque的应用并不多,而目前能看到的一个应用就是,STL用其作为stack和queue的底层数据结构。

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

stack是一种后进先出的特殊线性数据结构,因此只要具有push_back()和pop_back()操作的线性结构,都可以作为stack的底层容器,比如vector和list都可以;queue是先进先出的特殊线性数据结构,只要具有push_back和pop_front操作的线性结构,都可以作为queue的底层容器,比如list。
但是STL中对stack和queue默认选择deque作为其底层容器,主要是因为:

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

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

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

相关文章

spdlog C++日志管理 安装和下载

下载地址 https://github.com/gabime/spdlog?tabreadme-ov-file 使用git拉取代码 按照操作进行编译 点击spdlog.sln&#xff0c;用vs2019打开&#xff0c;进行编译debug x64 每项都编译一下&#xff0c;会生成安装包 安装包下载路径 https://download.csdn.net/download…

【AI学习中常见专业英文缩写词的解释】

前言&#xff1a; 为了看着不无聊&#xff0c;文中插入了一些AI生成的狗图片 AI(Artificail Intelligence)人工智能&#xff1a; 让机器模拟和展示人类智能的技术。 GAI(Generative Artificail Intelligence)生成式人工智能: 利用复杂的算法、模型和规则&#xff0c;从大规…

mysql数据库表的数据显示到前端tableView

首先我们在ui视图设计中引入TableView, 定义一个model QSqlQueryModel *modelnew QSqlQueryModel(ui->tableView);model->setQuery(query);//将查询结果绑定到模型上ui->tableView->setModel(model); 将tableView内容设置成model然后就可以出现数据库的数据。示…

2.8 构建gradle环境

构建gradle环境 目录一、安装Java Development Kit (JDK)二、下载Gradle三、解压Gradle四、配置环境变量五、验证安装六、gradle构建java项目七、eclipse配置gradle 目录 一、安装Java Development Kit (JDK) Gradle是基于Java开发的&#xff0c;所以首先需要安装JDK。你可以从…

春秋云境:CVE-2022-32991[漏洞复现]

从CVE官网查询该漏洞相关信息 该漏洞是由于welcome.php中的eid参数包含了SQL注入漏洞 则我们的目标就在于寻找welcome.php地址以及相关的可注入eid参数 开启靶机 先在页面正常注册、登录一个账号。密码随便填 进入了home目录&#xff0c;这里有三个话题可以选择开启 随便选…

【服务器部署篇】Linux下Nginx的安装和配置

作者介绍&#xff1a;本人笔名姑苏老陈&#xff0c;从事JAVA开发工作十多年了&#xff0c;带过刚毕业的实习生&#xff0c;也带过技术团队。最近有个朋友的表弟&#xff0c;马上要大学毕业了&#xff0c;想从事JAVA开发工作&#xff0c;但不知道从何处入手。于是&#xff0c;产…

【MySQL】20. 使用C语言链接

mysql connect mysql的基础&#xff0c;我们之前已经学过&#xff0c;后面我们只关心使用 要使用C语言连接mysql&#xff0c;需要使用mysql官网提供的库&#xff0c;大家可以去官网下载 我们使用C接口库来进行连接 要正确使用&#xff0c;我们需要做一些准备工作&#xff1a; …

从零构建生产级 AI 应用 ChatWithPDF

前言 目前 AIGC 的浪潮很火&#xff0c;不管你是什么方向的程序员&#xff0c;都可以通过大模型去构建自己的 App&#xff0c;但是搜索资料学习的时候发现&#xff1a; 目前构建 AI 应用的中文资源比较少&#xff0c;大多数都是英文的。教程大多是 demo 级别&#xff0c;没有…

claude3会员版怎么在国内充值

由于国内尚未正式开放注册&#xff0c;许多用户可能感到有些不便。但在这个时代&#xff0c;如果没有几个得心应手的AI工具链接&#xff0c;似乎都与时代脱节了。今天推荐一个非常实用的Claude3镜像站点&#xff1a; https://hiclaude3.cn 这个站点不仅拥有简洁明了的对话操作…

车联网大数据与人工智能一体化:开启智慧出行新时代

随着物联网技术的快速发展&#xff0c;车联网已经成为了汽车行业的重要趋势之一。而在车联网的发展过程中&#xff0c;大数据和人工智能的应用也日益成为关键因素。本文将探讨如何将大数据与人工智能一体化应用于车联网&#xff0c;以实现智慧出行的目标。 尤其是近来国内的华为…

JavaSE备忘录(未完)

文章目录 基本数据类型println 小知识除法( / ) 和 Infinity(无穷) 小知识除法InfinityInfinity 在除法中正负判断 求余(%) 小知识 基本数据类型 除 int、char 的包装类分别为 Integer、Character 外&#xff0c;其余基本数据类型的第一个字母大写就是它的包装类。 println 小…

spingboot3项目创建入门体验

spingboot3流程体验 项目简易打包部署 Spring Initializr 创建向导 spingboot3流程体验 先在IDEA创建一个新的空项目 然后在项目中创建一个模块 在pom.xml文件中添加maven配置继承spingboot3父项目和web开发场景启动器 创建启动springboot项目的主入口程序文件 import org.sp…

初识C++ · 类和对象(中)(1)

目录 1 类的6个默认成员函数 2 构造函数 3 析构函数 3 拷贝构造函数 1 类的6个默认成员函数 class Date { public:private:}; 这是一个空类&#xff0c;试问里面有什么&#xff1f; 可能你会觉得奇怪&#xff0c;明明是一个空类&#xff0c;却问里面有什么。其实一点也不…

数据融合概念解析:特征融合与特征交互

特征融合与特征交互的区别 我是目录 特征融合与特征交互的区别前言三者关系三者定义特性融合(Feature Fusion):特征拼接(Feature Concatenation):特征交互(Feature Interaction): 特征融合和特征交互关键的不同点数据处理目的应用 总结 前言 遥感系列第14篇。遥感图像处理方向…

js解密心得,记录一次抓包vue解密过程

背景 有个抓包结果被加密了 1、寻找入口&#xff0c;打断点 先正常请求一次&#xff0c;找到需要的请求接口。 寻找入口&#xff0c;需要重点关注几个关键字&#xff1a;new Promise 、new XMLHttpRequest、onreadystatechange、.interceptors.response.use、.interceptors.r…

c++的学习之路:25、map与set

摘要 本文中说一下map与set的使用 目录 摘要 一、关联式容器 二、键值对 三、map 1、map的介绍 2、map的使用 1、map的模板参数说明&#xff1a; 2、map的构造 3、map的迭代器 4、map的容量与元素访问 5、map中元素的修改 6、代码使用 ​编辑 三、总结 四、se…

PMM2 MySQL监控管理工具

目录 1. PMM介绍 2. 安装PMM服务端 2.1 安装docker 2.1.1 下载docker 2.1.2 上传docker包 2.1.3 启动守护进程 2.1.4 查看docker状态 2.2 安装PMM 2.2.1 下载镜像 2.2.2 load镜像 2.2.3 查看镜像 2.2.4 创建容器 2.2.5 运行镜像 2.2.6 验证PMM服务器 2.2.7 删除…

外包干了16天,技术倒退明显

先说情况&#xff0c;大专毕业&#xff0c;18年通过校招进入湖南某软件公司&#xff0c;干了接近6年的功能测试&#xff0c;今年年初&#xff0c;感觉自己不能够在这样下去了&#xff0c;长时间呆在一个舒适的环境会让一个人堕落&#xff01; 而我已经在一个企业干了四年的功能…

【剪映专业版】09定格、倒放、镜像、旋转、裁剪

视频课程&#xff1a;B站有知公开课【剪映电脑版教程】 分别为定格、倒放、镜像、旋转、裁剪 定格 时间指示器移动到需要定格的地方&#xff0c;点击定格&#xff0c;自动生成一张图片&#xff0c;时长为3秒。 定格出来的画面&#xff0c;可以任意调整长短时间。 如果需要导…

MySQL高级(性能分析-查看执行频次、慢查询日志)

目录 1、SQL性能分析 1.1、SQL执行频率 1.2、慢查询日志 1、SQL性能分析 1.1、SQL执行频率 MySQL 客户端连接成功后&#xff0c;通过 show [ session | global ] status 命令可以提供服务器状态信息。通过如下指令&#xff0c;可以查看当前数据库的 insert、update、delete、…