最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

C++ 中 std::vector 和 std::list 的區(qū)別詳解

 更新時(shí)間:2026年03月31日 09:26:24   作者:是嬌嬌公主~  
本文詳細(xì)介紹了C++標(biāo)準(zhǔn)庫中的std::vector和std::list的區(qū)別,從底層數(shù)據(jù)結(jié)構(gòu)、內(nèi)存布局與分配策略、操作時(shí)間復(fù)雜度對比、迭代器有效性與類別、其他特性與成員函數(shù)差異、內(nèi)存占用與緩存性能等方面進(jìn)行了闡述,感興趣的朋友跟隨小編一起看看吧

前言

在 C++ 標(biāo)準(zhǔn)庫(STL)中,std::vector 和 std::list 都是最常用的序列容器,它們都支持 push_back、insert、erase、begin()/end() 等相似接口,看起來“用法差不多”。但如果只停留在接口層面,就很容易在性能瓶頸出現(xiàn)時(shí)踩坑。本篇文章將一步步幫你徹底搞清楚二者的本質(zhì)區(qū)別~~

一、底層數(shù)據(jù)結(jié)構(gòu)(這是理解一切差異的根源)

std::vector< T >:動態(tài)數(shù)組。
它在連續(xù)的一塊內(nèi)存上存儲元素,就像一個(gè)可以自動擴(kuò)容的普通數(shù)組。當(dāng)元素?cái)?shù)量超過當(dāng)前容量時(shí),會向操作系統(tǒng)申請一塊更大的連續(xù)內(nèi)存,把舊元素搬過去(復(fù)制或移動),再釋放舊內(nèi)存。

std::list< T >:雙向鏈表。
每個(gè)元素都是一個(gè)獨(dú)立的節(jié)點(diǎn),節(jié)點(diǎn)結(jié)構(gòu)大致為:

struct Node{
    T data;
    Node* prev;
    Node* next;
};

節(jié)點(diǎn)之間通過指針鏈接,內(nèi)存完全不連續(xù)。list 內(nèi)部只維護(hù)頭尾指針(head 和 tail),無需連續(xù)內(nèi)存塊。

二、內(nèi)存布局與分配策略

  1. vector:
  • 元素連續(xù)存放,相鄰元素地址差正好是 sizeof(T)。
  • 維護(hù)兩個(gè)關(guān)鍵值:size()(當(dāng)前元素個(gè)數(shù))和 capacity()(已分配空間能容納的最大元素個(gè)數(shù)),始終滿足 size() ≤ capacity()。
  • 擴(kuò)容策略(實(shí)現(xiàn)相關(guān),通常是 1.5~2 倍增長):當(dāng) size() == capacity() 時(shí),重新分配更大內(nèi)存(典型 2 倍),并把所有元素移動過去。
  • 緩存友好:CPU 讀取連續(xù)內(nèi)存時(shí)會自動預(yù)取,命中率極高。
  1. list:
  • 每個(gè)節(jié)點(diǎn)單獨(dú)向堆申請內(nèi)存(new Node),節(jié)點(diǎn)之間可能散布在堆的任意位置。
  • 每個(gè)節(jié)點(diǎn)至少額外占用 2 個(gè)指針(64 位系統(tǒng) 16 字節(jié)),加上可能的內(nèi)存對齊開銷,內(nèi)存占用遠(yuǎn)大于 vector。
  • 插入/刪除無需搬動其他節(jié)點(diǎn),只需改 2~4 個(gè)指針即可。

vector 更“省內(nèi)存 + 快訪問”,list 更“靈活但浪費(fèi)空間”。

三、操作時(shí)間復(fù)雜度對比

操作std::vectorstd::listjieshi
隨機(jī)訪問 v[i] / *itO(1)O(n)vector 直接指針運(yùn)算,list 只能從頭/尾遍歷
尾部插入 push_back攤銷 O(1)O(1)vector 偶爾擴(kuò)容導(dǎo)致攤銷
尾部刪除 pop_backO(1)O(1)-
頭部插入 push_frontO(n)O(1)vector 需要整體右移
頭部刪除 pop_frontO(n)O(1)-
中間插入/刪除(有迭代器)O(n)O(1)vector 需要移動后續(xù)所有元素
查找元素(無序)O(n)O(n)兩者都需要線性遍歷
排序 std::sort極快(連續(xù)內(nèi)存)極慢(無法隨機(jī)訪問)std::list 只能用自己的 sort()

記憶總結(jié):
vector:隨機(jī)訪問快,中間修改慢。
list:任意位置修改快,隨機(jī)訪問慢。

