STL中map和set
C++11才開始支援括號初始化!!!
關於STL中的map和set
首先來看一下關聯容器吧
關聯容器迭代器:map的value_type是pair<const key_type, mapped_type>,所以map迭代器只能改變關鍵字對映的值(mapped_type),不能修改關鍵字;set的value_type等於key_type,都是const關鍵字,不能修改。
關於其中的幾點性質:
1.map使用鍵值對的方式來儲存資料,鍵不能有重複的,值可以重複,map使用鍵來儲存資料,系統會根據鍵來自動將資料排序;set鍵不能有重複,使用鍵來儲存資料,系統會根據該值來自動將資料排序
2.C++STL中map,set的底層實現全是用的紅黑樹,而且關鍵字都不能重複,而multimap和multiset關鍵字可以重複。(紅黑樹:實際上是AVL的一種變形,但是其比AVL(平衡二叉搜尋樹)具有更高的插入效率,當然查詢效率會平衡二叉樹稍微低一點點,畢竟平衡二叉樹太完美了。但是這種查詢效率的損失是非常值得的。它的操作有著良好的最壞情況執行時間,並且在實踐中是高效的: 它可以在O(log n)時間內做查詢,插入和刪除,這裡的n是樹中元素的數目。)
另外,比如:map採用紅黑樹實現,比hash_map(未進入stl)穩定,但是一般沒有hash_map快。
3.資料結構的的穩定與非穩定的是根據排序移動後原來在前面的邏輯位置仍然在前面保持不變的,所以map和set是穩定排序,multimap和multiset不穩定。
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
兩者的新增元素都可以用insert,只不過map的資料是pair對,而set是單值,那特殊的一點是map的下標操作
map下標操作(只能用於map(有序)和unorders_map(無序)):返回mapped_type(關鍵字對映的值),解引用返回value_type(即pair<const key_type, mapped_type>);若關鍵字還不存在,會建立一個對應關鍵字且值為0的新元素,已存在則返回最近一次賦的值。
只有map有下標,set型別沒有是因為人家就一個鍵,沒有值,而multimap沒有是因為可能有多個值跟同一個鍵相關。
舉例:
map<string, size_t> word_count;
word_count["Anna"] = 1;
這樣等價於把{“Anna”, 1}插入了。 由於下標運算子可能插入新元素,所以我們只能對非const的map使用下標操作。
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
那麼關於有序map和無序unordered_map
無序容器是雜湊表實現的,無序容器查詢的時間複雜度可達到O(常數),記憶體消耗在於雜湊表;而有序容器是紅黑樹實現的,查詢的時間複雜度為log(n),但記憶體佔用通常會少點。
map:map內部實現了一個紅黑樹(紅黑樹是非嚴格平衡二叉搜尋樹,而AVL是嚴格平衡二叉搜尋樹),紅黑樹具有自動排序的功能,因此map內部的所有元素都是有序的,紅黑樹的每一個節點都代表著map的一個元素。因此,對於map進行的查詢,刪除,新增等一系列的操作都相當於是對紅黑樹進行的操作。map中的元素是按照二叉搜尋樹(又名二叉查詢樹、二叉排序樹,特點就是左子樹上所有節點的鍵值都小於根節點的鍵值,右子樹所有節點的鍵值都大於根節點的鍵值)儲存的,使用中序遍歷可將鍵值按照從小到大遍歷出來。
unordered_map: unordered_map內部實現了一個雜湊表(也叫散列表,通過把關鍵碼值對映到Hash表中一個位置來訪問記錄,查詢的時間複雜度可達到O(1),其在海量資料處理中有著廣泛應用)。因此,其元素的排列順序是無序的。
優缺點:
map:
優點:有序性,這是map結構最大的優點,其元素的有序性在很多應用中都會簡化很多的操作紅黑樹,內部實現一個紅黑書使得map的很多操作在lgn的時間複雜度下就可以實現,因此效率非常的高
缺點:空間佔用率高,因為map內部實現了紅黑樹,雖然提高了執行效率,但是因為每一個節點都需要額外儲存父節點、孩子節點和紅/黑性質,使得每一個節點都佔用大量的空間
適用處:對於那些有順序要求的問題,用map會更高效一些
unordered_map:
優點:因為內部實現了雜湊表,因此其查詢速度非常的快
缺點:雜湊表的建立比較耗費時間
適用處:對於查詢問題,unordered_map會更加高效一些,因此遇到查詢問題,常會考慮一下用unordered_map
總結:
1.記憶體佔有率的問題就轉化成紅黑樹 VS hash表 , 還是unorder_map佔用的記憶體要高。
2.但是unordered_map執行效率要比map高很多
3.對於unordered_map或unordered_set容器,其遍歷順序與建立該容器時輸入的順序不一定相同,因為遍歷是按照雜湊表從前往後依次遍歷的
參考:
https://blog.csdn.net/BillCYJ/article/details/78985895
https://blog.csdn.net/billcyj/article/details/78065438