1.什么是map
map是一個鍵值對容器。在處理一對一數據是,很有用。
2.map數據結構的特點
map內部自建一顆紅黑樹,這棵樹具有對數據自動排序的功能,
因此,map內的數據都是按key的值排好序的。
3.map數據插入
數據的插入有三種方法:
第一種,調用insert函數,插入pair類型數據
示例如下所示:
#include <map> #include <string> #include <iostream> Using namespace std; int main() { map<int, string> mapStudent; mapStudent.insert(pair<int, string>(1, “student_one”)); mapStudent.insert(pair<int, string>(2, “student_two”)); mapStudent.insert(pair<int, string>(3, “student_three”)); map<int, string>::iterator iter; for(iter = mapStudent.begin(); iter != mapStudent.end(); iter++) { cout<<iter->first<<” ”<<iter->second<<end; } return 0; }
第二種,調用insert插入value_type類型數據
示例如下所示:
#include <map> #include <string> #include <iostream> Using namespace std; int main() { map<int, string> mapStudent; mapStudent.insert(map<int, string>::value_type(1, “student_one”)); mapStudent.insert(map<int, string>::value_type(2, “student_two”)); mapStudent.insert(map<int, string>::value_type(3, “student_three”)); map<int, string>::iterator iter; for(iter = mapStudent.begin(); iter != mapStudent.end(); iter++) { cout<<iter->first<<” ”<<iter->second<<end; } return 0; }
第三種,使用數組賦值方式
#include <map> #include <string> #include <iostream> Using namespace std; int main() { map<int, string> mapStudent; mapStudent[1]="student_one"; mapStudent[2]="student_two"; mapStudent[3]="student_three"; map<int, string>::iterator iter; for(iter = mapStudent.begin(); iter != mapStudent.end(); iter++) { cout<<iter->first<<” ”<<iter->second<<end; } return 0; }
如何判斷數據是否插入成功?
insert函數的返回值類型為:Pair<map<int,string>::iterator,bool>
返回值的key值表示,返回map的迭代器
返回值的value值表示,是否插入成功
因此,我們可以使用以下代碼來判斷,map鍵值對是否插入成功
Pair<map<int,string>::iterator,bool> Insert_Pair=mapStudent.insert(pair<int, string>(1, “student_one”)); if(Insert_Pair.second) cout<<"success.\n"; else cout<<"failed.\n";
4.map數據查找
第一種,使用count方法判定是否存在
第二種,使用find方法,定位key出現的位置,該方法返回一個迭代器。
當數據出現時,返回數據所在位置的迭代器;
否則,返回的迭代器等於end方法返回的迭代器。
示例代碼如下:
map<int,string>::iterator iter; iter=mapStudent.find(1); if(iter!=mapStudent.end()) cout<<"success find.\n"; else cout<<"failed.\n";
第三種,使用Lower_bound,Upper_bound方法,返回key的邊界,在此,不再詳細介紹。
5.map數據刪除
使用了我們很熟悉的erase函數,map中該函數有三個重載。
1)使用迭代器刪除
map<int,string>::iterator iter; iter = mapStudent.find(1); mapStudent.erase(iter);
2)使用關鍵字key刪除
int result = mapStudent.erase(1);
成功返回1,否則返回0
3)使用迭代器,刪除區間內的數據
mapStudent.erase(mapStudent.begin(),mapStudent.end());
6.關於map的自動排序
前面我們說過,map內的數據會根據key值由大到小排序,
也就是說key值必須支持小於<運算,否則無法插入map。
對於上面的示例,我們知道int類型本身是支持小於運算的。
但是對於不支持小於運算的key類型,我們該如何插入map呢?
很顯然,我們需要自定義該類型的<操作符。
如下例所示,我們要建立一個map<學生信息,分數>:
typedef struct tagStudentInfo { int nID; string strName; bool operator<(tagStudentInfo const &_A) const { if(nID<_A.nID) return true; return false; } }StudentInfo,*PStudentInfo; int main() { map<StudentInfo,int> mapStudent; StudentInfo studentInfo; studentInfo.nID=1; studentInfo.strName="student_one"; mapStudent.insert(pair<StudentInfo, int>(studentInfo,80)); return 0; }
另外一種方式是,定義一個單獨的類,類中定義key類型的比較函數
示例代碼如下:
typedef struct tagStudentInfo { int nID; string strName; }StudentInfo,*PStudentInfo; class sort { public: bool operator()(tagStudentInfo const &_A,tagStudentInfo const &_B) const { if(_A.nID<_B.nID) return true; return false; } } int main() { map<StudentInfo,int,sort> mapStudent; StudentInfo studentInfo; studentInfo.nID=1; studentInfo.strName="student_one"; mapStudent.insert(pair<StudentInfo, int>(studentInfo,80)); return 0; }
7.map內存占用
前面我們介紹過,map的數據結構為一顆紅黑樹,
該樹的一個節點在不保存數據時,占用16字節的空間,
包括一個父節點指針,左右孩子指針,還有一個枚舉值(標示紅黑的,相當於平衡二叉樹中的平衡因子),
可見,map還是很耗內存的。