我的编程空间,编程开发者的网络收藏夹
学习永远不晚

C++ STL 序列式容器与配接器的简单使用

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

C++ STL 序列式容器与配接器的简单使用

容器概述

C++标准里提供了以下容器或容器配接器:

序列式容器 配接器 关联式容器 不定序关联容器
array stack set unordered_set
vector queue map unordered_map
list priority_queue multiset unordered_multiset
deque multimap unordered_multimap
forward_list

序列式容器

array

array是静态连续空间,一经配置,大小不可改变。

就是数组,除了空间的灵活性不足,其他与vector很像。用的也比较少,一般都用vector了,这里就不多说了。

vector

vector的数据安排与操作方式,与array很相似。二者唯一的差别在于空间的运用的灵活性。

  • array是静态空间,一旦配置不能改变;
  • vector是动态空间,随着元素加入,内部机制会自行扩充空间以容纳新元素。

vector维护的是连续线性空间,其指针就是普通指针。


vector<int>::iterator iter;

那么iter其实就是int*类型。

两个迭代器start和finish之间是连续空间中目前已被使用的空间,end_of_storage指向整块连续空间的尾端。

为了降低频繁空间配置带来的成本开销,vector实际配置的大小会比客户需求的更大一些,以备将来可能的扩充。这便是capacity的概念。

  • [start,finish]是size();
  • [start, end_of_storage]是capacity();
  • [finish, end_of_storage]是备用空间。

一旦size() == capacity(),便是满载。下次再有新增元素,整个vector就要另觅他所了。“另觅他所”的过程会经历“重新配置大空间,元素移动,释放原空间”这一系列动作,工程浩大。

所谓动态增加大小,并不是在原空间之后接续新空间(因为无法保证原空间之后有可供配置的空间),而是以原空间大小的两倍另外配置一块较大空间,然后将原内容拷贝过来,然后才开始在原内容后边构造新元素,并释放原空间。

因此,对vector的任何操作,一旦引起空间重新配置,指向原vector的所有迭代器就都失效了,这是一个经常犯的错误,务必小心。

list

list是环状双向链表。它的好处在于每次插入或删除一个元素,就配置或释放一个元素空间,与vector相比,list对空间运用更加精准,绝不浪费。且对于任何位置的元素插入或移除,list永远是常数时间。

vector和list适用场景与以下有关:

  • 元素多寡
  • 元素的构造复杂度(有无non-trival copy constructor, non-trival copy assignment operator)
  • 元素存取行为的特性

list的节点结构如下:


template <class T>
struct __list_node{
    typedef void* void_pointer;
    void_pointer prev;
    void_pointer next;
    T data;
};

由于list的内存空间无法保证是连续的,所以它的迭代器不再是普通指针。list的迭代器必须有能力指向list节点,并进行正确的递增、递减、取值、成员存取等操作。

list的操作大多不会使迭代器失效,即便是删除操作,也只有指向被删除元素的那个迭代器失效。

由于list是一个环状双向链表,所以它只需要一个指针,便可以完整遍历整个链表。

对于insert操作,新节点将位于哨兵迭代器(标示出插入点)所指节点的前方,这是STL对插入操作的标准规范。

deque

vector是单向开口的连续线性空间,deque则是一种双向开口的线性连续空间。所谓双向开口,即可以在首尾两端分别做元素的插入和删除操作。

deque其实是动态地以分段连续空间组合而成。但是这些分段的连续空间,在用户看来确实一整块连续空间,这其实是deque做出的假象。这种假象由deque的中控器map(注意,不是STL中的map容器)负责维持。

这个map可以理解为映射,它是一个指针,指向一小段连续内存空间,这块空间中的每个元素又都是一个指针,每个指针都指向deque的分段连续空间中的某一段。默认每一段是512字节。

forward_list

forward_list是单向链表。

前边说了,对于insert操作,新节点将位于哨兵迭代器(标示出插入点)所指节点的前方,这是STL对插入操作的标准规范。

但是forward_list作为单向链表,它没有什么方便方法回头定出前一个位置,它只能从头找起,所以除了forward_list起点处附近的区域外,在其他位置insert()或erase()就很慢,对此,forward_list特别提供了insert_after()和erase_after()。

同样出于效率考虑,它不提供push_back(),只提供push_front()。

Adapter(配接器)

stack

stack是先进后出(FILO)的数据结构。他只有一个出口,除了最顶端元素外,没有其他方法获得stack的其他元素。即stack是不允许有遍历行为的,自然也就没有迭代器了。

STL中的stack其实不算是container,而是adapter,因为其底层默认是deque,把deque的头端封闭,便形成一个stack。

具有“修改某物接口,形成另一种风貌”之性质者,谓之adapter。

除了deque,list也是双向开口的,所以list也可以做stack的底层结构。

queue

queue是先进先出(FIFO)的数据结构。它有两个出入口,但都是被限制的,尾端只进不出,头端只出不进。除了尾端进,头端出之外,没有其他方法存取queue的其他元素,即queue也是不允许遍历的,自然也就没有迭代器了。

queue也是一种adapter,它同stack一样,默认以deque作为底层结构,list同样也可以做其底层结构。

把deque的头端入口和尾端出口,就成了一个queue。

priority_queue

priority_queue是拥有权值观念的queue。

所谓拥有权值观念,可以理解为有序的,其内的元素并非按照加入的次序排列,而是按照元素的权值排列,权值最高者排在最前边。

默认状态下,priority_queue是用一个大根堆(max-heap)来完成,而大根堆是一个以vector表现得完全二叉树。

大根堆:max-heap,父节点值大于或等于子节点值的完全二叉树;
小根堆:min-heap,父节点值小于或等于子节点值的完全二叉树。

所以,priority_queue是以vector为底层结构,辅以heap处理规则来实现的,所以它也是一种adapter。

priority_queue也不允许遍历,自然也没有迭代器。

到此这篇关于C++ STL 序列式容器与配接器的简单使用的文章就介绍到这了,更多相关C++ STL 序列式容器与配接器内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

C++ STL 序列式容器与配接器的简单使用

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

下载Word文档

猜你喜欢

如何在C++中使用STL关联式容器自定义排序规则

如何在C++中使用STL关联式容器自定义排序规则?相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。1) 使用函数对象自定义排序规则#include #inclu
2023-06-06

Android适配器Adapter与ListView和RecycleView的简单使用

本文将为大家介绍Android开发中常用的适配器(Adapter)概念,以及ListView和RecycleView的简单使用方法,需要的朋友可以参考下
2023-05-19

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录