iis服务器助手广告广告
返回顶部
首页 > 资讯 > 后端开发 > 其他教程 >C++ STL中容器适配器怎么实现
  • 902
分享到

C++ STL中容器适配器怎么实现

2023-06-14 18:06:32 902人浏览 泡泡鱼
摘要

这篇文章给大家分享的是有关c++ STL中容器适配器怎么实现的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。1 stack1.1 stack 介绍 stack是一种容器适配器,专门用在具有后进先出操作的上

这篇文章给大家分享的是有关c++ STL中容器适配器怎么实现的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。

1 stack

1.1 stack 介绍

  •  stack是一种容器适配器,专门用在具有后进先出操作的上下文环境中,其删除只能从容器的一端进行元素的插入与提取操作。

  • stack是作为容器适配器被实现的,容器适配器即是对特定类封装作为其底层的容器,并提供一组特定的成员函数来访问其元素,将特定类作为其底层的,元素特定容器的尾部(即栈顶)被压入和弹出。

  • stack的底层容器可以是任何标准的容器类模板或者一些其他特定的容器类,这些容器类应该支持以下操作:empty:判空操作、back:获取尾部元素操作、push_back:尾部插入元素操作、pop_back:尾部删除元素操作

  • 标准容器vector、deque、list均符合这些需求,默认情况下,如果没有为stack指定特定的底层容器,默认情况下使用deque。

C++ STL中容器适配器怎么实现

1.2 stack 使用

接口说明

C++ STL中容器适配器怎么实现

1.3 stack 模拟实现

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

1.4 deque 的简单介绍

原理

deque(双端队列):是一种双开口的"连续"空间的数据结构,注意和 queue 没有关系双开口的含义是:可以在头尾两端进行插入和删除操作,且时间复杂度为O(1),与vector比较,头插效率高,不需要搬移元素;与list比较,空间利用率比较高。
2、deque并不是真正连续的空间,而是由一段段连续的小空间拼接而成的,实际deque类似于一个动态的二维数组

C++ STL中容器适配器怎么实现

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

C++ STL中容器适配器怎么实现

缺陷

与vector比较,deque的优势是:头部插入和删除时,不需要搬移元素,效率特别高,而且在扩容时,也不需要搬移大量的元素,因此其效率是比 vector 高的。

与list比较,其底层是连续空间,空间利用率比较高,不需要存储额外字段。

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

为何作为stack 和 queue的 默认 实现

stack是一种后进先出的特殊线性数据结构,因此只要具有push_back()pop_back()操作的线性结构,都可以作为stack的底层容器,比如vector和list都可以;queue是先进先出的特殊线性数据结构,只要具有push_backpop_front操作的线性结构,都可以作为queue的底层容器,比如list。

但是STL中对stack和queue默认选择deque作为其底层容器,主要是因为:

stack 和 queue 不需要遍历(因此stack 和 queue没有迭代器),只需要在固定的一段或者两端进行操作。

在 stack 中元素增长时,deque 比 vector 的效率高(扩容时候不需要搬移大量数据);queue 中的元素增长时,deque 不仅效率高,而且内存使用率也高。

所以结合了deque的优点,完美递避开了其缺陷

2 queue

2.1 queue 介绍

  •  队列是一种容器适配器,专门用于在FIFO上下文(先进先出)中操作,其中从容器一端插入元素,另一端提取元素。

  • 队列作为容器适配器实现,容器适配器即将特定容器类封装作为其底层容器类,queue提供一组特定的成员函数来访问其元素。元素从队尾入队列,从队头出队列。

  • 底层容器可以是标准容器类模板之一,也可以是其他专门设计的容器类。该底层容器应至少支持以下操作: empty:检测队列是否为空、size:返回队列中有效元素的个数、front:返回队头元素的引用、back:返回队尾元素的引用、push_back:在队列尾部入队列、pop_front:在队列头部出队列

  • 标准容器类deque和list满足了这些要求。默认情况下,如果没有为queue实例化指定容器类,则使用标准容器deque。

2.2 queue 使用

接口介绍

C++ STL中容器适配器怎么实现

2.3 queue 模拟实现

因为queue的接口中存在头删和尾插,因此使用vector来封装效率太低,故可以借助list 和 deque 来模拟实现queue

