map
概述
std::map
在C++中是一种关联容器,它存储的是键值对,键和值可以是任何类型。与数组相比,std::map
有以下几个优点:
- 动态大小:数组在创建时需要指定大小,而
std::map
的大小是动态的,可以在运行时添加或删除元素。 - 键值对存储:数组通过索引访问元素,而
std::map
则通过键来访问对应的值。这使得我们可以使用非整数类型作为键,例如字符串。 - 自动排序:
std::map
中的元素按键自动排序,无论何时插入元素,std::map
都会保持排序。这对于需要有序数据的应用非常有用。 - 查找效率:在
std::map
中查找元素的时间复杂度为O(log n),而在数组中查找元素的时间复杂度为O(n)。因此,对于大数据集,std::map
的查找效率更高。 - 不存在越界问题:在数组中,如果尝试访问超出其大小的索引,会导致未定义的行为。而在
std::map
中,尝试访问不存在的键会返回一个特殊的迭代器end()
,不会导致未定义的行为。
1. map
用于存储键值对(key - value pairs),其中每一个key都唯一
map根据键值来自动排序,也可以通过键快速查找对应值
map使用红黑树实现
功能
函数 | 功能 | 时间复杂度 |
---|---|---|
insert | 插入元素 | O(log n) |
erase | 删除元素 | O(log n) |
find | 查找元素 | O(log n) |
count | 统计元素个数 | O(log n) |
size | 返回元素个数 | O(1) |
begin | 返回指向容器起始位置的迭代器 | O(1) |
end | 返回指向容器末尾位置的迭代器 | O(1) |
clear | 清空容器 | O(n) |
empty | 判断容器是否为空 | O(1) |
lower_bound | 返回指向第一个不小于指定键的元素位置 | O(log n) |
upper_bound | 返回指向第一个不大于指定键的元素位置 | O(log n) |
代码
#include <iostream>
#include <map>
using namespace std;
int main()
{
// 创建 map,并初始化
map<int, string> myMap = {{1, "Apple"}, {2, "Banana"}, {3, "Orange"}};
// 插入元素
myMap.insert(make_pair(4, "Grapes"));
// 查找访问元素
cout << "Value at key 2: " << myMap[2] << endl;
// 遍历并打印 map 各元素
for(const auto& pair : myMap)
{
cout << "Key: " << pair.first << ", Value: " << pair.second << endl;
}
// 删除元素
myMap.erase(3);
// 元素是否存在
if(myMap.count(3) == 0)
{
cout << "Key 3 not found." << endl;
}
// 清空 map
myMap.clear();
// 判空
if(myMap.empty())
{
cout << "Map is empty." << endl;
}
return 0;
}
Value at key 2: Banana
Key: 1, Value: Apple
Key: 2, Value: Banana
Key: 3, Value: Orange
Key: 4, Value: Grapes
Key 3 not found.
Map is empty.
2. multimap
功能
相比 map,multimap 允许存储多个具有相同键的键值对
函数 | 功能 | 时间复杂度 |
---|---|---|
insert | 插入元素 | O(log n) |
erase | 删除元素 | O(log n) |
find | 查找元素 | O(log n) |
count | 统计元素个数 | O(log n) |
size | 返回元素个数 | O(1) |
begin | 返回指向容器起始位置的迭代器 | O(1) |
end | 返回指向容器末尾位置的迭代器 | O(1) |
clear | 清空容器 | O(n) |
empty | 判断容器是否为空 | O(1) |
代码
#include <iostream>
#include <map>
using namespace std;
int main()
{
// 创建 map,并初始化
multimap<int, string> myMultimap = {{1, "Apple"}, {2, "Banana"}, {3, "Orange"}};
// 插入元素
myMultimap.insert(make_pair(3, "Grapes"));
// 查找访问元素
auto range = myMultimap.equal_range(2);
for(auto it = range.first; it != range.second; it ++ )
{
cout << "Key: " << it->first << ", Value: " << it->second << endl;
}
// 遍历并打印 myMultimap 各元素
for(const auto& pair : myMultimap)
{
cout << "Key: " << pair.first << ", Value: " << pair.second << endl;
}
// 删除元素
myMultimap.erase(2);
// 元素是否存在
if(myMultimap.count(2) == 0)
{
cout << "Key 2 not found." << endl;
}
// 清空 myMultimap
myMultimap.clear();
// 判空
if(myMultimap.empty())
{
cout << "myMultimap is empty." << endl;
}
return 0;
}
Key: 2, Value: Banana
Key: 1, Value: Apple
Key: 2, Value: Banana
Key: 3, Value: Orange
Key: 3, Value: Grapes
Key 2 not found.
myMultimap is empty.
3. unordered_map
功能
与 map 不同的是,unordered_map 不会根据键的顺序进行排序,而是使用哈希函数将键映射到存储桶中
具有更快的插入、删除和查找,但时间复杂度不稳定,因此通常选择 map 而非 unordered_map
函数 | 功能 | 平均时间复杂度 | 最坏时间复杂度 |
---|---|---|---|
insert | 插入元素 | O(1) | O(n) |
erase | 删除元素 | O(1) | O(n) |
find | 查找元素 | O(1) | O(n) |
count | 统计元素个数 | O(1) | O(n) |
size | 返回元素个数 | O(1) | O(1) |
clear | 清空容器 | O(n) | O(n) |
empty | 判断容器是否为空 | O(1) | O(1) |
代码
#include <iostream>
#include <unordered_map>
using namespace std;
int main()
{
// 创建 map,并初始化
unordered_map<int, string> myMap = {{1, "Apple"}, {2, "Banana"}, {3, "Orange"}};
// 插入元素
myMap.insert(make_pair(4, "Grapes"));
// 查找访问元素
cout << "Value at key 2: " << myMap[2] << endl;
// 遍历并打印 unordered_map 各元素
for(const auto& pair : myMap)
{
cout << "Key: " << pair.first << ", Value: " << pair.second << endl;
}
// 删除元素
myMap.erase(3);
// 元素是否存在
if(myMap.count(3) == 0)
{
cout << "Key 3 not found." << endl;
}
// 清空 unordered_map
myMap.clear();
// 判空
if(myMap.empty())
{
cout << "unordered_map is empty." << endl;
}
return 0;
}
Value at key 2: Banana
Key: 4, Value: Grapes
Key: 3, Value: Orange
Key: 2, Value: Banana
Key: 1, Value: Apple
Key 3 not found.
unordered_map is empty.
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。