内容
- list
- 区分:list是双向迭代器,vector是随机迭代器
构造
1 2 3 4 5 6 7 8 9 10 11 12
| #include<iostream> #include<vector> using namespace std; int main() { vector<int> ar1; vector<int> ar2 = { 12,23,34,45,56,67,78,89 }; vector<int> ar3(10, 23); vector<int> ar4({ 12,23,34,45,56,67 }); vector<int> ar5(ar2); vector<int> ar6(std::move(ar2)); }
|
与vector的区别
- 底层实现
- 空间利用率
- 查询元素
- vector:iterator
operator[]
,find
O(n),binary_search
O(logn)
- list:iterator
find
O(n)
- 插入和删除
- vector需要分的情况较多
- 看是否需要增容;
- 在中间插入还是在最后插入;
- 删除:最后删除O(1),中间删除需要内存拷贝;
- resize和reserve的区别
- list:
- 插入O(1),需要内存申请,
- 删除O(1),需要内存释放。
- 迭代器:
- vector:
- 随机迭代器,可检查越界。支持
++
,--
,+
,+=
,<
,>
,==
,!=
;
- 插入和删除元素可能导致迭代器失效。
- list:
- 插入元素不会导致迭代器失效,但是是插在当前迭代器指向的位置之前,插入后迭代器指向新插的位置;原位置的被挤到了右面。所以,如果需要在插入后继续遍历, 需要单独
++
1次。
- erase删除元素,被删的元素的迭代器失效。
如何抉择?
什么时候该用vector?什么时候该用list?
- 如果需要高效的随机存取,而不在乎插入和删除的效率(很少使用插入和删除操作)。选用vector。
- 如果需要大量的插入和删除的操作,随机存取很少使用。选用list。
举例
例1∶比如制作了一个游戏玩家排行榜,那么就要实时刷新这个排行榜,这个时候,如果有人达到排行的条件,那么就要把他加进去,如果人数多出了,那么就把排名靠后的移除掉,这就需要大量的插入删除操作,那么这个时候就应该优先考虑list,而不是vector。
中间插入
想在某个值的元素前面插入一个元素,首先需要find出位置并得到迭代器it,然后在it位置进行插入。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| int main() { std::list<int> lst{ 1, 2, 3, 4, 5, 6, 7, 8 }; auto it = std::find(lst.begin(), lst.end(), 5); lst.emplace(it, 50); std::for_each( lst.cbegin(), lst.cend(), [](auto&& v) { std::cout << v << std::endl; }); }
|
emplace:
(1)在位置插入新元素。
(2)与其他标准顺序容器不同,list
和forward_list
经过专门设计,可以在任何位置高效地插入和删除元素,即使在序列的中间也是如此。
(3)就地构造
返回值:
一个指向新插入元素的迭代器。