一、概述
map 由红黑树实现,其元素都是 “键值/实值” 所形成的一个对组(key/value pairs)。每个元素有一个键,是排序准则的基础。每一个键只能出现一次,不允许重复。
map主要用于资料一对一映射的情况,map 内部自建一颗红黑树,这颗树具有对数据自动排序的功能,所以在 map 内部所有的数据都是有序的。比如一个班级中,每个学生的学号跟他的姓名就存在着一对一映射的关系。
二、定义及初始化
使用之前必须加相应容器的头文件:
#include <map> // map属于std命名域的,因此需要通过命名限定,例如using std::map;
定义的代码如下:
map<int, string> a; // 定义一个int类型的映射a // map<int, string> a(10); // error,未定义这种构造函数 // map<int, string> a(10, 1); // error,未定义这种构造函数 map<int, string> b(a); // 定义并用映射a初始化映射b // map<int, string> b(a.begin(), a.end()); // error,未定义这种构造函数
三、基本操作
3.1 容量函数
- 容器大小:
mp.size();
- 容器最大容量:
mp.max_size();
- 容器判空:
mp.empty();
- 查找键 key 的元素个数:
mp.count(key);
#include <iostream> #include <map> #include <string> using namespace std; int main(int argc, char* argv[]) { map<int,string> mp; mp.insert({ 1, "张三" }); mp.insert({ 2, "李四" }); mp.insert(pair<int, string>{ 3, "隔壁老王" }); cout << mp.size() << endl; // 输出:3 cout << mp.max_size() << endl; // 输出:89478485 // 输出:1 cout << mp.count(2) << endl; // 输出:1 if (mp.empty()) cout << "元素为空" << endl; // 未执行 return 0; }
3.2 添加函数
- 在容器中插入元素:
mp.insert(const T& x);
- 任意位置插入一个元素:
mp.insert(iterator it, const T& x);
#include <iostream> #include <map> #include <string> using namespace std; int main(int argc, char* argv[]) { map<int,string> mp; // 在容器中插入元素 mp.insert({ 1, "张三" }); mp.insert({ 2, "李四" }); // 任意位置插入一个元素 map<int, string>::iterator it = mp.begin(); mp.insert(it, pair<int, string>{ 3, "隔壁老王" }); // 会自动排序 for (it = mp.begin(); it != mp.end(); it++) cout << it->first << " " << it->second << endl; cout << endl; return 0; } /* 1 张三 2 李四 3 隔壁老王 */
3.3 删除函数
- 删除键值为 keyValue 的元素:
mp.pop_back(const T& keyValue);
- 删除迭代器所指的元素:
mp.erase(iterator it);
- 删除区间[first,last]之间的所有元素:
mp.erase(iterator first, iterator last);
- 清空所有元素:
mp.clear();
#include <iostream> #include <map> #include <string> using namespace std; int main(int argc, char* argv[]) { map<int,string> mp; // 在容器中插入元素 mp.insert({ 1, "张三" }); mp.insert({ 2, "李四" }); mp.insert({ 4, "王五" }); mp.insert({ 5, "小明" }); // 任意位置插入一个元素 mp.insert(mp.begin(), pair<int, string>{ 3, "隔壁老王" }); // 会自动排序 // 删除键值为keyValue的元素 mp.erase(2); // 删除迭代器所指的元素 mp.erase(mp.begin()); // 删除区间[first,last]之间的所有元素 mp.erase(mp.begin(), ++mp.begin()); // 遍历显示 map<int, string>::iterator it = mp.begin(); for (it = mp.begin(); it != mp.end(); it++) cout << it->first << " " << it->second << endl; // 清空容器内的所有元素 mp.clear(); // 判断map是否为空 if (st.empty()) cout << "元素为空" << endl; // 输出:元素为空 return 0; } /* 4 王五 5 小明 元素为空 */
3.4 访问函数
- 查找键 key 是否存在,若存在,返回该键的元素的迭代器;若不存在,返回 map.end():
mp.find(key);
#include <iostream> #include <map> #include <string> using namespace std; int main(int argc, char* argv[]) { map<int,string> mp; // 在容器中插入元素 mp[1] = "张三"; mp[2] = "李四"; mp[3] = "隔壁老王"; // 通过find(key)查找键值 cout << mp.find(1)->first << endl; // 输出:1 cout << mp.find(2)->second << endl; // 输出:李四 return 0; }
3.5 其他函数
- 交换两个同类型容器的元素:
swap(map&, map&);
或mp.swap(map&);
#include "stdafx.h" #include <iostream> #include <map> #include <string> using namespace std; int main(int argc, char* argv[]) { map<int,string> mp1; // 在容器中插入元素 mp1[1] = "张三"; mp1[2] = "李四"; mp1[3] = "隔壁老王"; map<int, string> mp2; // 在容器中插入元素 mp2[1] = "tom"; mp2[2] = "jerry"; mp2[3] = "mariy"; // 交换两个容器的元素 mp2.swap(mp1); // 通过iterator遍历mp1 map<int, string>::iterator it; for (it = mp1.begin(); it != mp1.end(); it++) cout << it->second << " "; // 输出:tom jerry mariy cout << endl; return 0; }
四、迭代器与算法
1. 迭代器
- 开始迭代器指针:
mp.begin();
- 末尾迭代器指针:
mp.end();
// 指向最后一个元素的下一个位置 - 指向常量的开始迭代器指针:
mp.cbegin();
// 意思就是不能通过这个指针来修改所指的内容,但还是可以通过其他方式修改的,而且指针也是可以移动的。 - 指向常量的末尾迭代器指针:
mp.cend();
- 反向迭代器指针,指向最后一个元素:
mp.rbegin();
- 反向迭代器指针,指向第一个元素的前一个元素:
mp.rend();
- 返回最后一个 key<=keyElem 元素的迭代器:
mp.lower_bound(keyElem);
- 返回第一个 key>keyElem 元素的迭代器:
mp.upper_bound(keyElem);
- 返回容器中 key 与 keyElem 相等的上下限的两个迭代器,这两个迭代器被放在对组(pair)中:
mp.equal_range(keyElem);
#include <iostream> #include <map> #include <string> using namespace std; int main(int argc, char* argv[]) { map<int,string> mp; // 在容器中插入元素 mp[1] = "张三"; mp[2] = "李四"; mp[3] = "隔壁老王"; cout << mp.begin()->first << endl; // 输出:1 cout << (--mp.end())->first << endl; // 输出:3 cout << mp.cbegin()->first << endl; // 输出:1 cout << (--mp.cend())->first << endl; // 输出:3 cout << mp.rbegin()->first << endl; // 输出:3 cout << (--mp.rend())->first << endl; // 输出:1 cout << mp.lower_bound(2)->first << endl; // 输出:2 cout << mp.upper_bound(2)->first << endl; // 输出:3 pair<map<int, string>::iterator, map<int, string>::iterator> t_pair = mp.equal_range(2); cout << t_pair.first->first << endl; // 输出:2 cout << t_pair.second->first << endl; // 输出:3 cout << endl; return 0; }
2. 算法
- 遍历元素
map<int>::iterator it; for (it = mp.begin(); it != mp.end(); it++) cout << it->second << endl;
五、总结
可以看到,map 与set的用法基本一致,只有以下一处不同:
- map 可以像数组那样插入元素,而 set 不行。
来源:https://www.cnblogs.com/linuxAndMcu/p/10261263.html