返回顶部
首页 > 资讯 > 后端开发 > 其他教程 >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://lsjlt.com/news/274080.html(转载时请注明来源链接)

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

猜你喜欢
  • C++ STL中容器适配器怎么实现
    这篇文章给大家分享的是有关C++ STL中容器适配器怎么实现的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。1 stack1.1 stack 介绍 stack是一种容器适配器,专门用在具有后进先出操作的上...
    99+
    2023-06-14
  • C++ STL中的容器适配器实现
    1 stack 1.1 stack 介绍  stack是一种容器适配器,专门用在具有后进先出操作的上下文环境中,其删除只能从容器的一端进行元素的插入与提取操作。 ...
    99+
    2024-04-02
  • C++ STL容器适配器使用指南
    目录适配器stack容器适配器✒️stack的介绍✏️stack的使用✏️stack的模拟实现queue✒️queue的介绍✏️queue的使用✏️queue的模拟实现deque容器...
    99+
    2024-04-02
  • 怎么用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+
    2024-04-02
  • 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容器干什么用的
    stl 容器在 c++ 中的作用是存储和管理各种类型的数据,从而提供数据组织、内存管理、通用性、效率和可扩展性等优势。 STL 容器在 C++ 中的作用 STL(标准模板库)容器是包含...
    99+
    2024-05-06
    c++ 标准库
  • C++怎么使用STL迭代器和容器
    这篇“C++怎么使用STL迭代器和容器”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“C++怎么使用STL迭代器和容器”文章吧...
    99+
    2023-07-02
  • C++STL中vector容器的使用
    目录一、vector(1)区分size()和capacity()(2)迭代器失效(3)区分const_iterator和const iterator(4)区分reserve()和re...
    99+
    2024-04-02
  • C++ 容器适配器priority_queue的使用及实现代码
    优先级队列(Priority Queue) 队列是一种特征为FIFO的数据结构,每次从队列中取出的是最早加入队列中的元素。但是,许多应用需要另一种队列,每次从队列中取出的应是具有最...
    99+
    2024-04-02
  • Java中怎么实现适配器模式
    本篇文章为大家展示了Java中怎么实现适配器模式,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。类适配模式在地球时代,所有坐骑都是只能跑,不能飞的,而现在很多坐骑在地球都可以飞了。假设,地球时代的坐骑...
    99+
    2023-06-17
  • C++ STL 序列式容器与配接器的简单使用
    目录容器概述序列式容器 array vector list deque forward_list Adapter(配接器) stack queue priority_queue 容器...
    99+
    2024-04-02
  • 如何在C++中使用 STL 顺序容器
    今天就跟大家聊聊有关如何在C++中使用 STL 顺序容器,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。C++ 标准模板库 STL 顺序容器容器数据结构顺序性重复性支持迭代器vecto...
    99+
    2023-06-15
  • C++ STL容器详解之红黑树部分模拟实现
    目录一、红黑树的概念二、红黑树的性质三、红黑树节点的定义四、红黑树结构 五、 红黑树的插入操作六、代码总结一、红黑树的概念 红黑树(Red Black Tree),是在计算机科学中用...
    99+
    2024-04-02
  • C++ STL容器中红黑树部分模拟实现的示例分析
    这篇文章主要介绍了C++ STL容器中红黑树部分模拟实现的示例分析,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。一、红黑树的概念红黑树(Red Black Tree...
    99+
    2023-06-21
  • C++ STL反向迭代器的实现
    反向迭代器其实就行对正向迭代器进行封装,源生迭代器,为了实现运算符的结果不同,正向迭代器也对源生迭代器进行了封装。 反向迭代器的适配器,就是 Iterator是哪个容器的迭代器,re...
    99+
    2024-04-02
  • C++容器适配器的概念与示例
    目录一. 什么是适配器与容器适配器二. 理解容器适配器stack的模拟实现queue的模拟实现一. 什么是适配器与容器适配器 适配器是一种设计模式(设计模式是一套被反复使用的,多数人...
    99+
    2023-01-14
    C++容器适配器 C++适配器
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作