四、迭代器有效性與類別

迭代器是 STL 容器的“指針”,修改容器后迭代器可能失效,這是很多Bug的源頭。

1.迭代器類別:

vector:隨機(jī)訪問迭代器,支持 it + n、it[n]、it < other 等。
list:雙向迭代器,僅支持 ++、–。

2.插入/刪除后的迭代器有效性

vector:
insert/erase:可能導(dǎo)致所有迭代器、指針、引用全部失效(因?yàn)榭赡苡|發(fā) reallocation)。
即使不 reallocation,后面的元素也會前移,指向后面元素的迭代器會“錯(cuò)位”。
#:reallocation 指的是動態(tài)數(shù)組的內(nèi)存重新分配。

list:
insert/erase:只有指向被刪除元素的迭代器失效,其他所有迭代器、指針、引用全部保持有效(這是鏈表的最大優(yōu)勢)。

所以在循環(huán)中邊遍歷邊刪除時(shí),list 可以安全地 it = lst.erase(it);,vector 必須小心處理索引或使用 erase 返回的迭代器。

五、其他特性與成員函數(shù)差異

  1. vector 獨(dú)有(動態(tài)數(shù)組特權(quán)):
  • reserve(n):提前分配容量,避免反復(fù) reallocation。
  • capacity()、shrink_to_fit()(C++11)。
  • data():返回底層數(shù)組指針,可直接傳給 C API。
  • 支持 operator[](不檢查越界)和 at()(拋異常)。
  1. list 獨(dú)有(鏈表特權(quán)):
  • splice:O(1) 把另一個(gè) list 的子鏈“剪切”過來(無需復(fù)制元素)。
  • merge、remove、remove_if、reverse、unique 等鏈表專用算法。
  • sort():使用穩(wěn)定的歸并排序(std::sort 無法用于 list)。

共同點(diǎn):兩者都支持 emplace_back、emplace(C++11 原地構(gòu)造)、移動語義(高效轉(zhuǎn)移)。

六、內(nèi)存占用與緩存性能

假設(shè) sizeof(T) = 8 字節(jié),存儲 10000 個(gè)元素:

vector:約 80KB + 少量元數(shù)據(jù)。
list:約 80KB(數(shù)據(jù))+ 10000×16 字節(jié)(指針)≈ 240KB,3 倍內(nèi)存。

緩存命中率:

vector 在順序遍歷時(shí)幾乎 100% 命中 L1/L2 緩存。
list 每個(gè)節(jié)點(diǎn)跳轉(zhuǎn)可能導(dǎo)致緩存失效,性能差距可達(dá) 5~10 倍。

七、適用場景

  1. 選擇 std::vector 的情況:
  • 需要頻繁隨機(jī)訪問(下標(biāo)、排序、二分查找)。
  • 主要在尾部 push/pop。
  • 元素?cái)?shù)量較多,對內(nèi)存和緩存敏感。
  • 需要與 C 語言 API 交互(data())。
  • 典型場景:游戲中的實(shí)體列表、日志緩沖、JSON 解析結(jié)果、科學(xué)計(jì)算數(shù)組等。

2.選擇 std::list 的情況:

  • 極其頻繁地在任意位置插入/刪除(尤其鏈表中間)。
  • 需要穩(wěn)定迭代器(刪除一個(gè)元素后,其他迭代器不能失效)。
  • 元素本身很大,移動代價(jià)高(list 只改指針)。
  • 典型場景:LRU 緩存的鏈表實(shí)現(xiàn)、音樂播放器的播放隊(duì)列(頻繁切歌)、多線程任務(wù)調(diào)度隊(duì)列(頻繁插入/移除任務(wù))。

八、代碼示例

#include <vector>
#include <list>
#include <iostream>
using namespace std;
int main() 
{
    vector<int> v = {1,2,3,4,5};
    list<int> l = {1,2,3,4,5};
    // vector 中間插入(慢)
    v.insert(v.begin()+2,999);   // 1 2 999 3 4 5
    // list 中間插入(快 + 迭代器不失效)
    auto it = l.begin();
    advance(it,2);            // 指向第 3 個(gè)元素
    l.insert(it,999);              // 1 2 999 3 4 5
    // 此時(shí)原 it 仍指向原來的 3,不會失效
    cout<<"vector[2] ="<<v[2]<<endl;  // 999(O(1))
    // list 不能寫 l[2],必須遍歷
    return 0;
}

