multimap是C++ STL中允许键重复的关联容器,基于红黑树实现,元素按键有序存储,支持O(log n)的插入、删除与查找。1. 特性:支持重复键、自动排序、不可用下标访问。2. 操作:通过insert或emplace插入;find、count和equal_range处理查找;erase删除元素;迭代器遍历。3. 可自定义比较规则如降序。4. 适用一对多场景,如成绩映射学生、事件绑定多个回调。

在C++标准库中,multimap 是一种关联式容器,属于 STL 的一部分。它与 map 非常相似,但关键区别在于:multimap 允许键(key)重复,也就是说多个元素可以拥有相同的键。这使得 multimap 在处理一对多映射关系时非常有用。
1. multimap 基本特性
multimap 内部通常基于红黑树实现,元素按照键自动排序(默认升序),每个元素是一个键值对(key-value pair),类型为 std::pair。
主要特点包括:
- 支持重复的 key
- 按键有序存储(可自定义比较函数)
- 插入、删除、查找的时间复杂度为 O(log n)
- 不支持通过下标直接访问(因为 key 不唯一)
2. 常用操作和成员函数
以下是 multimap 中常用的操作方法:
立即学习“C++免费学习笔记(深入)”;
构造与赋值-
multimap:创建一个空的 multimapmmp; -
multimap:初始化包含重复 key 的元素mmp = {{1, "apple"}, {1, "banana"}, {2, "cherry"}}; -
mmp = another_mmp;:赋值操作
由于不能使用下标访问,插入必须通过 insert() 或 emplace()。
mmp.insert({key, value});mmp.insert(std::make_pair(key, value));-
mmp.emplace(key, value);:原地构造,效率更高
示例:
multimap查找元素mmp; mmp.insert({1, "one"}); mmp.insert({1, "uno"}); // 允许重复 key mmp.emplace(2, "two");
由于 key 可能对应多个值,不能像 map 一样用 operator[] 获取。应使用以下方法:
-
find(key):返回指向第一个匹配 key 的迭代器,未找到返回end() -
count(key):返回指定 key 的元素个数 -
equal_range(key):返回一个std::pair,表示所有相同 key 的范围
遍历某个 key 的所有值:
auto range = mmp.equal_range(1);
for (auto it = range.first; it != range.second; ++it) {
cout << it->second << endl; // 输出 "one", "uno"
}
删除元素
-
erase(key):删除所有等于 key 的元素,返回删除个数 -
erase(iterator):删除指定位置的元素 -
erase(first, last):删除一个区间内的元素
示例:
mmp.erase(1); // 删除所有 key 为 1 的元素遍历 multimap
使用迭代器遍历所有元素(按 key 排序):
for (const auto& pair : mmp) {
cout << pair.first << ": " << pair.second << endl;
}
3. 自定义比较规则
默认情况下,multimap 按 key 升序排列。可通过自定义比较函数改变排序方式。
例如,按降序排列:
multimap> mmp; mmp.insert({1, "a"}); mmp.insert({3, "c"}); mmp.insert({2, "b"}); // 输出顺序:3:c, 2:b, 1:a
也可以传入仿函数或 lambda(需用 decltype 和构造参数)。
4. 应用场景举例
multimap 适合如下场景:
- 学生按成绩分类:多个学生可能有相同分数
- 电话簿中一个人有多个号码(以姓名为 key)
- 事件系统中,一个事件类型绑定多个回调函数
示例:按分数存储学生姓名
multimapstudents; students.emplace(85, "Alice"); students.emplace(90, "Bob"); students.emplace(85, "Charlie"); auto range = students.equal_range(85); cout << "得分 85 的学生:" << endl; for (auto it = range.first; it != range.second; ++it) { cout << it->second << endl; }
基本上就这些。multimap 提供了灵活的一对多映射能力,合理使用能简化很多数据组织逻辑。注意避免误用 operator[],并善用 equal_range 处理重复键。不复杂但容易忽略细节。









