容器用於儲存一組相同型別元素,因此乙個容器可以看作是一類資料的集合。容器按其對元素的管理形式分為值容器和引用容器兩種型別。值容器裡,插入乙個元素時,容器儲存的是乙個元素的副本,而引用型別容器則是儲存該元素的引用或者位址。值容器可以簡單的模擬引用容器,只需要把元素型別定義為指標就可以了,因此值容器更為通用。c++標準庫里所有的容器都是值容器。
容器按型別分類包括有序和無序兩種。標準庫的有序容器包括set、map、multiset、multimap四類,這類容器內部的元素始終是有序的,容器內部預設使用『<』操作符完成元素大小的比較,使用者也可以提供自己的元素大小比較函式。這類容器增加元素只提供了insert操作,插入的元素由容器按其大小自動放到合適的位置。
無序容器即內部元素是沒有排序的,但也不是亂序的,元素的順序為元素加入容器中的順序。這類容器包括vector、list、deque三類。這類容器提供了push_back和push_front操作,即在尾部或者是頭部插入元素,insert操作可以在容器指定的位置插入元素。
還有一種是容器介面卡,比如stack、queue,可以從上面的無序容器適配出相關的介面。
以上就是標準庫包含的基本容器型別,由於時間的關係,標準庫還沒有提供hash表的實現,但會在未來的擴充套件裡增加。
不同容器雖然實現的方式差別很大,但都提供了相同或相似的介面,因此如何根據使用場景選擇合適的容器型別是很重要的。這就需要我們稍微了解一下容器的底層實現細節:
總結如下:
是否連續記憶體
支援頭部插入或刪除元素
支援中間插入或刪除元素
支援隨機訪問
vector是否
是(效率低)
是list否是
是(效率很高)
否deque
塊內連續
是是(效率高)
是需要說明的是,支援隨機訪問的容器就可以用標準庫的快速排序演算法std::sort進行排序。
根據容器的這些基本特性,我們就可以在具體的應用中選擇合適的容器了。vector占用記憶體少,並且和c的陣列相容,支援隨機訪問,因此訪問vector中間某個元素效率很高,但從vector的頭部或中間插入或刪除元素效率最低,因此對於不需要頻繁的從中間插入刪除資料的應用,應該優先使用vector。
如果元素個數比較多,並且需要從中間插入刪除元素,又能快速訪問到中間元素,則應該選用deque。
list從中間增加刪除元素效率很高,但如果訪問中間的某個元素必須從煉表頭開始遍歷,因此對於需要頻繁增加和刪除中間元素的應用,應該選擇list。
如果是需要元素能自動排序,則選擇set或map。
使用例子:
std::vectorovec; //定義乙個元素為int型別的陣列
for (inti=0; i<10; ++i) //插入10個元素
//遍歷並列印所有元素,(方法1)
for (intj=0; j::iterator it = ovec.begin();
for (; it!= ovec.end(); ++it)
ovec.pop_back();//刪除vector中最後乙個元素
list用法:
std::listolist;
//在底部增加或刪除元素操作同vector,遍歷操作只支援vector裡的方法2,不支援方法1
olist.remove(5);//刪除list中值為5的元素
std::list::iteratorit = olist.begin();
std::advance(it,4); //獲取指向第5個元素的迭代器
it = olist.erase(it);//刪除第5個元素並獲取下乙個元素
olist.insert(it,4); //在第5個元素前重新插入元素4
std::listolist2;
olist2.push_front(10);//list頭上增加乙個元素
olist2.splice(olist2.begin(),olist) //將olist的所有元素加入到olist2的前面,由於是直接將olist的節點掛過來,所以效率很高,***是olist鍊錶被清空了。
deque元素快速排序:
std::dequeodeque;
//deque的操作同vector
//快速排序deque內的元素
std::sort(odeque.begin(), odeque.end());
所有的容器型別都支援乙個無異常的資料交換操作swap:
std::listlist1;
std::listlist2;
//swap成員函式通過交換內部資料指標來完成操作,不涉及任何記憶體分配或複製,
//因此所有的標準庫容器都保證該操作是無異常的,即永遠不會失敗。
list1.swap(list2);
另外容器提供的成員函式可能功能上和標準演算法有重疊,比如查詢元素的操作,可以使用標準演算法查詢:
std::setoset;
for (inti=0; i<10; ++i)
std::set::iteratorit = std::find(oset.begin(), oset.end(), 1);
也可以用成員函式:
std::set::iteratorit = oset.find(1);
上面兩種實現是不一樣的,成員函式更高效,表達也更簡潔,標準庫演算法是根據迭代器進行線性查詢,而set的find方法則是從二叉樹進行查詢,效率更高,所以對於實現同乙個功能,應該優先使用成員函式。
C STL標準庫容器 概覽
本文對c 中的stl標準庫容器進行概覽,作為筆者平時的學習筆記,以茲備忘。同時,本文作為乙個目錄,接下來對常用容器,比如vector,map等的 具體介紹的博文將會由本文進行索引。c 的標準容器庫中提供了一系列的容器模版,可以作為日常工作生產中的資料結構使用,以此減少了程式設計師很多去造輪子的工作量...
c 標準庫 容器類
容器類可以分為兩大類和容器介面卡 1 序列容器 sequence containers 這種容器中的元素是有序的,每乙個元素在容器中都有乙個確切的位置,這個位置不依賴於元素的值,而是跟放入容器的時機有關。標準的序列容器有三個 vector,deque,list。另外你也可以把字串 string 和陣...
C 標準庫容器 Map
本部落格主要簡述了c 標準庫容器map的一些特性 map 的定義及特性 乙個map就是乙個 關鍵碼,值 對偶的序列,它提供基於關鍵碼的快速提取操作。每個關鍵碼至多保持乙個值,換句話說,map中的關鍵碼具有唯一性。簡單來說,map提供了乙個對映關係來查詢元素。map的部分成員 成員定義備註 key關鍵...