目录 关联容器 有序关联容器——map, set, multimap, multiset 无序关联容器——unordered_map, unordered_set, unordered_multimap, unordered_multiset 关联容器 选择什么容器根据业务需求, 研读STL剖析了解底层
目录
- 关联容器
- 有序关联容器——map, set, multimap, multiset
- 无序关联容器——unordered_map, unordered_set, unordered_multimap, unordered_multiset
关联容器
选择什么容器根据业务需求, 研读STL剖析了解底层数据结构, 更加清楚各种优势劣势
有序关联容器——map, set, multimap, multiset
map, multimap:
set, multiset:
pair:
有序依赖
- 元素的<运算符 > <运算符足以推断==和!=,交换执行即可
pair
make_pair(t1, t2) —— 自动推断类型
pair的比较
先比较前者-first;再比较后者-second;依赖于元素的<或==
容器内部类型别名
key_type 关键字类型 mapped_type set没有,关键字的关联类型 value_tyep 容器元素类型,对于set为key_type
;对于map为pair<const key_type, mapped_type>
set的iterator和const_iterator都是const的,即begin()和cbegin()得到的都是const迭代器
容器操作
增
注意检查插入单独的元素时返回值,ret.second
- 删
- 访问
通用操作
.find(k) 返回第一个找到的迭代器,不存在.end() .count(k) 数量 .lower_bound(k) 第一个>=k的迭代器 .upper_bound(k) 第一个>k的迭代器,和lower_bound得到一个范围 .equal_range(k) 返回迭代器pair<b, e>,k不存在,两个都为.end()根据通用操作得到的三种访问multi容器的方法
auto it = container.find(k); auto cnt = container.count(k); while (cnt) { *it ++; -- cnt; }
auto begin = container.lower_bound(k); auto end = container.upper_bound(k); while (begin != end) { *begin ++; }
auto ret = container.equal_range(k); auto begin = ret.first; while (begin != ret.second) { *begin ++; }
无序关联容器——unordered_map, unordered_set, unordered_multimap, unordered_multiset
unordered_map, unordered_multimap:
unordered_set, unordered_multiset:
桶
无序容器存储上组织为一组桶,每个桶保存零个或多个元素
桶管理
桶接口
.bucket_count() 当前桶个数 .max_bucket_size() 容器最大桶个数 .bucket_size(n) 第n个桶的元素个数 .bucket(k) k在哪个桶,返回整型桶迭代
local_iterator 迭代器类型 const_local_iterator .begin(n), .end(n) 桶n的迭代器 .cbegin(n), .cend(n)哈希策略
负载因子 .load_factor() float,每个桶的平均元素个数 .max_load_factor() 试图维护的平均个数,需要时会加桶保持max_load_factor() > load_factor() .rehash(n) 重组存储,使桶个数>=n的同时,bucket_coun(实际有的) > size / max_load_factor(理论上维护factor需要的) .reserve(n) 重组存储,可以保存n个而不必rehash
无序容器对关键字的要求
默认情况用==比较
内置类型,一些标准库设施如:string,智能指针,其他容器等等都哈希特例化,直接用
自定义类类型——自己提供==和哈希函数
size_t hasher(const MyClass &mc) // 这个用来找桶的 { return hash<string>()(mc.str()); // str()的到MyClass里的成员,能用来标识 // hash<string>()得到一个临时可调用类对象 } bool eqOp(const MyClass &mc1, const MyClass &mc2) // 这个用来找桶里元素的 { return mc1.str() == mc2.str(); } unordered_map<MyClass, decltype(hasher)*, decltype(eqOp)*> store;