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 ...
随机推荐
- 李洪强iOS开发之Foundation框架—结构体
Foundation框架—结构体 一.基本知识 Foundation—基础框架.框架中包含了很多开发中常用的数据类型,如结构体,枚举,类等,是其他ios框架的基础. 如果要想使用foundation框 ...
- lintcode :implement queue by two stacks 用栈实现队列
题目 用栈实现队列 正如标题所述,你需要使用两个栈来实现队列的一些操作. 队列应支持push(element),pop() 和 top(),其中pop是弹出队列中的第一个(最前面的)元素. pop和t ...
- lintcode :旋转字符串
题目: 旋转字符串 给定一个字符串和一个偏移量,根据偏移量旋转字符串(从左向右旋转) 样例 对于字符串 "abcdefg". offset=0 => "abcdef ...
- java:对象的转型
面向对象编程有三个特征,即封装.继承和多态,学习多态必须了解向上转型和向下转型. 一.向上转型:将子类对象赋值给父类的引用 动物 a=new 狗()://这就为向上转型 向上转型都会成功,是安全的. ...
- Tomcat启动后访问首页报错 显示JSP 空指针异常
HTTP Status 500 - type Exception report message description The server encountered an internal error ...
- CentOS7 升级python同时解决yum损坏问题
CentOS7中的python版本为python2.7.5,升级到最新版的python时需要注意两个问题 新版的python安装好后要修改python的系统默认指向问题 升级到最新版python后yu ...
- SPOJ 1108 Card Trick 暴力模拟
解释一下样例,因为我觉得这个题意表述的不是很清楚.以第二组样例为例. 牌序为:3 1 4 5 2 第一轮:把 3 放到末尾:1 4 5 2 3,最顶上的牌是1,把1拿走.剩余 4 5 2 3 第二轮: ...
- Apple开发者账号申请学习方式
http://jingyan.baidu.com/article/414eccf610e7c76b431f0a94.html https://developer.apple.com/wwdc/sche ...
- System,Integer,Calendar,Random和容器
System 1)arraycopy int[] a = {1.2.3.4}; int[] b = new int[5]; System.arraycopy(a,1,b,3,2); //把数组a中从下 ...
- Java IO 遇到的错误
1.java.io.FileNotFoundException: /storage/emulated/0/xxx.txt: open failed: EISDIR (Is a directory) 该 ...