總結(jié):
vector = 動態(tài)數(shù)組:連續(xù)內(nèi)存 -》 隨機(jī)訪問快、緩存友好、內(nèi)存省,但中間操作慢。
list = 雙向鏈表:指針鏈接 -》 任意位置修改快、迭代器穩(wěn)定,但隨機(jī)訪問慢、內(nèi)存占用高。

到此這篇關(guān)于C++ 中 std::vector 和 std::list 的區(qū)別的文章就介紹到這了,更多相關(guān)C++ std::vector 和 std::list 區(qū)別內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • C++實(shí)現(xiàn)LeetCode(50.求x的n次方)

    C++實(shí)現(xiàn)LeetCode(50.求x的n次方)

    這篇文章主要介紹了C++實(shí)現(xiàn)LeetCode(50.求x的n次方),本篇文章通過簡要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下
    2021-07-07
  • C語言入門學(xué)習(xí)之fgets()函數(shù)和fputs()函數(shù)

    C語言入門學(xué)習(xí)之fgets()函數(shù)和fputs()函數(shù)

    fgetc() 和 fputc() 函數(shù)每次只能讀寫一個(gè)字符,速度較慢,實(shí)際開發(fā)中往往是每次讀寫一個(gè)字符串或者一個(gè)數(shù)據(jù)塊,這樣能明顯提高效率,這篇文章主要給大家介紹了關(guān)于C語言入門學(xué)習(xí)之fgets()函數(shù)和fputs()函數(shù)的相關(guān)資料,需要的朋友可以參考下
    2021-11-11
  • 淺談C++如何求等差素?cái)?shù)列

    淺談C++如何求等差素?cái)?shù)列

    這篇文章主要介紹了淺談C++如何求等差素?cái)?shù)列,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-07-07
  • opencv實(shí)現(xiàn)圖片與視頻中人臉檢測功能

    opencv實(shí)現(xiàn)圖片與視頻中人臉檢測功能

    這篇文章主要為大家詳細(xì)介紹了opencv實(shí)現(xiàn)圖片與視頻中人臉檢測功能,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-01-01
  • C++深入細(xì)致探究二叉搜索樹

    C++深入細(xì)致探究二叉搜索樹

    二叉搜索樹是以一棵二叉樹來組織的。每個(gè)節(jié)點(diǎn)是一個(gè)對象,包含的屬性有l(wèi)eft,right,p和key,其中,left指向該節(jié)點(diǎn)的左孩子,right指向該節(jié)點(diǎn)的右孩子,p指向該節(jié)點(diǎn)的父節(jié)點(diǎn),key是它的值
    2022-05-05
  • C++中的取余函數(shù)remainder與fmod詳解

    C++中的取余函數(shù)remainder與fmod詳解

    這篇文章主要為大家詳細(xì)介紹了C++中的取余函數(shù)remainder、fmod的具體使用以及自編的remainder及fmod,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)學(xué)習(xí)
    2023-05-05
  • 亞馬遜經(jīng)典面試題實(shí)例詳解

    亞馬遜經(jīng)典面試題實(shí)例詳解

    這篇文章主要介紹了亞馬遜經(jīng)典面試題實(shí)例詳解的相關(guān)資料,希望通過本文能幫助到大家,讓大家學(xué)習(xí)理解這部分內(nèi)容,需要的朋友可以參考下
    2017-10-10
  • 帶你了解C++初階之引用

    帶你了解C++初階之引用

    這篇文章主要為大家介紹了C++初階之引用,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助
    2022-01-01
  • 在C++中如何阻止類被繼承詳解

    在C++中如何阻止類被繼承詳解

    這篇文章主要介紹了在C++中如何阻止類被繼承,對于C++初學(xué)者而言可以通過本文實(shí)例更好的理解類的原理及運(yùn)用,需要的朋友可以參考下
    2021-09-09
  • 詳解編譯器編譯原理

    詳解編譯器編譯原理

    這篇文章主要介紹了詳解編譯器編譯原理的相關(guān)資料,需要的朋友可以參考下
    2017-06-06

最新評論

额尔古纳市| 积石山| 雷山县| 泗水县| 大渡口区| 工布江达县| 宁化县| 曲阜市| 盐津县| 大邑县| 永靖县| 西昌市| 临沧市| 肥城市| 绩溪县| 镇赉县| 同仁县| 革吉县| 昌乐县| 建昌县| 搜索| 江达县| 宁阳县| 盐池县| 揭阳市| 汉寿县| 连南| 华宁县| 金门县| 松潘县| 永城市| 讷河市| 龙岩市| 诏安县| 阜南县| 桂林市| 南城县| 阜新| 日照市| 安图县| 永丰县|