[C++](13)stack queue priority_queue 模拟实现:容器适配器,deque介绍,仿函数详解
文章目录
- 使用
- stack 栈
- queue 队列
- priority_queue 优先级队列
- 什么是容器适配器?
- deque 容器简单介绍
- 模拟实现
- stack
- queue
- priority_queue
- 写死的大堆
- 仿函数
- 活的堆
- 兼容函数指针写法
- 迭代器范围构造
- 完整代码
- 仿函数其他用法
- 内置类型排序
- 自定义类型排序
- 反向迭代器(迭代器适配器)
使用
stack 栈
使用前需包含头文件 <stack>
stack
和 queue
不支持迭代器,这两种容器不应该让人随意遍历。
- 入栈:
push
- 查看栈顶元素:
top
- 出栈:
pop
例:
void test1()
{stack<int> s;s.push(1);s.push(2);s.push(3);s.push(4);while (!s.empty()){cout << s.top() << ' ';s.pop();}cout << endl;
}
//结果:4 3 2 1
queue 队列
使用前需要包含头文件 <queue>
- 入队:
push
- 出队:
pop
- 查看队头:
front
- 查看队尾:
back
void test2()
{queue<int> q;q.push(1);q.push(2);q.push(3);q.push(4);while (!q.empty()){cout << q.front() << ' ';q.pop();}cout << endl;
}
//结果:1 2 3 4
priority_queue 优先级队列
priority_queue 就是堆,其默认使用 vector 作为其底层存储数据的容器。
priority_queue 默认是大堆。
- 插入一个值:push
- 查看堆顶元素:top
- 删除堆顶元素:pop
例:
void test3()
{priority_queue<int> pq;pq.push(1);pq.push(6);pq.push(5);pq.push(9);pq.push(8);while (!pq.empty()){cout << pq.top() << ' ';pq.pop();}cout << endl;
}
//结果:9 8 6 5 1
改成小堆需要仿函数相关的知识,会在后面讲解,这里演示用法:
需要包含头文件 <functional>
void test3()
{priority_queue<int, vector<int>, greater<int>> pq; //小堆pq.push(1);pq.push(6);pq.push(5);pq.push(9);pq.push(8);while (!pq.empty()){cout << pq.top() << ' ';pq.pop();}cout << endl;
}
什么是容器适配器?
首先,我们来了解适配器的含义
适配器是一种接口转换器,生活中常见的有电源适配器,它可以将 220V 的交流电转换成适合电器使用的低压直流电。让原本不适用的电变得适用,这便是适配器的作用。
在计算机编程中,容器适配器则是将一个类的接口适配成用户所期待的。
stack
,queue
,priority_queue
都属于容器适配器,它们都是对其他容器的接口进行了包装。stack
和 queue
底层默认使用deque
容器。注意,其内部使用的基础容器并不是固定的,用户可以在满足特定条件的多个基础容器中自由选择。
deque 容器简单介绍
vector
优点:适合尾插尾删,随机访问,cpu 高速缓存命中高
缺点:
- 不适合头部或者中部的插入删除,效率低,需要挪动数据
- 扩容有一定的性能消耗,还可能存在一定程度的空间浪费
list
优点:
- 任意位置插入删除效率高 O(1)O(1)O(1)
- 按需申请释放空间
缺点:
- 不支持随机访问
- cpu高速缓存命中低
deque 就是 double-ended queue(双端队列),它结合了 vector 和 list 的设计。
基本原理就是由一个中控数组,也就是指针数组,维护多个缓冲区,缓冲区中存放真实数据。
缓冲数组满了,就会再开一个,中控数组里也就增加一个指针。
中控数组满了,则需要扩容,但是扩容的代价很小。
优点:
- 头部和尾部的插入删除数据效率不错
- 支持随机访问
- 扩容代价小
- cpu高速缓存命中高
缺点:
- 中部插入删除效率不行
- 虽然支持随机访问,但是效率相比 vector 还是有差距,频繁随机访问要小心
比较 vector 排序和 deque 排序:
void testOP()
{srand(time(0));const int N = 10000000;vector<int> v;v.reserve(N);deque<int> dq1;deque<int> dq2;for (int i = 0; i < N; ++i){auto e = rand();v.push_back(e);dq1.push_back(e);dq2.push_back(e);}int begin1 = clock();sort(v.begin(), v.end());int end1 = clock();int begin2 = clock();vector<int> cp(dq1.begin(), dq1.end());sort(cp.begin(), cp.end());dq1.assign(cp.begin(), cp.end());int end2 = clock();int begin3 = clock();sort(dq2.begin(), dq2.end());int end3 = clock();cout << "vector sort: " << end1 - begin1 << endl;cout << "deque copy vector sort: " << end2 - begin2 << endl;cout << "deque sort: " << end3 - begin3 << endl;
}
//结果:
//vector sort: 482
//deque copy vector sort: 540
//deque sort: 1343
可见 deque 的随机访问速度慢一些。把 deque 拷贝到 vector 排序再拷贝回来会快一些。
像 stack 和 queue 这样频繁头尾插入删除,随机访问少的数据结构就非常适合使用 deque 作为基础容器。
模拟实现
stack
模板参数 class Container = deque<T>
表示要使用的基础容器,默认为 deque
容器。
在基础容器上包装一层接口就行了。
template<class T, class Container = deque<T>>
class Stack
{public:void push(const T& x){_con.push_back(x);}void pop(){_con.pop_back();}const T& top(){return _con.back();}size_t size(){return _con.size();}bool empty(){return _con.empty();}private:Container _con;
};
我们在创建对象时可以自己传入基础容器的类型,比如 Stack<int, vector<int>> s;
,也可以不传,默认就是 deque
容器
stack支持使用的基础容器有:deque
(默认) vector
list
queue
template<class T, class Container = deque<T>>
class Queue
{public:void push(const T& x){_con.push_back(x);}void pop(){_con.pop_front();}const T& front(){return _con.front();}const T& back(){return _con.back();}size_t size(){return _con.size();}bool empty(){return _con.empty();}private:Container _con;
};
queue 支持使用的基础容器有:deque
(默认) list
priority_queue
堆的操作这里就不细讲了,详细讲解参考
[C++](13)stack queue priority_queue 模拟实现:容器适配器,deque介绍,仿函数详解相关推荐
- 模拟stack/queue/priority_queue
stack要点 1.stack遵从先进后出的规则,即先进栈的元素后出栈,入栈/出栈只能在栈的一端进行 2.stack是作为容器适配器被实现的,容器适配器是对特定类进行封装,作为其底层的容器 3.sta ...
- element布局容器大小_element中el-container容器与div布局区分详解
用于布局的容器组件,方便快速搭建页面的基本结构: el-container:外层容器.当子元素中包含 或 时,全部子元素会垂直上下排列,否则会水平左右排列. el-header:顶栏容器. el-as ...
- 阿里云容器服务飞天敏捷版详解
阿里云容器服务飞天敏捷版详解 libinjingshan 2017-04-24 23953浏览量 简介: 阿里云容器服务提供了公共云.专有云以及飞天敏捷版三种部署形态,全方位地满足企业客户利用CaaS ...
- stl的set,multiset, map, multimap, deque, list, stack, queue, priority_queue
set实际上是平衡二叉树,需要声明头文件#include<set> Insert:将元素插入集合中 使用前向迭代器对集合中序遍历 使用反向迭代器reverse_iterator可以反向遍历 ...
- Servlet生命周期与Web容器架构及处理请求详解
一.Servlet对象 Servlet对象运行在Servlet容器中,Servlet的生命周期由容器管理(Servlet容器的基本思想是在服务器端使用Java来动态生成网页). (一)Servlet对 ...
- OpenStack之Magnum容器编服务排引擎详解
Magnum项目是OpenStack中的容器编排服务引擎,向上提供统一API,向下异构兼容K8S,Mesos,Swarm等容器管理平台,是OpenStack与容器结合的官方正式项目. 当说到基于 Op ...
- 北航数据结构与c语言2017答案,2022年北京航空航天大学991数据结构与C语言程序设计考研资料汇总:参考书目-历年考研真题-模拟题库-笔记和课后习题详解...
北京航空航天大学软件学院官网网址: 991数据结构与C语言程序设计考研参考书目: 谭浩强<C程序设计>(第4版)笔记和课后习题详解 谭浩强<C程序设计>(第4版)精讲班[教材精 ...
- C++ Stack Queue priority_queue
栈stack:stack 后入先出(LIFO) q.top() 获取栈顶元素(并不删除) q.pop() 删除栈顶元素 q.push(x) 向栈中加入元素 q.empty() 判断栈是否为空 队列qu ...
- DockerKubernetes ❀ Docker镜像与容器相关操作基础命令详解
文章目录 1.Docker信息查询 1.1 版本信息 1.2 详细信息 1.3 帮助命令 2.镜像命令 2.1 本地镜像查看 2.2 镜像搜索 2.3 镜像拉取 2.4 镜像删除 3.容器命令 3.1 ...
最新文章
- FPGA之道(65)代码中的约束信息(二)乘法器的相关约束
- 【HDU 1542】Atlantis 矩形面积并(线段树,扫描法)
- linux磁盘阵列oravote,Oracle在Linux下集群RAC的安装与启停
- jQuery ajax使用方法
- c#使用HttpClient调用WebApi
- 小强系列之大话移动测试
- php如何检查对象的类型,如何在PHP中检查对象的特定类型
- cudaMemset的调用方式
- JMETER 分布式踩过的坑及填坑方法
- 路由器连接宽带(成功上网步骤方法)
- java 最佳主键_最佳Java 8书籍
- 特定条件下的技术团队绩效考核
- 项目周报模板(工作周报模板)
- win7如何添加终端服务器,Win7怎么添加windows超级终端?
- 修改服务器电脑mac地址,修改服务器电脑mac地址
- 同步Buck芯片的自举电容原理解析
- 2022-2022阿里巴巴Android面试真题解析,阿里+头条+抖音+百度+蚂蚁+京东面经
- 超级详细:Docker Commands —— Container Commands !(新手必看必会)
- 摄影构图学83年绝版_让模特露肩、露腿的摄影师们,我求求你别再祸害“古风摄影”了!...
- 阿里小程序亮相2019上海云峰会:大生态促成许多“小而美”
热门文章
- 2020-08-11
- python对excel的帮助大吗_python吊打Excel?其实是你没玩转
- 2021-04-10 Nginx配置移动端和电脑端自动双向跳转
- python docx 加粗的边框_使用python-docx在表格中指定边框外观
- 1.5 单结晶体管和晶闸管
- 微信会议邀请函怎么制作?
- 金山文字 职称计算机,计算机职称考试软件金山文字2005 播谷鸟计算机职称考试软件金山文字2005 v5.1...
- python学习实验报告(第四周)
- 单波段遥感图像薄云去除与云检测
- 第一人称射击游戏中实现摄像机跟随