map容器的使用方法的总结
map是键值对的关联容器 key ->>value ,<map><map>1.下标法map[key] = value//直接赋值法2.insert()插入法要使用pair 推荐使用make_pair()3.emplace插入法,效率高于insert。
map是键值对的关联容器 key ->>value ,key是唯一且默认按照升序排序的
与unordered_map 和multi_map的区别 80%多使用unordered_map 其次map容器
| 特性 | map | unordered_map | multimap |
| 底层实现 | 红黑树 | 哈希表 | 红黑树 |
| key的特性 | 唯一,不可重复 | 唯一,不可重复 | 可重复,支持多个相同的key |
| 序列性 | 自动按key升序(可定义为降序 ) | 无序,无固顺序 | 同map的key序列 |
| 查找时间复杂度 | O (logn)(红黑树二分查找) | 平均 O (1),最坏 O (n)(哈希冲突) | O (logn)(红黑树二分查找) |
| 插入/删除复杂度 | O (logn)(红黑树节点操作) | 平均 O (1),最坏 O (n)(哈希冲突) | O (logn)(红黑树节点操作) |
| 删查改语法 | 基础语法通用,无重复 key 限制 | 基础语法通用,无重复 key 限制 | 插入用insert/emplace(下标法不可用),查找 / 删除需遍历 |
| 空间开销 | 较小(红黑树节点开销) | 较大(哈希表预分配空间 + 哈希桶) | 较小(红黑树节点开销) |
| 头文件 | <map>(万能头已包含) |
<unordered_map>(万能头已包含) |
<map>(万能头已包含) |
一.增
1.下标法
map[key] = value//直接赋值法
map<int, string> mp;
mp[1] = "张三"; // 新增:key=1不存在,插入{1,"张三"}
mp[1] = "张小三";// 覆盖:key=1已存在,value更新为"张小三"
2.insert()插入法 要使用pair 推荐使用make_pair()
mp.insert(pair<int, string>(2, "李四")); // 写法1:显式构造pair
mp.insert(make_pair(3, "王五")); // 写法2:make_pair(推荐)
mp.insert(make_pair(2, "李小四")); // 插入失败:key=2已存在,value仍为"李四"
3.emplace插入法,效率高于insert
mp.emplace(4, "赵六"); // 新增{4,"赵六"},高效无拷贝
mp.emplace(4, "赵小六");// 插入失败:key=4已存在
二、删
1.mp.erase(key)//删除key值对应的value
mp.erase(1); // 删除key=1的键值对,成功返回1,失败返回0
2.按迭代器删除 mp.erase(iterator)(遍历删除时用)
auto it = mp.find(2);
if(it != mp.end()) mp.erase(it); // 找到key=2,删除对应元素
3.mp.clear()清除所有的键值对,mp.size()变为0
mp.clear(); // 清空整个map
三、查
1.find() 根据 key 查找,返回迭代器:找到则指向对应键值对,没找到则返回mp.end()
auto it = mp.find(3);
if(it != mp.end()){
cout << "找到:" << it->first << " " << it->second << endl; // it->first=key,it->second=value
}else{
cout << "未找到key=3" << endl;
}
2.下标法 mp[key] 直接通过 key 取值,存在则返回 value 引用,不存在则自动插入mp[key]=默认值;
if(mp.count(4)){ // 先通过count判断key是否存在
cout << mp[4] << endl; // 确定存在,再用下标取值
}
补充 count()判断key是否存在map容器中
if(mp.count(5)) cout << "key=5存在" << endl;
else cout << "key=5不存在" << endl;
四、改
map 无专门的「修改」方法,因 key 唯一,修改本质是对已存在的 key 重新赋值 value
1.下标法
确定key,对value进行修改
2.find查找到之后,对其进行修改 用 it ->second进行修改
auto it = mp.find(2);
if(it != mp.end()) it->second = "李四四"; // 找到后修改value
五、常用增删查改辅助函数
map<int, string> mp = {{1,"张三"},{2,"李四"}};
mp.empty(); // 判断是否为空:空返回true,非空返回false
mp.size(); // 获取键值对个数:此处返回2
mp.begin(); // 指向第一个元素的迭代器(默认升序,指向key最小的元素)
mp.end(); // 指向最后一个元素的下一个位置(尾后迭代器,不可解引用)
mp.rbegin(); // 反向迭代器,指向最后一个元素(key最大的元素)
mp.rend(); // 反向尾后迭代器
六、map的升序和降序
map的key默认为按key升序,也可在构造map中添加greater<key>改为降序
map<int, string, greater<int>> mp;
七、各容器的使用场景
1.map (key唯一且有序)
- 需要按 key 有序遍历 / 输出(比如按 key 升序 / 降序打印结果);
- 需要按 key 范围查找(比如查找 key≥5 且 key≤10 的所有元素);
- 数据量较小(n<1000),O (logn) 的效率完全足够;一句话:需要有序,选 map,红黑树的天然排序性无需额外处理。
2.unordered_map(key无序唯一)
- 只需要键值对映射,无需有序,追求读写效率(比如统计元素出现次数、哈希表缓存、快速查找);
- 数据量较大(n≥1000),对速度有要求;
- 经典刷题场景:两数之和、字母异位词分组、哈希表统计频率等。一句话:无有序要求,优先选 unordered_map,速度最快。
3.mulpimap(有序可重复 key)
- 明确需要一个 key 对应多个 value,且需要按 key 有序;
- 经典场景:员工编号 - 员工姓名(一个部门多个员工)、课程编号 - 学生姓名(一个课程多个学生);替代方案:如果不需要有序,可用
unordered_map<Key, vector<Value>>(哈希表 + vector),效率更高,刷题中更常用(比如unordered_map<int, vector<string>> mp;,一个 key 对应一个 value 数组)。
更多推荐


所有评论(0)