正文
容器是一種容納特定型別物件的集合。c++的容器可以分為兩類:順序容器和關聯容器。順序容器的元素排列和元素值大小無關,而是由元素新增到容器中的次序決定的。標準庫定義了三種順序容器的型別:vector、list和deque(雙端佇列)。此外,標準庫還提供了三種容器介面卡:stack、queue和prioroty_queue型別。介面卡是根據原始的容器型別所提供的操作,通過定義新的操作介面,來適應基礎的容器型別。
順序容器vector 支援快速隨機訪問
list 支援快速插入/刪除
deque 雙端佇列
順序容器介面卡
stack 後進先出(lifo)棧
queue 先進先出(fifo)佇列
priority_queue 有優先順序管理的佇列
#include#include#include
所有容器都定義了預設建構函式,可以用預設建構函式來初始化乙個空的容器物件,如下
list ilist;
此外,容器還有幾種建構函式,可以用來初始化容器物件,如下:
cc 建立乙個名為c的空容器。c是容器名,t是元素型別。適用於所有容器c c(c2) 建立容器c2的副本c。兩者必須是相同型別的容器和元素。適用於所有容器
c c(b,e) 建立c,其元素是迭代器b和e標記範圍內元素的副本。適用於所有容器
c c(n,t) 用n個值為t的元素建立c,其中t必須是容器型別c的元素型別的值或者是可以轉化為該型別的值。只適用於順序容器
c c(n) 建立n個初始化元素的容器c。只適用於順序容器
值得注意到是,接受容器大小做形參的建構函式只適用於順序容器,不適用於關聯容器。由於指標就是迭代器,因此我們還可以通過使用內建陣列中的一對指標初始化容器:
char *words=;size_t words_size=sizeof(words)/sizeof(char *);
//使用整個陣列初始化words2
list words2(words,words+words_size);
前面我們說過,容器是儲存某中型別元素的集合,所以可以定義元素是容器型別的容器。例如,可以定義vector型別的容器ivec,其元素為string型別的vector。但是注意,在指定容器元素為容器型別時,必須使用如下空格:
ector< vector > ivec; //合法。在兩個》之間有空格
vectorstring>> ivec; //
錯誤。在兩個》之間沒有空格,>>會導致歧義
順序容器內建了一些有用的操作:(1)在容器中新增元素;(2)在容器中刪除元素;(3)設定容器大小;(4)(如果有的話)獲取容器內的第乙個和最後乙個元素。
begin和end操作產生指向容器內第乙個元素和最後乙個元素的下一位置的迭代器。此外還有逆序迭代器(逆序迭代器從後向前遍歷容器,並反轉了某些相關的迭代器操作)rbegin和rend。如下:
c.begin() 返回乙個迭代器,它指向容器c的第乙個元素c.end() 返回乙個迭代器,它指向容器c的最後乙個元素的下乙個位置
c.rbegin() 返回乙個逆序迭代器,它指向容器c的最後乙個元素
c.rend() 返回乙個逆序迭代器,它指向容器c的第乙個元素的前乙個位置
下表為在順序表中新增元素的操作。注意其中的適用範圍和返回型別。
c.push_back() 在容器c的尾部新增值為t的元素。返回void型別c.push_front(t) 在容器c的前端新增值為t的元素。返回void型別。只適用於list和deque容器型別
c.insert(p,t) 在迭代器p所指向的元素前面插入值為t的新元素。返回指向新新增元素的迭代器
c.insert(p,n,t) 在迭代器p所指向的元素前面插入n個值為t的新元素。返回void型別
c.insert(p,b,e) 在迭代器p所指向的元素前面插入由迭代器b和e標記的範圍內的元素。返回void型別
其中push_front只適用於list和deque容器型別,這個操作實現在首部插入新元素的功能。
//用push_front在容器尾部依次新增0,1,2,3
listilist;
for(size_t i=0;i!=4;++i)
ilist.push_front(i);
//ilist內元素序列為:3,2,1,0
需要注意的是,任何insert或push操作都可以導致迭代器失效。所以在編寫迴圈將元素插入到vector和deque容器中時,程式必須確保迭代器在每次迴圈後都得到更新。
vectorivec;vector
::iterator iter=ivec.begin();
while(cin>>word)
iter=ivec.insert(iter,word); //
insert(iter,word)返回指向新新增元素的迭代器
//以下是錯誤的,因為此時iter已經失效
vectorivec;
vector
::iterator iter=ivec.begin();
while(cin>>word)
ivec.insert(iter,word);
//錯誤,經過一輪的insert後iter即失效,不能再呼叫
所有容器都提供以下與容器大小相關的操作。注意resize操作可能會使迭代器失效。
c.size() 返回容器c中元素的個數。返回型別為c::size_typec.max_size() 返回容器c可以容納的最多的元素個數.返回型別為c::size_type
c.empty() 返回標記容器大小是否為0的布林值
c.resize(n) 調整容器c的長度大小,使其能容納n個元素。如果n
c.resize(n,t) 調整容器c的大小,使其能容納n個元素。所有新新增的元素值為t
在vector和deque容器上做resize操作有可能會使其所有迭代器都失效。對於所有的容器型別,如果resize操作壓縮了容器,則指向已刪除的元素的迭代器會失效。
以下為訪問容器元素的操作。注意·使用越界的下標,或呼叫空容器的front或back函式,都會導致程式出現嚴重的錯誤。
c.back() 返回容器c的最後乙個元素的引用。如果c為空,則該操作未定義c.front() 返回容器c的第乙個元素的引用。如果c為空,則該操作未定義
c[n] 返回下標為n的元素的引用。如果n
<0或n>=c.size(),則該操作未定義。只適用於vector和deque容器
c.at(n) 返回下標為n的元素的引用。如果下標越界,則該操作未定義。只適用於vector和deque容器
以下為刪除容器元素的操作。刪除操作會使一些迭代器失效,需要特別注意。下表第乙個操作在刪除元素前,必須保證迭代器不是指向end的迭代器。
c.erase(p) 刪除迭代器p指向的元素。返回乙個迭代器,它指向被刪除元素後面的元素。如果p指向容器內最後乙個元素,則返回的迭代器指向容器的超出末端的下一位置。如果p本身就是超出容器末端的下乙個位置,則該函式未定義
c.erase(b,e) 刪除迭代器b和e所標記的範圍內所有元素。返回乙個迭代器,它指向被刪除元素段後面的元素。如果e本身就是指向超出容器末端的下乙個位置,
則返回的迭代器也指向容器末端的下乙個位置
c.clear() 刪除容器c內的所有元素。返回void
c.pop_back() 刪除容器c的最後乙個元素。返回void。如果容器為空,則該函式未定義
c.pop_front() 刪除容器c的第乙個元素。婦女會void。如果容器為空,則該函式未定義。只適用於list和deque容器
下表為順序容器的賦值操作。賦值後左右兩邊容器相等,儘管賦值之前兩個容器的大小不同,但賦值之後兩個容器的長度都為右運算元的長度。
c1=c2 刪除容器c1的所有元素,然後將c2的元素複製給c1。c1和c2的型別必須相同c1.swap(c2) 交換c1和c2的內容,c1和c2的型別必須相同。其效率比把c2元素複製到c1中要高
c.assign(b,e) 重新設定c的元素:將迭代器b和e標記範圍內的元素複製到c中。b和e必須不是指向c中元素的迭代器
c.assign(n,t) 將容器c重新設定為儲存n個值為t的元素
參考:
C 標準庫順序容器知識點總結
c 具有內建資料結構,但為了更好的滿足開發者的需求,c 標準庫提供了多種容器來供程式設計師呼叫,本篇部落格主要是順序容器的相關知識點總結 在c 中,容器主要是一些特定型別的集合,順序容器為程式設計師提供儲存和順序訪問的能力,主要的容器型別有vector deque list forward list...
C 順序容器
一 順序容器型別 順序容器 vector list deque 介面卡 stack queue priority queue 使用這些容器都必須使用相應的標頭檔案 二 容器元素初始化 cc 建立乙個名為c的空容器 cc c2 建立容器c2的副本 cc b,e 建立c,其元素是迭代器b和e的範圍內的副...
C 順序容器
1 概述 乙個容器就是一些特定型別物件的集合。順序容器型別 描述vector 可變大小陣列,支援快速訪問,在尾部之外的地方插入或刪除時可能很慢 deque 雙端佇列。支援快速訪問,在頭尾插入刪除會很快。list 雙向列表。只支援雙向順序訪問。插入刪除很快 forward list 單向列表。只支援單...