日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > c/c++ >内容正文

c/c++

C++ STL容器总结之vector(超详细版)

發(fā)布時(shí)間:2025/3/20 c/c++ 23 豆豆
生活随笔 收集整理的這篇文章主要介紹了 C++ STL容器总结之vector(超详细版) 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

一、vector簡介

vector的中文翻譯為向量,是一種C++ STL中的序列容器。它的是存儲方式和C++語言本身提供的數(shù)組一樣都是順序存儲,因此vector的操作和數(shù)組十分相似。但是和數(shù)組不一樣的是,數(shù)組的存儲空間是靜態(tài)的,一旦配置了就不能改變,而vector的存儲空間是動態(tài)的,隨著元素的加入,它的內(nèi)部機(jī)制會自動擴(kuò)充空間以容納新元素,因此也被稱為可變長數(shù)組。

二、vector存儲機(jī)制

vector的動態(tài)空間實(shí)現(xiàn)如下圖所示,

為了減少空間配置的時(shí)間代價(jià),通常vector配置的空間會比我們標(biāo)注的需求量更大一些,于是vector總的存儲空間就如上圖所示分成了兩部分,其中工作空間是按我們標(biāo)注的需求配置的,而備用空間就是額外配置的那一部分空間。

當(dāng)需要擴(kuò)充的新的空間時(shí),vector會優(yōu)先使用備用空間。例如我們現(xiàn)在要在末尾插入6,它會將 finishfinishfinish 迭代器指向的空間用于存儲6,最后再調(diào)整 finishfinishfinish 迭代器的位置。
當(dāng)備用空間不足以存放要插入的元素時(shí),vector會在另外較大的空閑空間中配置一塊大小為原來兩倍的新空間(由于不能保證原空間之后有足有的空閑空間,所以并不是直接在原空間后面接續(xù)),然后將原空間中的數(shù)據(jù)按順序遷移到新空間,最后釋放原來的存儲空間。這一過程可以簡單記憶為重新配置、移動數(shù)據(jù)、釋放原空間。

下面是以“在備用空間用完的情況下插入新元素3”為例,用圖片形式描述前后的存儲空間變化。

由于以上過程對使用者而言都是透明的,所以需要非常注意的一點(diǎn)是,一旦vector的空間重新配置,所有指向原vector的迭代器都會失效!

三、vector創(chuàng)建和初始化

初始化比較簡單,我們可以根據(jù)自己的使用需求來相應(yīng)的初始化方法。

//vector頭文件 #include <vector> //創(chuàng)建一個(gè)空的vector vector<int> vec1; //創(chuàng)建一個(gè)有n個(gè)元素的vector,初始值都為0 vector<int> vec2(n); //創(chuàng)建一個(gè)有n個(gè)元素的vector,并將它們值都初始化為x vector<int> vec3(n, x); //用vec3來初始化vec4,它們大小和元素的值都相同 vector<int> vec4(vec3);

四、vector基本操作詳解

很多人不明白為什么要了解容器本身實(shí)現(xiàn)的原理,覺得學(xué)會怎么用就夠了。其實(shí),學(xué)了容器的實(shí)現(xiàn)原理會對容器操作會有更加深刻的理解,同時(shí)也會對算法思想有或多或少的領(lǐng)悟。

接下來,我們結(jié)合這張底層存儲示意圖仔細(xì)分析vector的基本操作。

  • 迭代器
    這里簡單介紹下面將出現(xiàn)的兩種比較陌生的迭代器:
    • reverse_iteratorreverse\_iteratorreverse_iterator,稱為反向迭代器,它的遞增方向和我們常用的 iteratoriteratoriterator 相反,例如 rit++rit++rit++表示指向的位置往左移。
    • const_iteratorconst\_iteratorconst_iterator,它不能改變所指向的元素的值,但是可以再指向其他元素,和const關(guān)鍵詞標(biāo)注的 iteratoriteratoriterator 剛好相反。
//獲取第一個(gè)元素的迭代器,也就是圖中的start vec.begin();//獲取最后一個(gè)下個(gè)位置的迭代器,即圖中的finish vec.end();//返回vector<T>::reverse_iterator類型迭代器,指向finish-1 vec.rbegin();//返回vector<T>::reverse_iterator類型迭代器,指向start的前一個(gè)位置 vec.rend();//c++11,返回vector<T>::const_iterator類型迭代器,位置同圖中start vec.cbegin();//c++11,返回vector<T>::const_iterator類型迭代器,位置同圖中finish vec.cend();
  • 容量
