例說資料結構&STL(一)——vector

無鞋童鞋發表於2017-07-26

1 白話vector(向量)
  資料結構vector又稱為動態陣列,因為它無需像普通陣列定義的時候規定具體空間大小,一定程度上可以節約記憶體空間。但是它又具有普通陣列連續實體記憶體儲存的優勢,即各元素之間構成一個線性的前後次序,資料的物理儲存位置與其邏輯次序完全吻合,這樣我們就可以常數級時間內通過秩(下標)訪問每個元素。
  當然STL中vector底層構建還是基於靜態陣列實現的,只不過固定大小由系統自動完成,不用我們操心。一旦資料量超過系統初始設定的記憶體大小,系統也會自動拷貝資料到一塊更大的連續空間儲存,這個固定大小可以通過vector類提供的介面查詢。廢話不多說,下面直接進入STL中vector模板類的示例介紹中。
2 STL中vector實戰
 2.1 標頭檔案包含
  STL容器vector使用首先需要在程式開頭新增標頭檔案包含,這樣才可以直接呼叫vector中各種類方法。

#include<vector>

  其次一定要加上C++標準庫名稱空間std,一種方便形式是在檔案標頭檔案後面新增using namespace std;,這樣全文可以直接使用std下面定義的類與方法了。還可以每個實體前宣告諸如std::vector<int>形式,這樣稍顯複雜,但是如果程式中有自己定義的名稱空間就最好這樣宣告瞭。
 2.2 變數宣告
  由於vector是模板類,所以我們再定義vector變數的時候需要指明容器儲存的型別,這種資料型別可以是int,long,float等常見型別,還可以是定義的類諸如string等。下面我們以int型別為例。

vector<int> vec_one;  //最簡單vector例項定義

  定義變數同時初始化如下:

vector<int> vec_sed(10,1);         //分配10個空間,並且初始化為1

int nArr[] = {0,1,2,3,4,5,6,7,8,9};
//指標初始化為一個陣列某一範圍內資料,等價vector<int> vec_thr(&nArr[0],&nArr[9]);
vector<int> vec_thr(nArr,nArr+10); 

vector<int> vec_for(vec_thr.begin(),vec_thr.end()); //迭代器初始化為另一個vector某一範圍內資料

  上面不同vector例項化是由類中構造器過載所匹配的,但是需要注意下面的初始化方式:

int nLen = 10;
vector<int> vec_fiv(nLen); //分配nLen個空間,並且每個空間初始化為0

  上面例項並不是初始化一個儲存10的vector,而是分配了10個空間,並且每個空間初始化為0(建構函式預設初始化數值是0,所以沒有明確指出初始值就是0),切記不要弄錯。
 2.3 查詢元素

int nData1 = vec_fir.front(); //查詢vector中第一個元素
int nData2 = vec_fir.back();  //查詢vector中最後一個個元素
int nData3 = vec_fir.at(8);   //查詢vector中索引為8(即第9個)元素
int nData4 = vec_fir[8];      //同上,operator[]運算子過載

 2.4 賦值操作

vec_fir.assign(10,2);                          //重新賦值vec_fir例項中資料為102

vec_fir.assign(vec_sed.begin(),vec_sed.end()); //重新賦值vec_fir為vec_sed

 2.5 vector尾部操作
  由於vector陣列只需常數級時間花費在其尾部新增資料,所以STL提供了尾部刪除元素pop_back()與新增元素push_back()的方法介面,也很好記憶,back為尾部的意思,pop是刪除,push是推進。而首部新增與刪除就需要花費線性級時間,所以沒有pop_front()與push_front()對應方法(後面介紹的雙向連結串列list就有)。使用如下:

vec_fir.push_back(10) //vector尾部新增一個10資料

vec_fir.pop_back()   //刪除vector尾部一個資料

 2.6 刪除操作

vec_fir.erase(vec_fir.begin()); //刪除vec_fir第一個資料(索引刪除)

vec_fir.erase(vec_fir.begin(),vec_fir.begin()+5); //刪除vec_fir第一個到第五個間斷資料

 2.7 插入操作
  與刪除操作一樣,插入操作的時間複雜度是線性級,因為我們再刪除或者插入數值後需要移動剩餘所有資料,從而讓資料存放在連續的空間中。

vec_fir.insert(vec_fir.begin(),10086); //開始位置插入一個10086資料

vec_fir.insert(vec_fir.begin(),10,99); //開始位置插入10個初始化為99的資料集

vec_fir.insert(vec_fir.begin(),vec_sed.begin().vec_sed.begin()+5); //將vec_sed開始的5個數插入在vec_fir開頭

 2.8 遍歷vector
  由於vector資料存放在一塊實體記憶體連續的空間,所以我們可以通過下標順序訪問。

for(size_t i=0; i<vec_fir.size(); i++) //vec_fir.size()是統計陣列中資料個數
    cout<<vec_fir[i]<<endl; //或者vec_fir.at(i)

  此外還可以迭代器(指標)累加連續訪問每個數直到結尾,迭代器(iterator)是STL一個重要概念,簡單理解可以為指標,每個迭代器儲存一個vector中資料地址空間。使用迭代器需要另包含標頭檔案#include<iterator>,因為它不僅vector可以使用,後面很多STL容器都可以使用。

vector<int>::iterator iter;
for(iter=vec_fir.begin();iter!=vec_fir.end();iter++)
    cout<<*iter<<endl;

  另外還包括反向迭代,更詳細介紹請另閱例說資料結構&STL(十二)——iterator
 2.9 其他介面

vec_fir.size(); //求解vector資料個數

//重新定義空間大小為100個空間,空間增加了則新增空間初始化為0,縮小了就僅保留前100個資料
vec_fir.resize(100); 

vec_fir.clear(); // 清空vector

vec_fir.swap(vec_sed); //交換兩個vector中所有資料

 2.10 二維陣列
  下面我們示例定義一個10*9的二維陣列。

const size_t m=10, n=9;
vector<vector<int>> vec_2D_1(m,vector<int>(n)); //vector中儲存的是vector,並且裡面初始化m個儲存n個0的vector的資料集

vector<vector<int>> vec_2D_2(m,vector<int>(n,1)); //所有數初始化為1

vector<vector<int>> vec_2D_3; 
vec_2D_3.resize(m,vector<int>(n,1));

3 小結
  至此,我們將STL容器中vector大部分方法介面介紹了一遍,相信大家有了一定的認識,最後還是需要自己動手實踐才能真正很好的掌握。vector是STL基本容器,憑藉其查詢常數級,尾部插入常數級時間花費在很多程式中有大量的使用,所以學好vector是學號資料結構的第一步。
  以上是個人學習記錄,由於能力和時間有限,如果有錯誤望讀者糾正,謝謝!
  轉載請註明出處:http://blog.csdn.net/fx677588/article/details/76166957

相關文章