stl之順序容器學習筆記1

2021-05-23 05:30:16 字數 3832 閱讀 2169

初窺容器

容納特定型別物件的集合,稱為容器。

將單一型別的元素聚集起來成為容器,然後根據位置來儲存和訪問元素,稱為順序容器。順序容器的排列次序,按照元素新增到容器的次序決定。

stl定義了三種順序容器:

1、vector

2、list

3、deque

他們的差異在於訪問元素的方式,以及做新增、刪除元素時的執行代價不同。

1、vector擁有快速的隨機訪問能力(利用下標);快速的在容器尾部新增和刪除元素,但在其他位置插入和刪除元素,則會付出較多的代價。

2、list可在容器的任意位置插入或刪除元素,且高效。在元素訪問方面,只支援順序訪問而不支援隨機訪問(必須通過自增或自減迭代器)。

3、deque為雙端佇列,類似於vector,唯一不同的是可以快速在容器頭部或尾部插入或刪除元素。

iterator:迭代器,是一種型別,其作用是遍歷容器中的元素。所有的標準庫容器都定義了迭代器。

stl的迭代器支援解引用*(取指向的元素的值),自增++(指向下一元素),自減--(指向前一元素),相等==(如兩迭代器指向同一元素),不等!=運算子操作符。

舉個具體的示例,此示例實現了向容器中新增元素,並順序輸出元素。

vectorivec;//定義乙個vector容器,元素為int型

vector::iterator iter;//定義乙個vector型別的迭代器

int num;

while(num!=-1)

iter=ivec.begin();//將iter指向第乙個元素

for(;iter!=ivec.end();++iter)

