C++ map
容器介绍
map
是 C++ 标准库中的一个关联容器,它存储键值对,每个键值对的键是唯一的。map
中的元素是按照键的排序顺序进行存储的(通常使用键的 <
运算符进行排序)。map
实现了一个自平衡的二叉查找树,通常是红黑树,这使得其查找、插入和删除操作的时间复杂度为 O(log n)。
1. map
的基本特性
- 键唯一性:
map
中的每个键都是唯一的。 - 键排序:
map
按照键的顺序进行排序,默认使用operator<
来排序键。你也可以自定义排序规则。 - 关联存储:每个键对应一个值,即每个键值对(key-value pair)。
- 自动排序:默认情况下,
map
会按照键的升序进行排序,但你可以提供自定义的比较函数来改变排序顺序。
2. map
的常见操作
2.1 构造与初始化
#include <iostream>
#include <map>
int main() {
// 使用默认构造函数
std::map<int, std::string> m;
// 使用初始化列表
std::map<int, std::string> m2 = {{1, "one"}, {2, "two"}, {3, "three"}};
// 输出
for (const auto& pair : m2) {
std::cout << pair.first << ": " << pair.second << std::endl;
}
return 0;
}
2.2 插入元素
你可以使用 insert()
或 []
操作符来插入元素。
std::map<int, std::string> m;
m[1] = "apple"; // 使用 [] 插入
m.insert({2, "banana"}); // 使用 insert 插入
2.3 查找元素
使用 find()
方法可以查找某个键对应的值。
std::map<int, std::string> m = {{1, "apple"}, {2, "banana"}};
auto it = m.find(1); // 查找键为1的元素
if (it != m.end()) {
std::cout << "Found: " << it->second << std::endl;
}
2.4 删除元素
可以使用 erase()
删除指定键的元素。
m.erase(1); // 删除键为1的元素
2.5 获取大小与检查是否为空
std::cout << "Size: " << m.size() << std::endl;
std::cout << "Is empty: " << (m.empty() ? "Yes" : "No") << std::endl;
2.6 访问元素
可以使用 []
操作符或 at()
方法访问元素。注意,如果键不存在,[]
操作符会插入一个默认值。
std::cout << m[1] << std::endl; // 如果键1存在,返回对应的值;如果不存在,插入一个默认值
2.7 遍历 map
可以使用迭代器遍历 map
:
for (auto it = m.begin(); it != m.end(); ++it) {
std::cout << it->first << ": " << it->second << std::endl;
}
或者使用范围基于的 for
循环:
for (const auto& pair : m) {
std::cout << pair.first << ": " << pair.second << std::endl;
}
3. 自定义排序规则
map
默认按照键的升序排序,但可以自定义排序规则。例如,按降序排序:
#include <iostream>
#include <map>
struct Descending {
bool operator()(int a, int b) const {
return a > b;
}
};
int main() {
std::map<int, std::string, Descending> m;
m[1] = "apple";
m[2] = "banana";
m[3] = "cherry";
for (const auto& pair : m) {
std::cout << pair.first << ": " << pair.second << std::endl;
}
return 0;
}
4. map
和 unordered_map
的区别
- 排序:
map
是有序的,它按照键的顺序进行排序;而unordered_map
是无序的,它根据哈希值存储元素。 - 时间复杂度:
map
的查找、插入、删除操作的时间复杂度是 O(log n),而unordered_map
的这些操作的时间复杂度是 O(1)(在最坏的情况下可能退化为 O(n))。
5. 常见的成员函数
insert()
:插入元素。find()
:查找元素。erase()
:删除元素。size()
:获取元素个数。empty()
:检查容器是否为空。clear()
:删除所有元素。
如果需要快速查找并且顺序不重要,可以考虑使用 unordered_map
。
#include <map>
#include <string>
#include <iostream>
int main() {
// 示例:使用 map 存储键值对
std::map<int, std::string> m;
m[1] = "apple";
m[2] = "banana";
m[3] = "cherry";
// 遍历并输出
for (const auto& pair : m) {
std::cout << pair.first << ": " << pair.second << std::endl;
}
return 0;
}