c++之顺序容器
概述
名称 | 优缺点 |
---|---|
vector | 可变大小数组。 支持快速随机访问。在尾部之外的位置插入或删除元素可能会很慢。 |
deque | 双端队列。支持快速随机访问。在头尾位置插入或删除很快 |
string | 与vector类似,但是专门用于保存字符。随机访问快,在尾部插入或删除很快 |
arrary | 固定大小数组。支持快速随机访问。不能添加和删除元素 |
list | 双向链表。只支持双向顺序访问。在list中任何位置进行插入或删除都很快 |
forward_list | 单向链表。只支持单向顺序访问。在链表任何位置进行插入或删除都很快 |
通常使用std::vector 是最好的选择,除非有很好的理由选择其他容器。
容器几乎可以存放任意类型的元素,包括容器。
迭代器iterator
迭代器的算术运算只能应用于
string vector deque 和array
容器中,不能用于forward_list
容器中。
迭代器中的begin指向容器首元素的位置, end指向容器尾元素之后的位置。end可以和begin指向相同的位置,但是不能指向begin之前的位置。
while(begin != end)
{
*begin = value;
++begin;
}
end返回的迭代器不指向某个位置,所以不能对其进行递增和解引用操作。
- 迭代器的类型
std::vector<int>::iterator it; // it能够读写std::vector<int>中的元素
std::vector<int>::const_iterator it2; //it2只能读元素,不能写元素
- begin和end
list<string> a = {"Milton", "Shakespeare", "Austen"};
auto it1 = a.begin(); // list<string>::iterator
auto it2 = a.rbegin(); // list<string>::reverse_iterator
auto it3 = a.cbegin(); // list<string>::const_iterator
auto it4 = a.crbegin();// list<string>::const_reverse_iterator
注:reverse_iterator是一个反向迭代器,各种操作的含义与iterator相反。
注:遍历容器时,当不需要修改元素时,应该使用cbegin和cend。
容器定义与初始化
vector<int> ivec(10, -1); // ten int elements, each initialized to -1
list<string> svec(10, "hi!"); // ten strings; each element is "hi!"
forward_list<int> ivec(10); // ten elements, each initialized to 0
deque<string> svec(10); // ten elements, each an empty string
- arrary固定数组
当定义一个arrary容器时,不仅要指定元素类型,还要制定容器大小。
array<int, 10> ia1; // ten default-initialized ints
array<int, 10> ia2 = {0,1,2,3,4,5,6,7,8,9}; // list initialization
array<int, 10> ia3 = {42}; // ia3[0] is 42, remaining elements are 0
顺序容器的操作
- 向顺序容器添加元素
注:forward_list有自己专门版本的insert和emplace
注:forward_list不支持push_back和emplace_back
注:vector和string不支持push_front和emplace_front
c.push_back();
c.emplace_back();
c.push_front();
c.emplace_front();
c.insert(p, t);
c.insert(p, n, t); //在迭代器p指向元素之前插入n个值为t的元素。
c.insert(p, b, e); //在迭代器be范围的元素插入到迭代器p指向元素之前。
- 访问元素
注:at和下标只适用于vector、string、deque和array
注:back不适用于forward_list
c.back()
c.front()
c[n]
c.at(n)
注:书上说下标访问不会检查越界行为,但是at访问会的。可是我写程序时下标访问也会检查越界行为的。
- 删除元素
c.pop_back()
c.pop_front()
c.erase(p)
c.erase(b, e)
c.clear()
- 改变容器的大小
注:resize不适用于arrary
c.resize(n)
c.resize(n, t) //调整容器的大小为n, 新增的元素初始化为t
向容器中添加、删除元素都会使得指向容器元素的指针、引用和迭代器失效。