知识的学习在于点滴记录,坚持不懈;知识的学习要有深度和广度,不能只流于表面,坐井观天;知识要善于总结,不仅能够理解,更知道如何表达!
C++ STL容器分类
C++校招面试过程中,STL容器是考察的一个重点,不仅仅通过代码考察容器的应用,还要通过回答问题考察容器的底层实现,大家平时刷题的时候,应该优先用STL容器、泛型算法来解决,不仅可以大大减少代码量,更能熟练掌握它们的应用。
通过下面表格,罗列一下常用到的C++STL容器(包含C++11新引入的容器):
容器类名(顺序容器) | 容器名称 |
---|---|
array | 数组容器(C++11) |
forward_list | 单向链表容器(C++11) |
vector | 向量容器 |
deque | 双端队列容器 |
list | 双向链表容器 |
容器类名(容器适配器) | 容器名称 |
---|---|
stack | 栈(适配deque) |
queue | 单向队列(适配deque) |
priority_queue | 优先级队列,默认是大根堆实现(适配vector) |
容器类名(关联容器) | 容器名称 |
---|---|
set | 单重集合 |
multiset | 多重集合 |
map | 单重映射表 |
multimap | 多重映射表 |
unordered_set | 无序单重集合(C++11) |
unordered_ multiset | 无序多重集合(C++11) |
unordered_map | 无序单重映射表(C++11) |
unordered_multimap | 无序多重映射表(C++11) |
要求必须掌握上面容器的这几点:
1.了解各个容器的用途,应用场景
2.了解容器的底层数据结构,内存扩容方式
3.常用数据增删改查的方法,以及各容器特有的成员方法
4.各个容器之间的对比应用
最好是在刷题的时候,或者做项目的时候,能够使用到相应的容器,这样才能达到熟练掌握。
顺序容器
这部分对于顺序容器进行一下内容总结。
vector容器内容梳理
底层数据结构:内存可以2倍扩容的数组,默认构造的vec对象底层没有分配空间,随着增加元素才从0-1-2-4-8-16-32…这样的方式进行扩容,所以vec容器初始的内存使用效率比较低,可以使用reserve方法进行优化。
数据增删查接口:
接口名称 | 使用方式 | 功能描述 | 时间复杂度 |
---|---|---|---|
push_back | push_back(val) | 从尾部添加元素 | O(1) |
pop_back | pop_back() | 从尾部删除元素 | O(1) |
insert | insert(iterator it, val) | 从迭代器指定的位置插入元素 | O(n) |
erase | erase(iterator it),erase(iterator first, iterator last) | 从迭代器指定的位置或区间删除元素 | O(n) |
reserve/resize成员方法:reserve是给vector容器预留空间,并不增加元素个数,主要用来解决vector容器初始的内存使用效率低的问题;resize不仅会给vector底层开辟空间,还增加了相应个数的元素。
遍历搜索容器:
1.可以通过迭代器遍历或者搜索容器,代码示例:
#include <iostream>
#include <vector>
using namespace std;
int main()
{
// vector容器使用示例
vector<int> vec;
for (int i = 0; i < 20; ++i)
{
vec.push_back(rand() % 100);
}
// 遍历1
vector<int>::iterator it1 = vec.begin();
for (; it1 != vec.end(); ++it1)
{
cout << *it1 << " ";
}
// 遍历2
auto it2 = vec.begin();
for (; it2 != vec.end(); ++it2)
{
cout << *it2 << " ";
}
// 遍历3,foreach底层也是通过容器的迭代器实现的容器元素遍历
for (int val : vec)
{
cout << val << " ";
}
// 遍历4
for (int i = 0; i < vec.size(); ++i)
{
cout << vec[i] << " ";
}
return 0;
}
2.可以通过泛型算法对vector容器进行搜索,代码示例:
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int main()
{
// vector容器使用示例
vector<int> vec;
for (int i = 0; i < 20; ++i)
{
vec.push_back(rand() % 100);
}
// find演示vector中搜索20是否存在,如果存在则删除第一个20
auto it1 = find(vec.begin(), vec.end(), 20