C++中的容器大致可以分为两个大类:顺序容器和关联容器。顺序容器中有包含有顺序容器适配器。
顺序容器:将单一类型元素聚集起来成为容器,然后根据位置来存储和访问这些元素。主要有vector、list、deque(双端队列)。顺序容器适配器:stack、queue和priority_queue。
关联容器:支持通过键来高效地查找和读取元素。主要有:pair、set、map、multiset和multimap。
接下来依次对于各种容器做详细的介绍。
一、顺序容器
1、顺序容器定义
为了定义一个容器类型的对象,必须先包含相关的头文件:
定义vector:#include <vector>
定义list:#include <list>
定义deque:#include <deque>
定义示例
|
1 2 3 |
|
2、顺序容器初始化

初始化示例:
|
1 2 3 4 5 6 7 8 9 10 |
|
3、顺序容器支持的指针运算
①所有顺序都支持的指针运行

②vector 和 deque 容器的迭代器提供额外的运算

③迭代器失效:一些容器操作会修改容器的内在状态或移动容器内的元素。这样的操作使所有指向被移动的元素的迭代器失效,也可能同时使其他迭代器失效。使用无效迭代器是没有定义的,可能会导致与悬垂指针相同的问题。
④begin和end成员:begin和end操作产生指向容器内第一个元素和最后一个元素的下一位置的迭代器。

3、顺序容器操作
①添加元素

添加元素示例:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
|
②容器大小的操作

示例:
|
1 2 3 4 |
|
③访问元素

|
1 2 3 4 5 6 |
|
④删除元素

示例:
|
1 2 3 4 5 6 7 8 9 10 |
|
⑤赋值与swap

|
1 2 3 4 |
|
swap示例:
vector<string> vs1(3); // vs1有3个元素
vector<string> vs(5); // vs2有5个元素
vs1.swap(vs2);//执行后,vs1中5个元素,而vs2则存3个元素。
⑥vector的自增长:capacity 和 reserve 成员
为了提高vector的效率,不用每次添加元素都重新分配空间。vector会在分配空间时候预分配大于需要的空间。vector 类提供了两个成员函数:capacity 和reserve 使程序员可与 vector 容器内存分配的实现部分交互工作。
capacity操作:获取在容器需要分配更多的存储空间之前能够存储的元素总数
reserve操作:告诉vector容器应该预留多少个元素的存储空间
capacity(容量)与size(长度)的区别:size指容器当前拥有的元素个数,而capacity则指容器在必须分配新存储空间之前可以存储的元素总数。capacity是比size大的一般情况下。
示例:
|
1 2 3 4 5 6 |
|
可以通过函数reserve()来操作预留空间
//在之前一段代码的基础上
ivec.reserve(ivec.capacity()+50);//为ivec增加了50的预留空间
另外:如果不手动操作来预留空间,每当 vector 容器不得不分配新的存储空间时,以加倍当前容量的分配策略实现重新分配。
4、容器的选用
选择容器类型的常规法则:
①如果程序要求随机访问元素,则应使用 vector 或 deque 容器。
②如果程序必须在容器的中间位置插入或删除元素,则应采用 list 容器。
③如果程序不是在容器的中间位置,而是在容器首部或尾部插入或删除元素,则应采用 deque 容器。
④如果只需在读取输入时在容器的中间位置插入元素,然后需要随机访问元素,则可考虑在输入时将元素读入到一个 list 容器,接着对此容器重新排序,使其适合顺序访问,然后将排序后的 list 容器复制到一个 vector容器。
如果程序既需要随机访问又必须在容器的中间位置插入或删除元素,选择何种容器取决于下面两种操作付出的相对代价:随机访问 list 容器元素的代价,以及在 vector 或 deque 容器中插入/删除元素时复制元素的代价。通常来说,应用中占优势的操作(程序中更多使用的是访问操作还是插入/删除操作)将决定应该什么类型的容器。
5、容器适配器
①适配器通用的操作和类型

②适配器的初始化
所有适配器都定义了两个构造函数:默认构造函数用于创建空对象,而带一个容器参数的构造函数将参数容器的副本作为其基础值。
默认的stack和queue都基于deque容器实现,而priority_queue则在vector容器上实现。

2086

被折叠的 条评论
为什么被折叠?