namespace czh{// 设计模式 -- 适配器模式(配接器)template<class T, class Container = deque<T>>class queue{public:void push(const T& x){_con.push_back(x);}void pop(){_con.pop_front();}        T& front(){return _con.front();}const T& front() const{return _con.front();}T& back(){return _con.back();}const T& back() const{return _con.back();}size_t size() const{return _con.size();}bool empty() const{return _con.empty();}private:Container _con;};}

3 priority_queue

3.1 priority_queue 介绍

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

3.2 priority_queue 使用

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

#include <iOStream>#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; for (auto& e : v) q1.push(e); cout << q1.top() << endl; // 如果要创建小堆,将第三个模板参数换成greater比较方式 priority_queue<int, vector<int>, greater<int>> q2(v.begin(), v.end()); cout << q2.top() << endl;   }

3.3 仿函数的引入

仿函数准确来说是一个类,这个类重载了operator(),这个类的对象调用 operator(),可以像函数一样去使用,在优先级队列中的使用可以控制创建的优先级队列中是大堆还是小堆使其可以像水龙头的开关一样可以去控制热水还是凉水。在 STL库中中的两个仿函数的实现如下:

STL 中的优先级队列

C++ STL中容器适配器怎么实现

C++ STL中容器适配器怎么实现

C++ STL中容器适配器怎么实现

举例说明仿函数的应用

比如我们想买个手机,在京东上搜索手机,可以按照价格、销量等标签排序,那么我们可以利用仿函数简单实现,写一个商品类代表手机我们用排序算法 sort 对其排序,但是我们不可以在类的内部重载 > < 运算符,因为我们并不知道如何排序,按照什么标准排序,为了更好说明问题,来盘代码。

C++ STL中容器适配器怎么实现

#include <iostream>#include "priority_queue.h"#include <alGorithm>#include <vector>using namespace std;//仿函数的应用struct Phone{int saleNum;int price;//.....};struct LessPhonePrice{bool operator()(const Phone& p1, const Phone& p2){return p1.price < p2.price;}};struct LessPhoneSaleNum{bool operator()(const Phone& p1, const Phone& p2){return p1.saleNum < p2.saleNum;}};void TestSort(){vector <Phone> gv = { { 1, 3 }, { 5, 2 }, { 2, 10 } };sort(gv.begin(), gv.end(),LessPhoneSaleNum());//匿名对象会在STL中调用我自己写的比较方法sort(gv.begin(), gv.end(), LessPhonePrice());}int main(){TestSort();return 0;}

C++ STL中容器适配器怎么实现

C++ STL中容器适配器怎么实现

3.4 priority_queue 模拟实现

因为优先级队列的底层结构就是堆所以对 vector 进行适当封装就可以了,如果不知道堆的知识请参考我的另外一篇文章 https://www.yisu.com/article/210171.htm

#pragma once//仿函数template<class T>class Less{public:bool operator()(const T& t1, const T& t2) const{return t1 < t2;}};template<class T>class Greater{public:bool operator()(const T& t1, const T& t2) const{return t1 > t2;}};namespace czh{template<class T, class Container = vector<T>, class Compare = Greater<T>>class priority_queue {public:priority_queue() = default;template<class InputIterator>priority_queue(InputIterator first, InputIterator last):_con(first, last){//利用向下调整算法,从下到上建堆利用向上调整算法,从上到下调整for (size_t i = 1; i < _con.size(); i++){AdjustUp(i);}}void push(const T& data){_con.push_back(data);// 向上调整AdjustUp(_con.size() - 1);}void pop(){if (empty()) return;swap(_con.front(),_con.back());_con.pop_back();AdjustDown(0);}size_t size() const{return _con.size();}const T& top() const{ return _con.front();}bool empty() const{return _con.empty();}private://向上调整算法void AdjustUp(int child){Compare com;int parent = (child - 1) >> 1;while (child > 0){if (com(_con[child], _con[parent])){swap(_con[child], _con[parent]);child = parent;parent = (child - 1) >> 1;}else{break;}}}void AdjustDown(int parent){Compare com;size_t child = 2 * parent + 1;while (child < _con.size()){if (child + 1 < _con.size() && com(_con[child + 1], _con[child])){child++;}if (com(_con[child], _con[parent])){swap(_con[child], _con[parent]);parent = child;child = 2 * parent + 1;}else{break;}}}//向下调整算法Container _con;};}

4 容器适配器模式

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

C++ STL中容器适配器怎么实现

C++ STL中容器适配器怎么实现

C++ STL中容器适配器怎么实现

感谢各位的阅读!关于“C++ STL中容器适配器怎么实现”这篇文章就分享到这里了,希望以上内容可以对大家有一定的帮助,让大家可以学到更多知识,如果觉得文章不错,可以把它分享出去让更多的人看到吧!

--结束END--

本文标题: C++ STL中容器适配器怎么实现

本文链接: https://www.lsjlt.com/news/274080.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • C++ STL中容器适配器怎么实现
    这篇文章给大家分享的是有关C++ STL中容器适配器怎么实现的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。1 stack1.1 stack 介绍 stack是一种容器适配器,专门用在具有后进先出操作的上...
    99+
    2023-06-14
  • C++ STL中的容器适配器实现
    1 stack 1.1 stack 介绍  stack是一种容器适配器,专门用在具有后进先出操作的上下文环境中,其删除只能从容器的一端进行元素的插入与提取操作。 ...
    99+
    2022-11-12
  • C++ STL容器适配器使用指南
    目录适配器stack容器适配器✒️stack的介绍✏️stack的使用✏️stack的模拟实现queue✒️queue的介绍✏️queue的使用✏️queue的模拟实现deque容器...
    99+
    2022-11-12
  • 怎么用C++模拟实现STL容器
    这篇文章主要介绍了怎么用C++模拟实现STL容器的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇怎么用C++模拟实现STL容器文章都会有所收获,下面我们一起来看看吧。一、list的介绍列表是一种顺序容器,它允许在...
    99+
    2023-07-04
  • C++如何实现STL容器
    这篇文章给大家分享的是有关C++如何实现STL容器的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。各大容器的特点:可以用下标访问的容器有(既可以插入也可以赋值):vector、deque、map;特别要注意一下,v...
    99+
    2023-06-29
  • C++实现STL容器的示例
    各大容器的特点: 1.可以用下标访问的容器有(既可以插入也可以赋值):vector、deque、map; 特别要注意一下,vector和deque如果没有预先指定大小,是不能用下标法...
    99+
    2022-11-13
  • C++STL容器中string类怎么用
    这篇文章将为大家详细讲解有关C++STL容器中string类怎么用,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。前言为什么学习string类:在C语言中,字符串是以'\0'结尾的集合,为了...
    99+
    2023-06-29
  • C++ 容器适配器priority_queue怎么用
    这篇文章给大家分享的是有关C++ 容器适配器priority_queue怎么用的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。优先级队列(Priority Queue)队列是一种特征为FIFO的数据结构,每次从队列...
    99+
    2023-06-14
  • 利用C++模拟实现STL容器:list
    目录一、list的介绍二、list的排序三、迭代器1、list的迭代器失效问题2、迭代器的功能分类3、list迭代器的模拟实现4、迭代器价值5、迭代器operator->的重载...
    99+
    2022-12-08
    C++实现STL容器list C++ STL容器list C++ STL容器
  • C++怎么使用STL迭代器和容器
    这篇“C++怎么使用STL迭代器和容器”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“C++怎么使用STL迭代器和容器”文章吧...
    99+
    2023-07-02
  • C++ 容器适配器priority_queue的使用及实现代码
    优先级队列(Priority Queue) 队列是一种特征为FIFO的数据结构,每次从队列中取出的是最早加入队列中的元素。但是,许多应用需要另一种队列,每次从队列中取出的应是具有最...
    99+
    2022-11-12
  • C++ STL容器详解之红黑树部分模拟实现
    目录一、红黑树的概念二、红黑树的性质三、红黑树节点的定义四、红黑树结构 五、 红黑树的插入操作六、代码总结一、红黑树的概念 红黑树(Red Black Tree),是在计算机科学中用...
    99+
    2022-11-12
  • 怎么解析C++ 的STL迭代器原理和实现
    怎么解析C++ 的STL迭代器原理和实现,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。1. 迭代器简介为了提高C++编程的效率,STL(Standar...
    99+
    2023-06-26
  • C++ STL容器中红黑树部分模拟实现的示例分析
    这篇文章主要介绍了C++ STL容器中红黑树部分模拟实现的示例分析,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。一、红黑树的概念红黑树(Red Black Tree...
    99+
    2023-06-21
  • Java中怎么实现适配器模式
    本篇文章为大家展示了Java中怎么实现适配器模式,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。类适配模式在地球时代,所有坐骑都是只能跑,不能飞的,而现在很多坐骑在地球都可以飞了。假设,地球时代的坐骑...
    99+
    2023-06-17
  • C++容器适配与栈的实现及dequeque和优先级详解
    目录容器适配器栈的实现queque实现dequequedequeque的缺陷优先级队列习题优先级队列模拟实现仿函数容器适配器 我们可以看出,栈中没有空间配置器(内存池),而是适配器...
    99+
    2022-11-13
    C++容器适配 C++dequeque C++优先级
  • java适配器模式怎么实现
    适配器模式是一种结构型设计模式,用于将一个类的接口转换为另一个接口,以便兼容不同的类或系统。在Java中,适配器模式可以通过以下步骤...
    99+
    2023-10-23
    java
  • 深入探究C++中的容器适配器与仿函数技术
    目录一、容器适配器二、仿函数一、容器适配器 容器适配器其实是一种设计模式。转换出我们想要的东西。 比方说我们实现栈的时候既可以用数组,也可以用链表,此时我们就可以用到容器适配器了。 ...
    99+
    2023-05-17
    C++容器适配器 C++仿函数
  • Android应用中怎么实现一个FragmentPagerAdapter适配器
    这期内容当中小编将会给大家带来有关Android应用中怎么实现一个FragmentPagerAdapter适配器,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。1适配器FragmentPagerAdapte...
    99+
    2023-05-31
    android fragmentpageradapter age
  • C++中list容器的实现
    目录一、list容器1.1 简介1.2 构造函数1.3 赋值和交换1.4 大小操作1.5 插入和删除1.6 数据存取1.7 反转和排序一、list容器 1.1 简介 ① 功能:将数据...
    99+
    2023-05-13
    C++ list容器
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作