vector容器

一、vector

(1)定義

vector是C++標準模板庫中的部份內容,它是一個多功能的,可以操做多種數據結構和算法的模板類和函數庫。算法

vector之因此被認爲是一個容器,是由於它可以像容器同樣存放各類類型的對象,簡單地說,vector是一個可以存聽任意類型的動態數組,可以增長和壓縮數據編程

(2)底層實現

在內存中分派一塊連續的內存空間進行存儲。支持不指定vector大小的存儲數組

STL內部實現時,首先分配一個很是大的內存空間預備進行存儲,即capacity()函數返回的大小,當超過度配的空間時再總體從新分配一塊內存存儲,這給人以vector能夠不指定vector即一個連續內存的大小的感受(其實是對於大數據存儲是自動從新分配了)。一般默認的內存分配能完成大部分狀況下的存儲。數據結構

不少時候咱們沒必要要知道vector裏面有多少數據,vector裏面的數據是動態分配的,使用push_back()的一系列分配空間經常決定於文件或一些數據源。若是你想知道vector存放了多少數據,你可使用empty()。獲取vector的大小,可使用size()。數據結構和算法

例如,若是你想獲取一個vectorv的大小,但不知道它是否爲空,或者已經包含了數據,若是爲空想設置爲-1,你可使用下面的代碼實現:函數

int nSize = v.empty() ? -1 : static_cast<int>(v.size());

(3)使用 

爲了可使用vector,必須在你的頭文件中包含下面的代碼:大數據

#include <vector>

vector屬於std命名域的,所以須要經過命名限定,以下完成你的代碼:
spa

using std::vector;
vector<int> vInts;

或者連在一塊兒,使用全名:code

std::vector<int> vInts;

建議使用全局的命名域方式:orm

using namespace std;

(4)特色

優勢:(1)隨機存取,即[]操做和vector.at();

          (2)動態操做,push_back()與pop_back();

          (3)自動調整內存,節省空間。

缺點:(1)實現插入與刪除操做效率低;

          (2)只能在尾部插入與刪除,在頭部插入與刪除消耗時間規模與容器大小成正比;

          (3)當動態添加的數據超過默認內存大小時,要進行總體的從新分配,拷貝與釋放。

(5)vector VS 數組

數組:

分配的是靜態空間,通常分配了就不能夠改變,就像咱們熟知的定義了一個數組,那麼數組的長度就不能夠改變了。

不能夠進行越界訪問,可是編譯器不檢查越界,這一點在咱們編程的時候要尤其注意(常見錯誤!)。通常申請的數組長度不能知足咱們的要求了,咱們要從新申請大一點數組,而後把原數組中數據複製過來。

vector:

分配的是動態空間,即:咱們發如今聲明vector容器的時候也能夠不指定容器的大小,vector是隨着元素的加入,空間自動擴展的。

可是,咱們必需要負責任的確定vector分配的空間是連續的,也就是支持數組中的下標隨機訪問,實際上vector的實現機制是:預留一部分空間,並且預留空間的大小是按必定比率增加的,若是空間不夠用的話,要保證連續,就必須從新new一片空間,而後將原有元素移動到新空間,同時預留新的空間(而且新分配的空間比原來分配的空間),最後將原來的那部分空間釋放掉。這樣預留空間的好處就是不用每次向vector中加元素都從新分配空間。

二、vector成員函數

(1)構造函數、析構函數

/*建立與銷燬*/
vector<Elem> c
//建立一個空的vector。
vector <Elem> c1(c2)
//複製一個vector。
vector <Elem> c(n)
//建立一個vector,含有n個數據,數據均已缺省構造產生。
vector <Elem> c(n, elem)
//建立一個含有n個elem拷貝的vector。
vector <Elem> c(beg,end)
//建立一個以[beg;end)區間的vector。
c.~ vector <Elem>()
//銷燬全部數據,釋放內存。

示例:

vector<Widget> vWidgets(500);
//建立一個包含500個Widget類型數據的vector:
vector<Widget> vWidgets(500, Widget(0));
//建立一個包含500個Widget類型數據的vector,而且都初始化爲0:
vector<Widget> vWidgetsFromAnother(vWidgets);
//建立一個Widget的拷貝

(2)賦值操做

/*賦值操做*/
c.assign(beg,end)
//將[beg; end)區間中的數據賦值給c
c.assign(n,elem)
//將n個elem的拷貝賦值給c

示例:

vector<int> v1,v2;
v1.push_back(10);
v1.push_back(20);
v2.push_back(30);
v2.assign(v1.begin(),v1.end());
vector<int> v;
v.assign(5,10);//往v裏放5個10

(3)插入操做

