C 基礎 04 vector詳解

2022-09-04 08:30:14 字數 4472 閱讀 8400

按照寫部落格的習慣一開始總要加點雞湯文什麼的,請原諒我今天想不起來。

*********************************************

今天要寫的內容是順序型容器。首先,標準庫定義了三種順序容器型別:vector,list和deque(雙端佇列),這篇部落格介紹的是vector容器。

首先要知道,vector不是一種資料型別,而是乙個類模板,可以用來定義任意多種資料型別,比如說vector是一種資料型別,vector也是一種資料型別。使用vector之前我們要先包含標頭檔案

#includeusing std::vector;

vectorv1;       //初始化乙個為空的vector

vectorv2(v1); //v2是v1的乙個副本

vectorv3(n,i); //n個值為i的vector

vectorv4(n); //v4含n個預設初始化值的vector(如int預設0,string預設"")

每個標準庫容器型別都定義了名為iterator的成員,也就是迭代器,迭代器所指向的型別為vector容器中實際儲存的型別,比如

vectoriterator iter;
迭代器常用於遍歷容器,最常見的便是begin和end操作,vector.begin()返回vector中的第乙個元素,vector.end()返回末端元素的下乙個。

vectorivec;

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

ivec.push_back(i);

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

需要注意的是,如果有元素新增或者刪除,會使迭代器失效,從而需要調整迭代器的值。否則很可能會導致執行時崩潰,者點很重要。

新增:需要注意的是新增新元素可能會使迭代器失效,所以程式需要保證迭代器在插入或者push操作後能得到更新。

//新增元素

v.push_back(t); //在vector尾部新增乙個元素t

v.insert(iter,t); //在迭代器iter所指向的元素前面插入元素t,返回新新增的元素的迭代器

v.insert(iter,n,t); //在迭代器iter所指向的元素前面插入n個元素t,返回void

v.insert(iter,iter1,iter2); //在迭代器iter所指向的元素前面插入迭代器[iter1,iter2)之間的元素(左閉右開),返回void

所有容器型別都支援關係操作符來比較大小,規則是:

//v1和v2長度和所有元素都相等,則v1=v2,否則不等。

//v1長度小於v2,但是v1所有元素和v2 相等,則 v1 < v2。

//v1和v2元素不等,則比較結果取決於第乙個不相等的元素。

vector大小的操作:

v.size();      //返回v中元素的個數,返回型別 v::size_type

v.max_size(); //返回v可容納最多元素個數

v.empty(); //判斷是否為空

v.resize(n); //調整v長度大小,使其能容納n個元素,如果nvector訪問:

v.back(); //返回v最後乙個元素的引用

v.front(); //返回v第乙個元素的引用

v[n]; //返回v下標為n的引用

v.at[n]; //返回v下標為n的引用

//返回的是引用,注意和迭代器的區別,迭代器返回的是指標

vectorv;

//迭代器

vector::iterator iter = v.begin();

//引用,下面val = val2

vector::reference val = v.front();

vector::reference val2 = *v.begin();

vector刪除操作:

v.erase(iter);        //刪除iter所指向的元素,返回iter下乙個元素

v.erase(iter1,iter2); //刪除[iter1,iter2)之間的元素(左閉右開)

v.clear(); //全刪,返回void

v.pop_back(); //刪除最後乙個,返回void

賦值操作:

v1 = v2;                //複製v2到v1

v1.swap(v2); //交換內容:交換v1和v2之間的元素,速度比v2複製到v1快

v1.assign(iter1,iter2); //重新設定:將[iter1,iter2)之間的元素(左閉右開)複製到v中

v1.assign(n,t); //重新設定:將v中重新設定為n個值為t的元素

注意swap不會使迭代器失效。

assign會將vector中所有元素刪除,然後再插入新元素。assing可以用於:相同或者不同的容器內,元素型別不同但是相互相容之間的轉換賦值。(比如vector和list之間的賦值)

vectorv1;

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

v1.push_back("dddd");

listlist1;

list1.assign(v1.begin(),b1.end());

首先要明白vector容器的元素在記憶體中是以連續的方式存放。想一下如果新增新元素的時候時候已經沒有空間來容納新元素,又不能隨便找個地兒來放新元素,所以需要重新分配vector的儲存空間:copy舊元素到新儲存空間,插入新元素,刪除舊儲存空間。

如果vector在每次新增新元素的時候都這麼搞乙個,那效率何在?所以,顯然vector設計的時候也考慮到這方面的問題,作者使用的記憶體分配策略是:以最小的代價連續儲存元素。用通俗大大白話來講,就是每次分配的時候會比你當前所需要的空間多一些,當已經分配的空間使用完後才會開闢新的空間。

首先來看一下capacity和reserve操作

v.size();     //返回vector中元素的個數

v.capacity(); //返回vector能夠儲存的元素總數

v.reserve(n); //手動設定vector容器應該預留n個元素的空間

舉乙個簡單的例子來說明他們之間的關係:

vectorv;

cout<<"vector size:"《明白了吧,capacity總是要大於或等於size的,至於為什麼是32?因為每當vector不得不分配新的儲存空間時,會以加倍當前容量 的分配策略來重新分配。比如你新增1個元素,size為1,capacity也為1,然後再新增,capacity 乘2,然後再新增再乘2,如下:

//新增的時候size和capacity的關係:

—— v.capacity()

0 - 0

1 - 1

2 - 2

3 - 4

4 - 4

5 - 8

9 - 16

以此類推...

或者我們可以自己設定預留空間,修改上面的例子:

vectorv;

v.reserve(50);

cout<<"vector size:"<

vector:優點:快速隨機訪問缺點:在容器任意位置插入或刪除,比在容器尾部插入或刪除,開銷大。

list:是不連續儲存的,優點:在容器中任何位置高效的插入和刪除元素。缺點:不支援隨機訪問,訪問元素需要遍歷其他元素。

deuqe :擁有更複雜的資料結構,優點:從容器兩端插入和刪除都非常快,支援高效隨機訪問。缺點:在中間插入或刪除效率很低。

(1)需要高效隨機訪問元素,則使用vector或者deque。

(2)需要高效在容器中間位置插入或者刪除元素,則使用list。

(3)若不是在中間位置插入,而是容器首部或者尾部插入,則使用deque。

(4)若既需要高效隨機訪問又需要高效中間插入,則可以將元素新增到list中然後排序啥的,再複製到vector中。

再不睡覺就作死了。。

C 基礎04 vector型別

vector可以把若干物件裝進來,也被稱為容器。1.1 容器中常見存放的型別 include using namespace std include class student int main 2.1 利用拷貝方式初始化int main 2.2 列表初始化int main vector int v...

C 基礎 04 標準庫vector型別

include using std vector vector不是一種資料型別,而只是乙個類模版,可用來定義任意多種資料型別。定義及初始化 vector儲存型別為t的物件。預設建構函式v1為空 vectorv1 v2是v1的乙個副本 vectorv2 v1 v3包含n個值為i的元素 vectorv3...

C 基礎 vector 向量

vector 是序列式容器 sequence containers 中的一種,是乙個封存了動態大小陣列的順序容器。可以簡單的認為,vector就是能夠存放任意資料的動態陣列,隨著元素的加入,它的內部機制會自行擴充空間以容納新元素。線性連續空間,兩個迭代器start和finish分別指向配置得來的連續...