一、概述
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 不行。