{//iter不等於超出容器末端的第乙個元素時,即迴圈輸出

cout <<*iter 《當然以上程式若要正確編譯,還要包含相應的標頭檔案

#include

#include

#include

所有的容器都是類模板,在定義時,需提供相應的元素型別,如vector,可以把vector想象成乙個罐子,至於罐子中是放糖還是毒藥,由我們自己定義。

當然也可以定義。list,deque..所有的容器都帶有預設的建構函式,用於建立乙個空的容器物件。

容器的建構函式

除了預設建構函式外,stl容器提供了如下幾個建構函式,非常符合人們的思維方式:

1、cc;預設建構函式,用於建立乙個空的容器。

如:vectorivec;

2、cc1(c);使用c的副本初始化c1。c和c1必須具有相同的容器型別。適用於所有型別的容器。如:

vectorivec1;

....//向ivec1中加入元素

vectorivec2;

3、cc1(b,e);使用b,e迭代器之間的元素副本初始化c1。b標識了首複製元素,e標識了尾複製元素。適用於所有型別的容器。看以下示例

vectorivec;

vector::iterator iter_mid,iter;

....//向vector中增加元素

iter_mid=ivec.begin()+ivec.size()/2;

iter=ivec.begin();

listilist(iter,iter_mid);//利用vector的元素初始化list,完全可以,只要元素型別一致即可

4、cc(n,t);使用n個值為t的元素對c進行初始化,t的型別必須為t。只適用於順序容器。

如:int a=5;

vectorivec(10,a);

5、cc(n);建立可以容納n個t型別元素的容器,但不初始化元素。換句話說就是初始化容器的大小,但不初始化元素值。只適用於順序容器。

vectorivec(100);

容器元素的型別限制

容器元素的型別受以下兩個基本條件限制:

1、元素型別必須支援賦值操作。

2、元素型別的物件,必須可以複製。

考慮如下的例子:

如類foo沒有預設的建構函式,但有乙個需提供int型別形參的建構函式(foo(int a);)那麼

vectorfvec;//ok,構造了乙個空容器,不牽涉到元素初始化

vectorfvec(10);//error,構造可容納10個foo物件元素的容器,牽涉到元素建構函式,但未提供建構函式需要的引數

vectorfvec(10,1);//ok,構造乙個擁有10個1的容器,牽涉到元素的建構函式,也提供了建構函式需要的引數,可以成功初始化。

當然,我們可以定義容器的容器。

也就是說,可以定義乙個vector,其中的元素型別為vector。

vector< vector> ivvect;

注意以上定義,元素型別前後,必須加空格。否則會出現編譯錯誤,因為在std命名空間中有》操作符,會發生錯誤的引用。

迭代器詳述

前面初步描述了一下iterator迭代器型別,下面詳細論述。

迭代器的常用操作:

1、*iter:解引用,返回iter指向的元素的值。

2、iter->mem:先對iter進行解引用,然後獲取指定元素的mem成員。相當於(*iter).mem。

3、++iter/iter++:使iter指向下乙個元素。

4、--iter/iter--:使iter指向前乙個元素。

5、iter1==iter2/iter1!=iter2:兩迭代器指向同一元素時,則相等。需注意,兩迭代器指向超出末端的下乙個元素時,也相等。

vector和deque容器迭代器的額外操作

只有vector和deque提供容器迭代器的算術運算集合和關係運算集合(除==和!=)

1、iter+n/iter-n:將迭代器指向前面或後面的n個元素。新計算出的迭代器必須指向容器中的元素或超出容器末端的下一位置。

2、iter1+=iter2/iter-=iter2:迭代器加減法的符合運算;將iter1加上或減去lter2的運算結果,賦給iter1。

3、iter1-iter2:兩個迭代器的減法,其運算結果加上iter2即為iter1。這兩個迭代器必須指向同一容器中的元素或超出容器末端的下一位置。

4、>,>=,<,<=:關係操作符,比較的是迭代器在容器中的位置。如iter1指向的元素位於iter2的前面,則iter1關係操作符只適用於vector和deque,因為只有這兩種容器提供元素快速隨即訪問(通過元素位置,即下標)。

看乙個例子:

//取vector容器的中點

vector::iterator iter=ivec.begin()+ivec.size()/2-1;

listilist(ivec.begin(),ivec.end());

ilist.begin()+ilist.size()/2;//error,list沒有定義+操作

迭代器範圍

c++語言使用一對迭代器來標記迭代器範圍,這兩個迭代器指向了容器的元素或超出容器末端的第乙個元素(即最後乙個元素的下乙個位置),常用begin和end表示。

[begin,end)

標示從begin開始,end結束,但不包括end。

形成此種元素範圍的條件是:

1、兩個迭代器均指向容器中的元素或超出末端的下一位置。

2、如果這兩個迭代器不相等,則begin不斷自增的情況下,必定能begin=end。也就是說,end不可能出現在begin之前。

使用左閉合區間的意義:

1、當begin和end相等時,迭代器範圍為空。

2、當begin和end不相等時,範圍內至少有乙個元素,且begin指向該區間的第乙個元素。根據上面第二條,begin不斷自增,可以達到begin=end。

考慮以下的例子:

while(begin!=end)

//如果begin==end,(根據意義1)則說明迭代器範圍內沒有元素,則進入不了迴圈。(根據意義2)如begin!=end,則範圍內肯定有元素,可以安全的解引用。

++begin;

stl之順序容器學習筆記3

vector容器的自增長 概述vector物件為了支援快速隨機的訪問,將元素以連續的方式存放 與陣列相同 當我們向vector中新增乙個元素時,如果容器已經沒有空間容納新的元素,此時,由於元素必須連續存放以實現快速索引,所以不能在記憶體中隨便找個地方來儲存這個元素。於是,vector必須重新分配儲存...

stl之關聯容器學習筆記1

概述 stl定義了另一種容器,名曰關聯容器,關聯容器和順序容器的本質區別在於 關聯容器通過鍵key來儲存和讀取元素,而順序容器則通過元素在容器中的位置順序儲存和訪問元素。關聯容器的大部分行為與順序容器相同,但其獨特之處在於支援鍵的使用。stl提供了兩個基本的關聯容器 1 map 容器中以鍵值的形式來...

stl容器之順序容器

stl容器分為順序容器和關聯容器 其中順序容器最常用的由vector,list,queue 1.vector vector 向量容器,可以看作變長陣列,長度可根據需要自行變化。使用的標頭檔案 include 定義方式 vector陣列名 vectorar 訪問容器內資料的方式和普通陣列相同,可以用a...