例說資料結構&STL(九)——map
1 白話map
map是STL的一個關聯容器,它提供一對一(其中第一個可以稱為關鍵字,每個關鍵字只能在map中出現一次,第二個可能稱為該關鍵字的值)的資料處理能力。由於這個特性,它完成有可能在我們處理一對一資料的時候,在程式設計上提供快速通道。這裡說下map內部資料的組織,map是內部自建一顆紅黑樹(一種非嚴格意義上的平衡二叉樹),這顆樹具有對資料自動排序的功能,所以在map內部所有的資料都是有序的,這和資料結構set一樣,只不過map的鍵與值是不同的型別,而set中每個鍵值對是同一個值。
map鍵與值都可以是隨意型別,例如我們想訪問學生登分系統,通過定義一個姓名對應分數的map,這樣鍵可以是string型別,而值可以是int型別,所以定義的map可以是map<string,int> score
。此外我們還想在登分之前通過學號姓名的map,這樣鍵值對我們就可以分別定義為int,string型別,所以定義的map又可以是map<int,string> name
。
2 STL中map實戰
2.1 包含map的標頭檔案
#include<map>
using namespace std;
2.2 map物件宣告
map的構造過載了好幾種建構函式,但是都是涉及記憶體分配器,所以我們就按預設定義即可:
map<int,float> map_fir;
2.3 插入鍵值對
由於map是自動排序的,所以鍵值對插入什麼地方無需關注,我們只要關心放入什麼資料就行。map插入鍵值對有三種方式,如下:
map<int,float> map_sed;
map_sed.insert(pair<int,float>(100 , 0.1234)); //方法一
map_sed.insert(map<int,float>::value_type(110,100.86)); //方法二
map_sed[120] = 10000; // 方法三
以上三種用法,雖然都可以實現資料的插入,但是它們是有區別的。當然前兩種方式是一樣的,都是用insert函式插入資料。但是資料的插入涉及到集合的唯一性這個概念,即當map中有這個關鍵字時,insert操作是插入資料不了的,但是用operator[]過載的方式就不同了,它可以覆蓋以前該關鍵字對應的值。如下:
map<int,float> map_sed;
map_sed.insert(pair<int,float>(100 , 0.1234));
map_sed.insert(pair<int,float>(100 , 0.5555)); //該鍵值對不會更新,100鍵對應的還是0.1234值.
map_sed[110] = 50;
map_sed[110] = 10086; //110鍵對應的值會發生改變,變成10086。
2.4 查詢鍵值對
有時候我們希望查詢一下當前map中是否存在某一鍵值,和set一樣我們有兩種方法,如下:
map<int,float> map_thd;
map_thd.count(110); // 統計map中某一關鍵字出現的個數,注意是關鍵字,不是值
上面程式統計110出現的個數,我們知道map中關鍵字只可以出現一次,所以返回結果要麼是1要麼是0。所以通過返回值可以確認map中是否存在該關鍵字。
map<int,float> map_for;
if(map_for.find(110)!=map_for.end()) // find()方法返回的是查詢關鍵字的迭代器,如果沒有查詢到則指向end()
//...
2.5 邊界元素
map<int,float>::iterator iter1 = map_fir.lower_bound(2); //返回map中>=2的索引(迭代器),切記不是小於2的有意思
map<int,float>::iterator iter2 = map_fir.upper_bound(2); //返回map中>2的索引
2.6 查詢鍵值對
關聯式容器也可以通過迭代器間接訪問每個元素,迭代器可以象徵性的看成是指標。map和其他能夠使用迭代器的容器一樣,它的迭代器是雙向的,我們可以從頭到尾(正向迭代),也可以從尾到頭(反向迭代)訪問每個資料。
#include<iterator>
map<int,float>::iterator iter; //對應迭代器物件
//正向間接訪問
for(iter=map_fir.begin();iter!=map_fir.end();iter++)
cout<<iter->first<<"="<<iter->second<<endl;
反向索引:
map<int,float>::reverse_iterator iter; //對應反向迭代器物件
//反向間接訪問
for(iter=map_fir.rbegin();iter!=map_fir.rend();iter++)
cout<<iter->first<<"="<<iter->second<<endl;
上面begin()指向的是map中首元素地址,而end()指的是集合中尾部資料的下一位地址。在反向迭代器操作中,rbegin()指向的是map尾部資料,而rend()指向第一個元素前面一個位置的元素(這個元素被認為是反轉後的尾部)。此外,切記上面反轉迭代也是iter++,而不是我們想的iter- -,這個過程map內部已經幫忙轉換。
2.7 刪除操作
map<int,float>::iterator iter;
iter = map_fir.find(1);
map_fir.erase(iter); // 迭代器刪除某一個鍵值對
int n = map_fir.erase(1); // 關鍵字刪除,如果刪除了會返回1,否則返回0
map_fir.erase(map_fir.begin(),map_fir.end()); // 成片刪除
2.8 其他常用操作
map<int,float> map_fir;
map_fir.swap(map_sed); // 交換所有資料,需要確保map中元素型別相同
map_fir.clear(); // 清空map_fir
map_fir.size(); // 統計map_fir中元素個數
map_fir.empty(); // 判斷map中是否為空,如果是空則返回1
3 小結
上面介紹了map資料結構特點以及STL中包含的介面。由於map和set一樣是基於紅黑樹構建的資料結構,所以其存取,訪問等時間複雜度都為O(logn),n為集合中元素的個數。
以上是個人學習記錄,由於能力和時間有限,如果有錯誤望讀者糾正,謝謝!
轉載請註明出處:http://blog.csdn.net/FX677588/article/details/76375350
相關文章
- 例說資料結構&STL(十一)——hash_map/unordered_map資料結構
- 例說資料結構&STL(十三)——pair資料結構AI
- 例說資料結構&STL(一)——vector資料結構
- 例說資料結構&STL(二)——list資料結構
- 例說資料結構&STL(三)——deque資料結構
- 例說資料結構&STL(四)——queue資料結構
- 例說資料結構&STL(五)——stack資料結構
- 例說資料結構&STL(六)——heap資料結構
- 例說資料結構&STL(八)——set資料結構
- 例說資料結構&STL(十二)——iterator資料結構
- 例說資料結構&STL(七)——priority_queue資料結構
- 例說資料結構&STL(十)——hash_set/unordered_set資料結構
- Map 資料結構資料結構
- STL:map用法總結
- Set和Map資料結構。資料結構
- js資料結構--字典(map)JS資料結構
- STL中經常使用資料結構資料結構
- C++ STL:std::unorderd_map 物理結構詳解C++
- ES6 Map 資料結構資料結構
- 【Go進階—資料結構】mapGo資料結構
- Redis基礎資料結構之MapRedis資料結構
- ECMAScript-新的資料結構Map資料結構
- go中map的資料結構理解Go資料結構
- ES6之Map資料結構資料結構
- Java資料結構之Map學習總結Java資料結構
- 資料結構第九節(排序(上))資料結構排序
- 理解 Golang 的 map 資料結構設計Golang資料結構
- Java常用資料結構之Map-HashMapJava資料結構HashMap
- 《大話資料結構》讀後總結(九)資料結構
- ES6之Set和Map資料結構資料結構
- 《STL原始碼剖析》-- stl_map.h原始碼
- 《STL原始碼剖析》-- stl_hash_map.h原始碼
- ES6的Set、Map資料結構 陣列資料結構陣列
- 傳說中的資料結構_JAVA資料結構Java
- 資料結構:線性表-例題資料結構
- [翻譯]map和reduce,處理資料結構的利器資料結構
- 【PG結構】Postgresql資料庫資料目錄說明SQL資料庫
- STL的map使用和分析