【C++ STL】map容器的基本使用

map容器

map 是 C++ STL 中最常用的有序关联式容器 ,核心是存储 key-value(键值对),且 key 唯一、自动排序,底层基于红黑树实现,保证增删查改的时间复杂度稳定在O(logn)。
特性:

  • 存储结构:键值对(key-value),每个 key 对应唯一 value
  • 排序规则:默认按 key 升序排列(可自定义排序规则)
  • 可修改性:key 不可修改(需删除后重新插入),value 可直接修改
  • 底层实现:红黑树(平衡二叉树),避免退化成链表,保证高效操作
  • 空值处理:用 [] 访问不存在的 key 时,会自动插入该 keyvalue 为默认值

基本使用

  • 使用 map 必须包含头文件
c++ 复制代码
#include <map> // 核心头文件
  • 初始化
c++ 复制代码
// 1、空map(默认构造函数
// 键(int)值(string)
map<int, string> m1;
// key(可以是自定义类型)
map<pair<int, int>, vector<int>> m2;

// 2、列表初始化(c++ 11)
map<int, string> m3 = {
	{1, "zs"},
	{2, "ls"}
};

// 3、拷贝构造
map<int, string> m4(m3);

// 4、范围初始化
map<int, string> m5(m3.begin(), m3.end());

// 5、自定义键的排序规则
// 这里的排序规则只针对键,可以传入比较函数或者仿函数
map<int, string, greater<int>> m6;

核心操作API

插入元素

  • \]运算符,m\[key\] = value的方式,比较简单(key 不存在则插入,存在则修改 value);

map<int, string> m = {
{1, "zs"},
{2, "ls"}
};

// []插入元素
m[3] = "ww";

cout << m[3] << endl;

复制代码
* insert({key, value}),key 存在则**插入失败**(不修改),返回 pair \<迭代器,bool\>

```c++
map<int, string> m = {
	{1, "zs"},
	{2, "ls"}
};

// insert插入元素
pair<map<int,string>::iterator, bool> ret = m.insert({ 3, "ww" });

cout << ret.second << endl;		// 1

ret = m.insert({ 3, "zl" });
cout << ret.second << endl;		// 0
  • emplace(key, value)原地构造,避免拷贝,性能优于 insert,key 存在则插入失败
  • insert_or_assign(key, value)C++17 新增,key 存在则修改 value,不存在则插入(兼顾 [] 和 insert 的优点)
c++ 复制代码
map<int, string> m = {
	{1, "zs"},
	{2, "ls"}
};

// insert_or_assign插入元素
m.insert_or_assign(3, "ww");

m.insert_or_assign(3, "ll");
cout << m[3] << endl;		// ll

访问元素

  • \] 运算符,不建议使用(不存在则会插入默认值)

c++ 复制代码
map<int, string> m = {
	{1, "zs"},
	{2, "ls"}
};

cout << m.at(2) << endl;
  • 迭代器访问
c++ 复制代码
map<int, string> m = {
	{1, "zs"},
	{2, "ls"}
};

auto ret = m.find(1);
// 这里必须判断是否找到元素
if (ret != m.end())
{
	cout << ret->first << ":" << ret->second << endl;
}

查找元素

  • find,返回迭代器,如果未找到返回m.end()
c++ 复制代码
map<int, string> m = {
	{1, "zs"},
	{2, "ls"}
};

auto ret = m.find(1);
// 这里必须判断是否找到元素
if (ret != m.end())
{
	cout << ret->first << ":" << ret->second << endl;
}
  • count(),仅判断是否存在

删除元素

  • 按key删除,返回删除元素的个数
c++ 复制代码
map<int, string> m = {
	{1, "zs"},
	{2, "ls"}
};

int ret = m.erase(1);
cout << ret << endl;		// 1
  • 按迭代器删除
c++ 复制代码
map<int, string> m = {
	{1, "zs"},
	{2, "ls"}
};

auto ret = m.find(1);
// 这里必须判断是否找到元素
if (ret != m.end())
{
	// 返回的是迭代器
	auto re = m.erase(ret);
	cout << re->second << endl;
}
  • 删除范围,左开右闭
c++ 复制代码
map<int, string> m = {
	{1, "zs"},
	{2, "ls"}
};

m.erase(m.begin(), m.find(2));
  • clear清空所有元素

遍历元素

  • 普通迭代器,可读写
c++ 复制代码
map<int, string> m = {
	{1, "zs"},
	{2, "ls"}
};

for (map<int, string>::iterator it = m.begin(); it!= m.end(); ++it)
{
	cout << "key = " << it->first << ", value = " << it->second << endl;
}
  • const迭代器,只读
c++ 复制代码
map<int, string> m = {
	{1, "zs"},
	{2, "ls"}
};

for (map<int, string>::const_iterator it = m.cbegin(); it!= m.cend(); ++it)
{
	cout << "key = " << it->first << ", value = " << it->second << endl;
}
  • 范围for循环(c++11)
c++ 复制代码
map<int, string> m = {
	{1, "zs"},
	{2, "ls"}
};

for (auto& p : m)
{
	cout << p.first << ": " << p.second << endl;
}
  • 反向迭代器

进阶用法

  • 自定义排序规则
    • 按key降序
c++ 复制代码
map<int, string, greater<int>> m6;
复制代码
- 自定义排序函数
c++ 复制代码
// 按照字符串长度排序(倒序)
struct strLenCmp {
	bool operator()(const string& a, const string& b) const
	{
		return a.size() > b.size();
	}
};

int main()
{
	map<string, string, strLenCmp> m = {
		{"aaa", "a"},
		{"bbbb", "b"},
		{"ccccc", "c"}
	};

	for (auto& p : m) {
		cout << p.first << endl;
	}

	return EXIT_SUCCESS;
};
复制代码
- 若 `key` 是自定义结构体 / 类,必须重载 `<` 运算符(满足排序规则)
  • 性能优化
    • 避免频繁使用 [] 访问不存在的 key(会自动插入默认值,浪费内存);
    • 插入大量元素时,优先用 emplace() 而非 insert()(原地构造,减少拷贝);
    • 遍历只读场景用 const 迭代器(避免误修改,且性能略优);
    • 若无需有序,优先用 unordered_map(哈希表,平均查找 O(1))。

结束语

  • map 核心是有序唯一键值对 ,底层红黑树保证 O(logn) 操作效率,默认按 key 升序排列;
  • 插入优先用 emplace()(高性能),访问优先用 find()+ 迭代器(避免 [] 自动插入空值),删除用 erase(key)(最直观);
  • 自定义 key 需重载 < 运算符,自定义排序需传入仿函数,只读遍历用 const 迭代器更安全。
相关推荐
xuansec2 小时前
【JavaEE安全】Java反射机制:核心原理、实战应用与安全风险管控
java·安全·java-ee
蜜獾云2 小时前
设计模式之原型模式:以自己为原型,自己实现自己的对象拷贝逻辑
java·设计模式·原型模式
汉克老师2 小时前
GESP 四级C++考试2025年3月第二部分判断题(1-10题)
数据结构·c++·排序算法·指针·结构体·gesp4级·gesp四级
格林威2 小时前
工业相机图像高速存储(C++版):内存映射文件(MMF)零拷贝方案,附海康相机实战代码!
开发语言·c++·数码相机·计算机视觉·视觉检测·工业相机·海康相机
无限进步_2 小时前
深入解析string:从设计思想到完整实现
开发语言·c++·ide·windows·git·github·visual studio
nhc0882 小时前
贵州本地企业做软件定制开发,怎么选靠谱服务商?
java·微信小程序·软件开发·小程序开发
8Qi82 小时前
LeetCode热题100--189
c语言·数据结构·c++·算法·leetcode
灰色小旋风2 小时前
力扣第八题C++ 字符串转换整数
c++·算法·leetcode
melonbo2 小时前
C++ 中用于模块间通信的设计模式
开发语言·c++·设计模式