05 容器⚓︎
约 1109 个字 3 行代码 预计阅读时间 6 分钟
注
由于这门课应该默认学生已经上过 CS106B/X,所以对容器的具体用法就没有细讲,而我之前并没有上过这门课,所以一刷过后可能会补一下这里列出容器的常见用法。
容器(container
- 组织性(organization
) :相类似的数据可以被打包在一起 - 标准性(standardization
) :有着在预期范围内且能被实现的共同点 - 抽象性(abstraction
) :用户能够较为容易地利用复杂的想法
一些典型的容器⚓︎
有以下常见容器:
- vector
- stack
- queue
- set
- map
- array:固定长度的 vector
- deque:双向队列(double ended queue)
- list(和 Python 的列表不同
! ) :双向链表 - unordered set
- unordered map
vector⚓︎
std::vector<int> vec;
:创建新的空向量std::vector<int> vec(n);
:创建一个包含 n 个 0 的向量std::vector<int> vec(n, k);
:创建一个包含 n 个 k 的向量vec.push_back(k);
:将 k 加在向量的末端vec.clear();
:移除向量内所有元素int k = vec[i];
:得到索引为 i 的元素(不检查索引越界的情况)vec.size();
:查看向量大小(元素个数)for (std::size_t i = 0; i < vec.size(); ++i) ...
:遍历向量元素vec[i] = k;
:改变索引为 i 的元素的值(不检查索引越界的情况)
set⚓︎
std::set<int> s;
:创建空集合s.insert(k)
:将值k
加入集合内s.erase(k)
:从集合中移除值k
if (s.count(k)) ...
:检查值k
是否在集合内if (s.empty()) ...
:检查集合是否为空
map⚓︎
std:::map<int, char> m;
:创建空映射m.insert({k, v}); /* or */ m[k] = v;
:将键k
和对应值v
加入映射内m.erase(k);
:将键k
从映射中移除if (m.count(k)) ...
:检查键k
是否在映射内if (m.empty()) ...
:检查映射是否为空char c = m.at(k); m.at(k) = v;
:检索并覆写键k
对应的值(若键不存在则报错)char c = m[k]; m[k] = v;
:检索并覆写键k
对应的值(若键不存在则自动插入)
分类⚓︎
序列容器⚓︎
特点:
- 按顺序访问容器
- 内部有序的容器属于这类容器
例子
在高层次上,向量是规模可伸缩的一组相同类型元素的有序集,可看做数组。
它的一些成员变量(member variables
_size
:向量的元素个数_capacity
:分配给元素的空间大小
暂时没有理解,待补充
部分序列容器对照表
容器 | std::vector |
std::deque |
std::list |
---|---|---|---|
在前端插入 / 删除 | 慢 | 快 | 快 |
在后端插入 / 删除 | 非常快 | 很快 | 快 |
索引访问 | 非常快 | 快 | 不可能 |
在中间插入 / 删除 | 慢 | 快 | 很快 |
内存占用 | 少 | 多 | 多 |
结合(切片 / 合并) | 慢 | 很慢 | 快 |
稳定性 | 差 | 很差 | 好 |
- 通常用
std::vector
可以应付大多数情况 - 若需要再前端快速插入元素,考虑用
std::deque
- 若需要合并多个列表,考虑用
std::list
(不常用)
关联容器⚓︎
特点:
- 容器不必有序
- 更加容易搜索
- 映射、集合等属于这类容器
例子
映射是由配对(pair)实现的:std::pair<const key, value>
,其中键(key)是不可改变的常量。若知道配对的第一个属性(键myMap[key]
)返回第二个属性(值
有序版本(默认)的映射和集合需要由比较符来定义,而无序映射和集合需要由一个自定义的散列函数来定义,因此无序映射和集合通常比它们的有序版本更快一些,当然也更复杂些,使用时根据情况自行权衡。
注:散列函数的知识回顾
容器适配器⚓︎
容器适配器(container adaptors)是容器的“包装纸”,它可以修改序列容器的接口,改成用户想要与容器的交互方式。
用容器适配器从 deque 中实现 queue
队列作为容器适配器被实现,使用一个来自被称为「底层容器
更具体些:
底层容器可能是某种标准容器类模板,或者别的设计好的容器类,它至少支持以下运算:
empty
size
front
back
push_back
pop_front
评论区
如果大家有什么问题或想法,欢迎在下方留言~