STL容器用法與介紹之vector

2021-10-06 05:43:41 字數 3735 閱讀 1670

a) vector是乙個封裝了動態大小陣列的順序容器,並支援反轉;

b) vector是在堆上分配記憶體,並在記憶體中具有連續的儲存空間,它提供了自動記憶體管理功能,隨著元素的增加或刪除,記憶體會同步進行增大或縮小;

c) 訪問vector中的元素可以通過元素下標實現隨機訪問,也可以通過迭代器實現順序訪問;

d) 在vector尾部新增和刪除元素的時間複雜度是o(1),但是在vector頭部或中間插入和刪除元素的時間複雜度是o(n)。原因:由於vector的記憶體空間是連續的,所以在頭部和中間進行插入和刪除會造成記憶體塊的拷貝。如果vector記憶體空間不夠時,還需要重新申請一塊足夠大的記憶體再進行記憶體拷貝。如果vector中的元素是結構體或者類,對頭部和中間的元素進行插入刪除不僅需要拷貝記憶體塊,還會進行析構和構造操作。

優點:支援隨機儲存,查詢效率高;

缺點:在頭部和中間插入刪除元素需要移動記憶體,效率低;

使用場景:適用於元素結構簡單,變化小,並且頻繁隨機訪問但不需要對頭部和中間元素進行新增刪除操作的場景。

a) 建立物件與初始化

std::vectorvectest1; //vectest1是乙個空的vector,它潛在元素型別為t

std::vectorvectest2(vectest1); //vectest2中包含有vectest1中所有元素的副本

std::vectorvectest2 = vectest1; //與上式等價

std::vectorvectest3(n, val); //vectest3中包含了n個重複的元素,每個元素的值都是val

//以下為c++11新特性,使用之前請確認編譯器是否支援

std::vectorvectest4; //vectest4包含了初始值個數的元素,每個元素被賦予相應的初始值

std::vectorvectest4 = ; //與上式等價

b) 增加元素

std::vectorvectest1 = ;

std::vectorvectest2 = ;

vectest1.push_back(6); //在vector尾部增加乙個元素6

vectest1.insert(vectest1.begin(), 6); //在vector頭部增加乙個元素6

vectest1.insert(vectest1.end(), 5, 6); //在vector尾部增加5個相同的元素6

vectest1.insert(vectest1.begin(), vectest2.begin(), vectest2.end()); //在vectest1的頭部插入vectest2[first, last)間的元素

vectest1.emplace_back(6); //在vector尾部增加乙個元素6

push_back/insert/emplace_back之間的區別:

push_back把元素插入容器的末尾,insert把元素插入任何指定的位置。不過push_back速度一般比insert快。如果能用push_back盡量先用push_back。emplace_back是在c++11標準中引入的。它的用法與完成的動作與push_back完全相同,但它們的實現不一樣。使用push_back時,首先會呼叫建構函式構造這個臨時物件,然後需要呼叫拷貝建構函式,將這個臨時物件放入容器中,最後將這個臨時變數釋放;使用emplace_back時,因為輸入的是元素引用,只需要在新增元素的時候構造一次即可,不需要觸發拷貝構造和轉移構造。

c) 刪除元素

std:vectorvectest2 = ;

vectest1.erase(vectest1.begin() + 2); //刪除第3個元素

vectest1.erase(vectest1.begin() + i, vectest1.begin() + j); //刪除區間[i, j - 1]之間的元素

vectest1.pop_back(); //刪除vector尾部的元素,使用之前需要進行非空判斷

vectest1.clear(); //清空所有元素

d) 訪問元素

std::vectorvectest1 = ;

int ivalue1 = vectest1[0]; //返回下標為0的元素引用

int ivalue2 = vectest1.at(0); //與上式相同,如果下標不存在,會丟擲out_of_range的異常,建議使用

int ivalue3 = vectest1.front(); //返回vector頭部元素的引用,使用前需要進行非空判斷

int ivalue4 = vectest1.back(); //返回vector尾部元素的引用,使用前需要進行非空判斷

for (std::vector::iterator iter = vectest1.begin(); iter != vectest1.end(); ++iter)

e) 替換元素

std::vectorvectest1 = ;

std::vectorvectest2 = ;

vectest1.assign(); //相當於賦值操作,c++11新特性,使用之前請確認編譯器是否支援

vectest1.assign(5, 3); //與上式類似,用5個3對vectest1進行賦值

vectest1.assign(vectest2.begin(), vectest2.begin() + i); //使用vectest2中[0, i - 1]區間的元素對vectest1進行賦值

vectest1.swap(vectest2); //交換vectest1和vectest2中的元素

f) 元素反轉

//需要標頭檔案#includestd::reverse(vectest1.begin(), vectest1.end());
g) 元素排序

//需要標頭檔案#includestd::sort(vectest1.begin(), vectest1.end()); //預設按公升序排列

bool comp(const int& a, const int& b) //自定義排序比較函式

std::sort(vectest1.begin(), vectest1.end(), comp); //按自定義排序比較函式降序排列

h) 元素唯一

//需要標頭檔案#include//結合使用std::sort/std::unique/erase

std::vectorvectest1 = ;

std::sort(vectest1.begin(), vectest1.end());

vectest1.erase(std::unique(vectest1.begin(), vectest1.end()), vectest1.end());

i) 元素與指標結合使用

我們有時候會用智慧型指標來表示二級指標(指向指標的指標),實現指標的自動管理,防止記憶體洩漏。

int** ptr = new int*[isize];

for (int i = 0; i < isize; ++i)

std::vector> vecsubtest; //增加智慧型指標的引用計數,防止智慧型指標提前釋放

std::unique_ptruptest(new int*[isize]);

for (int i = 0; i < isize; ++i)

在上例中ptr是和uptest.get()是等價的。

STL容器和迭代器用法歸納(1)

在我所看到的介紹stl的幾本書和文章裡。開頭總要說stl能節省大量的時間和精力,但很多c 程式設計師確不知道,不會用,或不願意用,因為覺得stl不好理解,不好用,複雜。可能也正如這些書中所說,我也經歷過從不用到用的過程,而我身邊也有人還沒有使用stl。但其實只要我們需要儲存資訊,然後查詢這些資訊並使...

STL容器之stack與queue用法

目錄 一 棧的概念 二 棧的構造與常用介面 三 佇列的概念 四 佇列的構造與常用介面 棧的儲存規則是先進後出 filo 可以同vector deque一樣可以儲存任意一種資料型別的資料元素,它只有乙個出口,而且它只能訪問棧頂的元素,不允許遍歷操作,需要獲取棧裡的元素,則需要乙個個將棧頂的元素移出。1...

STL容器之set用法

目錄 一 set容器概念 二 set構造和基本函式介面 三 統計和查詢 set是一種關聯式容器,底層是通過平衡二叉樹 紅黑樹 實現的,插入 刪除和查詢效率都非常高,所有元素插入容器中,會被預設以公升序的形式進行排序,而且不允許插入已經存在且相同的資料元素。此外還有乙個multiset容器,它的底層實...