//獲取當(dāng)前容量大小 vec.size();//獲取包括備用空間在內(nèi)的總?cè)萘看笮?/span> vec.capacity();//最大容量,即最多可以存儲多少個(gè)當(dāng)前類型元素 vec.max_size();//判斷vector是否為空,即判斷start == finish vec.empty();//重新設(shè)置vector的容量,大小為n vec.resize(n);
  • 元素訪問
    因?yàn)関ector也是順序存儲,所以它進(jìn)行元素的隨機(jī)訪問的時(shí)間復(fù)雜度也為 O(1)O(1)O(1)
//像數(shù)組一樣用索引進(jìn)行隨機(jī)訪問,例如vec[0] operator []//作用同上,增加異常處理,越界拋出out of range vec.at(index);//返回一個(gè)元素,即迭代器start指向的元素 vec.front();//返回最后一個(gè)元素,即迭代器finish-1指向的元素 vec.back();
  • 修改操作操作
    由于是順序存儲結(jié)構(gòu),隨機(jī)插入或隨機(jī)刪除都會引起元素的移動(對末尾元素操作除外),因此它們的時(shí)間復(fù)雜度都是 O(n)O(n)O(n)。下圖是刪除元素的底層實(shí)現(xiàn)示意,可以用于幫助我們的理解,從圖中也可以看出刪除操作不會引起總空間的變化。
//元素的賦值值操作(類似于初始化) //將vec賦值為n個(gè)x vec.assign(n, x); //將[first, last)范圍內(nèi)的元素賦值給vec vec.assign(first, last); //傳入?yún)?shù)為數(shù)組指針,將數(shù)組[0, n)中的元素賦值給vec vec.assign(array, array + n);//將新元素x插入到finish所在的位置,并將迭代器finish后移,時(shí)間復(fù)雜度為O(1) vec.push_back(x);//清除位于finish-1的元素,時(shí)間復(fù)雜度為O(1) vec.pop_back();//時(shí)間復(fù)雜度為O(n),position表示插入位置的迭代器 //在position插入新元素,其值為x vec.insert(position, x); //在position插入n個(gè)新元素,它們的值都為x vec.insert(position, n, x);//時(shí)間復(fù)雜度為O(n),下列參數(shù)均為迭代器 //清除某個(gè)特定位置的元素 vec.erase(position); //清除[first, last)中的所有元素 vec.erase(first, last);//交換vec和vec2中的所有元素, vec.swap(vec2);//清除所有的元素,事實(shí)上調(diào)用了erase(begin(), end()) vec.clear();
  • 遍歷操作
//順序遍歷 //最常用的方式 for (int i = 0; i < vec.size(); i++) cout << vec[i] << endl; //利用迭代器 vector<int>::iterator it; for (it = vec.begin(); it != vec.end(); i++) cout << *it << endl; //c++11 for(auto x : vec) cout << x << endl;//逆序遍歷 //常用方式 for (int i = size() - 1; i >= 0; i--) cout << vec[i] << endl; //利用反向迭代器 vector<int>::reverse_iterator rit; for (rit = vec.rbegin(); rit != vec.rend(); rit++) cout << *rit << endl;
  • 查找操作
    這個(gè)操作主要是利用STL提供的 findfindfind 函數(shù)。
#include <algorithm> //需要調(diào)用find函數(shù),在[first, last)中查找x,返回的是迭代器 vector<int>::iterator it = find(vec.begin(), vec.end(), x); //如果找到則輸出YES,否則輸出NO if (it != vec.end()) cout << "YES" << endl; else cout << "NO" << endl;
  • 排序和翻轉(zhuǎn)
    主要是調(diào)用STL提供的 sortsortsortreversereversereverse 函數(shù)。
#include <algorithm> //升序排序(默認(rèn)) sort(vec.begin(), vec.end()); sort(vec.begin(), vec.end(), less<int>()); //降序排序 sort(vec.begin(), vec.end(), greater<int>());//元素翻轉(zhuǎn) reverse(vec.begin(), vec.end());

五、參考資料

  • C++官方的vector文檔
  • 《STL源碼剖析》
  • 個(gè)人混亂的實(shí)驗(yàn)代碼

  • 既然都看到就這里了(我也終于寫到這里了),希望你可以做到下面三點(diǎn)哦:

    • 點(diǎn)贊,這是對作者辛苦寫作的最低成本的鼓勵。
    • 答應(yīng)我,把它學(xué)會!(別扔進(jìn)收藏夾吃灰)
    • 可以考慮關(guān)注一波,STL系列的文章會持續(xù)更新。

    總結(jié)

    以上是生活随笔為你收集整理的C++ STL容器总结之vector(超详细版)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。