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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > c/c++ >内容正文

c/c++

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

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

一、vector簡介

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

二、vector存儲機制

vector的動態空間實現如下圖所示,

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

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

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

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

三、vector創建和初始化

初始化比較簡單,我們可以根據自己的使用需求來相應的初始化方法。

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

四、vector基本操作詳解

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

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

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

五、參考資料

  • C++官方的vector文檔
  • 《STL源碼剖析》
  • 個人混亂的實驗代碼

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

    • 點贊,這是對作者辛苦寫作的最低成本的鼓勵。
    • 答應我,把它學會!(別扔進收藏夾吃灰)
    • 可以考慮關注一波,STL系列的文章會持續更新。

    總結

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

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。