C++ map詳解


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還是很耗內存的


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM