// 2016-05-13 补充Allocator(空间配置器)的介绍
// 2016-05-14 补充vector的一些零散的知识(第二部分的“补充部分”);
// 补充构造函数fill(2)的注意事项
// 补充vector内元素的比较(<, <=, >, >=, ==, !=)
1.引入
STL,即 standard tempalate library,标准模板库,是C++的重要组成部分。C++ STL(标准模板库)是一套功能强大的 C++ 模板类,提供了通用的模板类和函数,这些模板类和函数可以实现多种流行和常用的算法和数据结构,如向量、链表、队列、栈。
STL的构成:
组成部分 | 描述 |
---|---|
iterator(迭代器) | 迭代器用于遍历对象集合的元素。 |
container(容器) | 容器是用来管理某一类对象的集合。 |
Generic algorithm(泛型算法) | 算法作用于容器。它们提供了执行各种操作的方式,包括对容器内容执行初始化、排序、搜索和转换等操作。 |
容器的构成:
分类 | 举例 |
---|---|
Sequential Container(顺序容器) | vector, list, deque |
Associative Container (关联容器) | map, multimap, set, multiset |
Container Adapter (容器适配器) | stack, queue |
2.vector类介绍
According to cplusplus.com,
Vectors are sequence containers representing arrays that can change in size.
Just like arrays, vectors use contiguous storage locations for their elements, which means that their elements can also be accessed using offsets on regular pointers to its elements, and just as efficiently as in arrays.* But unlike arrays, their size can change dynamically, with their storage being handled automatically by the container*.
Internally, vectors use a dynamically allocated array to store their elements. This array may need to be reallocated in order to grow in size when new elements are inserted, which implies allocating a new array and moving all elements to it. This is a relatively expensive task in terms of processing time, and thus, vectors do not reallocate each time an element is added to the container.
Instead, vector containers may allocate some extra storage to accommodate for possible growth, and thus the container may have an actual capacity greater than the storage strictly needed to contain its elements (i.e., its size). Libraries can implement different strategies for growth to balance between memory usage and reallocations, but in any case, reallocations should only happen at logarithmically growing intervals of size so that the insertion of individual elements at the end of the vector can be provided with amortised constant time complexity (see push_back).
Therefore, compared to arrays, vectors consume more memory in exchange for the ability to manage storage and grow dynamically in an efficient way.
Compared to the other dynamic sequence containers (deques, lists and forward_lists), vectors are very efficient accessing its elements (just like arrays) and relatively efficient adding or removing elements from its end. For operations that involve inserting or removing elements at positions other than the end, they perform worse than the others, and have less consistent iterators and references than lists and forward_lists.
分析:
(1)vector是array的升级版
vector是一个sequence容器,是array的升级版,主要因为vector能高效地对内存进行管理以及动态增长。但是,vector其实就是将array和方法封装形成的一个类。
(2)vector容器的内存管理
vector的容器大小可以动态增长,但是并不意味着每一次插入操作都进行reallocate。内存的分配与释放耗费的资源是比较大的,因此应当减少它的次数。与此同时,这也就意味着容器的容量(capacity)与容器目前容纳的大小(size)是不等的,前者应大于后者。
补充:上文也说了,对于vector内存的增长有很多strategies,例如第一次增长我增加2个内存单位,第二次增长我增加4个内存单位,第三次,第四次,… 第n次我增长2^n(前提是vector内存不够时再分配),这样也就大大减少了reallocate的次数。
(3)vector容器的意义
然后,vector虽然相对于array消耗了更多的内存,但是却实现了对内存的高效管理和增长,这种消耗是值得的。
(4)vector容器与其他容器的比较
与其他的sequence容器比较(如list,dequeue), vector访问元素的效率较高,但是对于增加与删除操作就不如其他两个容器了。
补充:
(5)vector的容纳对象
vector能容纳绝大多数类型的对象作为它的元素,但是因为引用不是对象,所以不存在包含引用的vector,即引用不能作为vector的对象。并且,vectot容纳的对象也可以是vector,但是有一点要注意,便是在这种情况下vector容器定义的格式:
// 早期c++标准
vector<vector<int> > // 倒数两个尖括号之间要加空格
// c++11
vector<vector<int>> // 倒数两个尖括号之间无需加空格
时间复杂度:
container | access | insert or erase |
---|---|---|
vector | O(1) | O(n^2) |
list | O(n) | O(n) |
dequeue | O(n) | O(n) |
虽然list和deque时间复杂度相同,但是因为空间复杂度不同,二者效率也是不同的。
到这里,在对vector容器有一定了解之后,我们开始接触vector容器的各种操作。
3.vector类常用操作
注:列操作清单,详解在后文。
操作 | 作用 |
---|---|
(constructor) | Construct vector |
(destructor) | Vector destructor |
operator= | Assign content |
begin | Return iterator to beginning |
end | Return iterator to end |
rbegin | Return reverse iterator to reverse beginning |
rend | Return reverse iterator to reverse end |
cbegin (c++11) | Return const_iterator to beginning |
cend (c++11) | Return const_iterator to end |
crbegin (c++11) | Return const_reverse_iterator to reverse beginning |
crend (c++11) | Return const_reverse_iterator to reverse end |
size | Return size |