考虑篇幅过长,使用连载方式,学习STL容器,请关注STL专题,点点赞!
一 STL容器
- 序列容器(sequence containers)
vector
list
deque
stack
queue
heap
priority_queue
slist - 关联容器
tree(二叉搜索树,平衡二叉搜索树,AVL tree,红黑树)
set
map
multiset
multimap
hashtable
hash_set
hash_map
hash_multiset
hash_multimap
二 序列容器用法
注意:优先复习常用的STL模板类容器,其他的后续补充。
2.1 vector
- 内存分配
vector和array的区别,体现在内存分配上。
array:静态空间,线性连续内存 ,一旦分配内存大小就不能改变。(可以为堆内存,也可以时栈内存)。
vector:动态空间,线性连续内存,内部机制允许自行扩充空间,不够存储时会自动扩容。 - 遍历
cpp
std::vector<int> vtData(2, 9);
std::vector::iterator it;
for (it = vtData.begin(); it != vtData.end(); it++) {
std::cout << it << std::endl;
}
for (int i = 0; i < (int)vtData.size(); i++) {
std::cout << vtData[i] << std::endl;
}
for (auto &item : vtData) {
std::cout << item << std::endl;
}
- 源码关键函数
标准库copy函数
cpp
// c++ 标准函数copy用法
// 从源范围复制元素到目标范围,而不考虑目标范围是否已有内容
#include <algorithm>
#include <iterator>
#include <vector>
int main() {
std::vector<int> source = {1, 2, 3, 4, 5};
std::vector<int> destination(source.size()); // 确保目标容器有足够的空间
// 拷贝src [begin(), end())的元素到dst
std::copy(source.begin(), source.end(), destination.begin());
// 现在 destination 包含 {1, 2, 3, 4, 5}
return 0;
}
vector类型别名
cpp
// vector中类型别名
class vector {
public:
typedef T value_type;
typedef value_type* pointer;
typedef value_type* iterator;
typedef value_type& reference;
iterator start; // 空间头;指向第一个元素;begin()
iterator finish; // 空间尾;指向最后一个元素的下一个位置; end()
public:
iterator begin() {return start;}
iterator end() {return finish;}
};
vector的第一个元素和最后一个
cpp
// 第一元素
reference front {return *begin(); }
// 最后一个元素
reference back() {return *(end() - 1);}
vector尾端插入和取出,插入要考虑vector的动态空间特性,会自动扩容
cpp
// 尾巴插入一个元素; 这里体现了vector的动态空间,自动扩容特性;
void push_back(const T& x)
{
if (finish != end_of_storage) {
construct(finish, x);
++finish;
}
else
insert_aux(end(), x);
}
cpp
// 将尾端元素取出
void pop_back() {
--finish;
destroy(finish);
}
erase清除指定位置的元素,这里体现了内存偏移
cpp
iterator erase(iterator position) {
// 不是最后一个元素,擦除此位置,后续元素往前移动
if (position +1 != end()) {
copy(position + 1, finish, position);
}
// 有效元素的位置,减去1。处理尾部边界。
-- finish;
// 销毁最后一个元素(注意:finish在上一行代码,已经减1,进行了偏移)
destroy(finish);
// 注意:返回的还是原来迭代器的位置,但是此位置的元素已经变了。
// 同时,要注意vector是线性内存,map是链表结构,需要考虑迭代器是否失效。
return position;
}
考虑篇幅过长,使用连载方式,学习STL容器,请关注STL专题,点点赞!