STL六大组件之——容器知识大扫盲
STL中的容器主要涉及顺序容器类型:vector、list、deque,顺序容器适配器类型:stack、queue、priority_queue。标准库中的容器分为顺序容器和关联容器。顺序容器(sequential container)内的元素按其位置存储和访问,顾名思义,这些内部元素是顺序存放的;顺序容器内的元素排列次序与元素值无关,而是由元素添加到容器里的次序决定。而关联容器的元素按键(key)排序。
容器类共享部分公共接口。标准库定义的三种顺序容器类型:vector、list、deque,它们的差别仅在访问元素的方式,以及添加或删除元素相关操作的代价。顺序容器适配器包括:stack、queue和priority_queue。容器只定义了少量操作,大多数操作由算法库提供。如果两个容器提供了相同的操作,则它们的接口(函数名和参数个数)应该相同。
|
标准容器类 |
说明 |
|
顺序性容器 |
|
|
vector |
从后面快速的插入与删除,直接访问任何元素 |
|
deque |
从前面或后面快速的插入与删除,直接访问任何元素 |
|
list |
双链表,从任何地方快速插入与删除 |
|
关联容器 |
|
|
set |
快速查找,不允许重复值 |
|
multiset |
快速查找,允许重复值 |
|
map |
一对多映射,基于关键字快速查找,不允许重复值 |
|
multimap |
一对多映射,基于关键字快速查找,允许重复值 |
容器类型:
|
vector |
容器,支持快速随机访问(连续存储) |
|
list |
链表,支持快速插入/删除 |
|
deque |
双端队列,支持随机访问(连续存储),两端能快速插入和删除 |
|
stack |
栈 |
|
queue |
队列 |
|
priority_queue |
优先级队列 |
下表为迭代器为所有容器类型所提供的运算:
|
*iter |
返回类型iter所指向的元素的引用 |
|
iter->mem |
对iter进行解引用,并取得指定成员 |
|
++iter |
给iter加1,使其指向容器中下一个元素 |
|
iter++ |
|
|
--iter |
给iter减1,使其指向容器中前一个元素 |
|
iter-- |
|
|
iter1 == iter2 |
当两个迭代器指向同一个容器中的同一元素,或者当它们都指向 |
|
iter1 != iter2 |
同一个容器的超出末端的下一个位置时,两个迭代器相等。 |
vector和deque容器的迭代器提供了额外的运算:迭代器的算术运算和另一些关系运算,如下表所示:
|
iter + n |
在迭代器上加(减)整数值,将产生指向容器中前面(后面)第n个元素的迭代器; |
|
iter - n |
新计算出来的迭代器必须指向容器中的元素或超出容器末端的下一位置。 |
|
iter1 += iter2 |
复合运算:先加(减),再赋值 |
|
iter1 -= iter2 |
|
|
iter1 - iter2 |
只适用于vector和deque |
|
>, >=, <, <= |
比较迭代器的位置关系;只适用于vector和deque |
关系操作符只适用于vector和deque容器,这是因为只有这两种容器为其元素提供快速、随机的访问。它们确保可根据元素位置直接有效地访问指定的容器元素。这两种容器都支持通过元素位置实现的随机访问,因此它们的迭代器可以有效地实现算术和关系运算。
迭代器范围:[first, last)是一个左闭合区间,表示范围从first开始,到last结束,但不包括last。注意:如果first不等于last,则对first反复做自增运算必须能够到达last;否则,即last位于first之前,则将发生未定义行为。
迭代器范围使用左闭合的意义:因为这样可以统一表示空集,就无需特别处理。
另外,使用迭代器时,要特别留意迭代器的可能的失效问题。
访问元素:
|
back() |
返回容器的最后一个元素的引用。如果容器为空,则该操作未定义 |
|
front() |
返回容器的第一个元素的引用。如果容器为空,则该操作未定义 |
|
c[n] |
返回下标为n的元素的引用;如果n<0 or n>=size(),则该操作未定义 |
|
at[n] |
返回下标为n的元素的引用;如果下标无效,则抛出异常out_of_range异常 |
删除元素 :
|
erase(p) |
删除迭代器p所指向的元素。返回一个迭代器,它指向被删除的元素后面的元素。如果p指向容器内最后一个元素,则返回的迭代器指向容器的超出末端的下一个位置;如果p本身就是指向超出末端的下一个位置的迭代器,则该函数未定义 |
|
erase(b, e) |
删除[b, e)内的所有元素。返回一个迭代器,它指向被删除元素段后面的元素。如果e本身就是指向超出末端的下一个位置的迭代器,则返回的迭代器也指向超出末端的下一个位置。 |
|
clear() |
删除容器内的所有元素,返回void |
|
pop_back() |
删除容器内的最后一个元素,返回void。如果容器为空,则该操作未定义。 |
|
pop_front() |
删除容器内的第一个元素,返回void。如果c为空容器,则该操作未定义 |
赋值与swap:
|
c1 = c2 |
删除容器c1的所有元素,然后将c2的元素复制给c1。c1和c2的类型必须相同。 |
|
c1.swap(c2) |
交换内容:调用该函数后,c1中存放的是c2原来的元素,c2中存放的是c1原来的元素。c1和c2的类型必须相同。该函数的执行速度通常要比将c2的元素复制到c1的操作快。 |
|
c.assign(b, e) |
重新设置c的元素:将迭代器b和e标记的范围内所有的元素复制到c中。b和e必须不是指向c中元素的迭代器。 |
|
c.assign(n, t) |
将容器c重新设置为存储n个值为t的元素。 |
注意:assign操作首先删除容器内所有的元素,再将参数所指定的新元素插入到容器中。
swap操作不会删除或插入任何元素,而且保证在常量时间内实现交换。由于容器内没有移动任何元素,因此迭代器不会失效。但要注意这些迭代器指向了另一个容器中的元素。
容器的选用:
vector和deque容器提供了对元素的快速访问,但付出的代价是,在容器的任意位置插入或删除元素,比在容器尾部插入和删除的开销更大,因为要保证其连续存储,需要移动元素;list类型在任何位置都能快速插入和删除,因为不需要保证连续存储,但付出的代价是元素的随机访问开销较大。特征如下:
1)与vector容器一样,在deque容器的中间insert或erase元素效率比较低;
2)不同于vector容器,deque容器提供高效地在其首部实现insert和erase的操作,就像在尾部一样;
3)与vector容器一样而不同于list容器的是,deque容器支持对所有元素的随机访问。
4)在deque容器首部或尾部删除元素则只会使指向被删除元素的迭代器失效。在deque容器的任何其他位置的插入和删除操作将使指向该容器元素的所有迭代器都失效。
容器的比较:
vector (连续的空间存储,可以使用[]操作符)快速的访问随机的元素,快速的在末尾插入元素,但是在序列中间岁间的插入,删除元素要慢,而且如果一开始分配的空间不够的话,有一个重新分配更大空间,然后拷贝的性能开销。
deque (小片的连续,小片间用链表相连,实际上内部有一个map的指针,因为知道类型,所以还是可以使用[],只是速度没有vector快)快速的访问随机的元素,快速的在开始和末尾插入元素,随机的插入,删除元素要慢,空间的重新分配要比vector快,重新分配空间后,原有的元素不需要拷贝。对deque的排序操作,可将deque先复制到vector,排序后在复制回deque。
list (每个元素间用链表相连)访问随机元素不如vector快,随机的插入元素比vector快,对每个元素分配空间,所以不存在空间不够,重新分配的情况。
set:内部元素唯一,用一棵平衡树结构来存储,因此遍历的时候就排序了,查找也比较快的哦。
map :一对一的映射的结合,key不能重复。
stack :适配器,必须结合其他的容器使用,stl中默认的内部容器是deque。先进后出,只有一个出口,不允许遍历。
queue: 是受限制的deque,内部容器一般使用list较简单。先进先出,不允许遍历。
vector<bool> 与bitset<> ,前面的可以动态改变长度。
priority_queue: 插入的元素就有优先级顺序,top出来的就是优先级最高的了
valarray 专门进行数值计算的,增加特殊的数学函数。
一些容器选用法则:
1)如果程序要求随机访问元素,则应使用vector或deque容器;
2)如果程序必须在容器的中间位置插入或删除元素,则应采用list容器;
3)如果程序不是在容器的中间位置,而是在容器首部或尾部插入或删除元素,则应采用deque容器;
4)如果只需要在读取输入时在容器的中间位置插入元素,然后需要随机访问元素,则可以在输入时将元素读入到一个list容器中,然后对容器排序,再将排序后的list容器复制到vector容器中。
5)如果程序既需要随机访问,又需要在容器的中间位置插入或删除元素,此时应当权衡哪种操作的影响较大,从而决定选择list容器还是vector或deque容器。注:此时若选择使用vector或deque容器,可以考虑只使用它们和list容器所共有的操作,比如使用迭代器而不是下标,避免随机访问元素等,这样在必要时,可以很方便地将程序改写为使用list容器。
STL六大组件之——容器知识大扫盲的更多相关文章
- STL —— STL六大组件
注:以下内容摘自 http://blog.csdn.net/byxdaz/article/details/4633826 STL六大组件 容器(Container) 算法(Algorithm) 迭代器 ...
- STL 六大组件 功能与运用
STL 提供六大组件,彼此可以组合套用: 1 容器(containers):各种数据结构,如vector,list,deque,set,map,用来存放数据,从实现的角度来看,STL容器是一种clas ...
- STL六大组件简介
一.STL简介 (一).泛型程序设计 泛型编程(generic programming) 将程序写得尽可能通用 将算法从数据结构中抽象出来,成为通用的 C++的模板为泛型程序设计奠定了关键的基础 (二 ...
- [转贴]从零开始学C++之STL(一):STL六大组件简介
一.STL简介 (一).泛型程序设计 泛型编程(generic programming) 将程序写得尽可能通用 将算法从数据结构中抽象出来,成为通用的 C++的模板为泛型程序设计奠定了关键的基础 (二 ...
- STL六大组件之——分配器(内存分配,好深奥的东西)
SGI设计了双层级配置器,第一级配置器直接使用malloc()和free(),第二级配置器则视情况采用不同的策略:当配置区块超过128bytes时,视之为“足够大”,便调用第一级配置器:当配置区小于1 ...
- STL六大组件之——算法小小小小的解析
参考自侯捷的<stl源码剖析> stl算法主要分为非可变序列算法(指不直接修改其所操作的容器内容的算法),可变序列算法(指可以修改它们所操作的容器内容的算法),排序算法(包括对序列进行排序 ...
- STL六大组件之——适配器代表大会
适配器也是一种常用的设计模式: 将一个类的接口转换为另一个类的接口,使得原本因接口不兼容而不能合作的两个类可以一起运作.STL提供三种适配器:改变容器接口的容器适配器.改变迭代器接口的迭代器适配器以及 ...
- STL六大组件之——迭代器这个东西
迭代器:除了在其它语言中司空见惯的下标法访问容器元素之外,C++语言提供了一种全新的方法——迭代器(iterator)来访问容器的元素.迭代器其实类似于引用,指向容器中某一元素.换个方式来说,容器就是 ...
- IT知识大扫盲
做了这么多软件开发,下列一些知识不一定都懂. 首先,说一些电子商务扫盲的名词: 常见的电子商务类型有:C2C.B2B.B2C.C2B.O2O等等,下面来简要说明下这几种类型. C2C(Customer ...
随机推荐
- Makefile笔记
一个简单的Makefile描述规则组成: TARGET...:PREREQUISITES... COMMANDS... ... target:规则的目标.通常是程序中间或者最后要生成的文件名,也可以是 ...
- ServletRequest中getReader()和getInputStream()只能调用一次的解决办法
转载:http://blog.sina.com.cn/s/blog_870cd7b90101fg58.html 最近使用spring mvc做项目,数据格式是json,有一个功能是实现记录请求的参数, ...
- 利用Nginx搭建http和rtmp协议的流媒体服务器
http://www.linuxidc.com/Linux/2013-02/79118.htm
- Python中itertools模块
itertools模块包含创建有效迭代器的函数,可以用各种方式对数据进行循环操作,此模块中的所有函数返回的迭代器都可以与for循环语句以及其他包含迭代器(如生成器和生成器表达式)的函数联合使用. ch ...
- React事件处理函数的bind复用和name复用
一.bind复用 <!DOCTYPE html> <html lang="zh-cn"> <head> <meta charset=&qu ...
- Hadoop HDFS文件常用操作及注意事项(更新)
1.Copy a file from the local file system to HDFS The srcFile variable needs to contain the full name ...
- excel文档
1.快速统计行数(ctrl+Shift+(方向键向下)). bson数据类型 留个影响 public enum BsonType { Double = 0x01, String = 0x02, Doc ...
- Anchor和Dock的区别
Dock的Bottom,整个控件填充下半部分,控件会被横向拉长 Anchor,仅仅是控件固定在下方,位置不会发生移动,自动锚定了此控件和父容器的底部的间隔 Anchor可以确定控件的相对位置不发生变化
- Eclipse中Python插件PyDev的安装与配置流程
安装PyDev插件的两种安装方法: 方法1.下载地址:http://sourceforge.net/projects/pydev/files/,将下载的PyDev解压(目前最新版本 PyDev 4.5 ...
- C#4.0新特性(3):变性 Variance(逆变与协变)
一句话总结:协变让一个粗粒度接口(或委托)可以接收一个更加具体的接口(或委托)作为参数(或返回值):逆变让一个接口(或委托)的参数类型(或返回值)类型更加具体化,也就是参数类型更强,更明确. 通常,协 ...