/*插入操做*/
c.insert(pos,elem)
//在pos位置插入一個elem拷貝,傳回新數據位置/返回插入的值的迭代器。
c.insert(pos,n,elem)
//在pos位置插入n個elem數據。無返回值。
c.insert(pos,beg,end)
//在pos位置插入在[beg,end)區間的數據。無返回值。

c.push_back(elem)
//在尾部加入一個數據。
//vector添加數據的缺省方法是push_back()

示例:

vector<int> v;
v.insert(v.begin(),10);
v.insert(v.begin(),2,20);
v.insert(v.begin(),v1.begin(),v1.begin()+2);
vector<int> v;
v.push_back(1);
v.push_back(2);
v.push_back(3);
if(!vec.empty()){
    cout << 「the first number is:」 << v.front() << endl;
    cout << 「the last number is:」 << v.back() << endl;
}

(4)刪除操做

/*刪除操做*/
c.clear()
//移除容器中全部數據

c.erase(pos)
//刪除pos位置的數據,傳回下一個數據的位置
c.erase(beg,end)
//刪除[beg,end)區間的數據,傳回下一個數據的位置

c.pop_back()
//刪除最後一個數據。

remove(num);
//刪除鏈表中匹配num的元素。
remove_if(comp);
//刪除條件知足的元素,參數爲自定義的回調函數。

unique();
//刪除相鄰的元素

示例:

vector<int>::iterator it;
for(it = v.begin();it!=v.end();it++){
    cout << *it << "\t";
}
v.clear();
for(it = v.begin();it!=v.end();it++){
    cout << *it << "\t";
}
cout << endl;
vector<int> v;
v.push_back(1);
v.push_back(2);
v.push_back(3);
v.erase(v.begin());
vector<int> v;
v.push_back(1);
v.push_back(2);
v.push_back(3);
v.erase(v.begin(),v.end());

(5)定位操做

/*定位操做*/
使用兩種方法來訪問vector。
一、vector::at()
二、vector::operator[]
operator[]主要是爲了與C語言進行兼容。它能夠像C語言數組同樣操做。但at()是咱們的首選,由於at()進行了邊界檢查,若是訪問超過了vector的範圍,將拋出一個例外。
因爲operator[]容易形成一些錯誤,全部咱們不多用它。
c.at(idx)
//傳回索引idx所指的數據,若是idx越界,拋出out_of_range

c.back()
//傳回最後一個數據,不檢查這個數據是否存在
c.begin()
//傳回迭代器重的可一個數據
c.end()
//指向迭代器中的最後一個數據地址
c.front()
//傳回第一個數據

c.rbegin()
//傳回一個逆向隊列的第一個數據。
c.rend()
//傳回一個逆向隊列的最後一個數據的下一個位置。
c.max_size()
//返回容器中最大數據的數量

reverse();
//反轉鏈表

示例:

vector<int> v;
v.reserve(10);
 
for(int i=0; i<7; i++)
    v.push_back(i);
 
try
{
 int iVal1 = v[7];  // not bounds checked - will not throw
 int iVal2 = v.at(7); // bounds checked - will throw if out of range
}
catch(const exception& e)
{
 cout << e.what();
}
/*
咱們使用reserve()分配了10個int型的空間,但並不沒有初始化。 
*/
vector<int> v;
v.push_back(1);
v.push_back(2);
v.push_back(3);
vector<int>::iterator it;
for(it = v.begin();it!=v.end();it++){
    cout << *it << "\t";
}
cout << endl;
vector<int> v;
v.push_back(1);
v.push_back(2);
v.push_back(3);
vector<int>::reverse_iterator it;
for(it = v.rbegin();it!=v.rend();it++){
    cout << *it << "\t";
}
cout << endl;

(6)數據大小

/*大小*/
c.capacity()
//返回容器中數據個數

c.empty()
//判斷容器是否爲空

c.resize(num)
//從新指定隊列的長度。

c.reserve()
//保留適當的容量。
c.size()
//返回容器中實際數據的個數。

示例:

vector<int> v;
v.push_back(1);
cout << v.capacity() << endl;  // 1
v.push_back(2);
cout << v.capacity() << endl;  // 2
v.push_back(3);
cout << v.capacity() << endl; // 4
vector<int> v;
v.push_back(1);
v.push_back(2);
v.push_back(3);
if(!v.empty()){
    cout << "v is not empty!" << endl;        
}

(7)交換操做

/*交換操做*/
c1.swap(c2)
//將c1和c2元素互換。
swap(c1,c2)
//同上操做。

示例:

vector<int> v1,v2,v3;
v1.push_back(10);
v2.swap(v1);
swap(v3,v1);

(8)排序

c.sort()       
//將鏈表排序,默認升序
c.sort(comp)       
//自定義回調函數實現自定義排序
相關文章
相關標籤/搜索