C 语言

关注公众号 jb51net

关闭
首页 > 软件编程 > C 语言 > C++之vector/list/map对比

C++之vector/list/map完整对比与解读

作者:C++程序员kingfriend

这段文章详细介绍了C++中三种常用容器vector、list和map的底层实现、核心性能对比及适用场景,通过对比它们在随机访问、插入删除、内存开销等方面的差异,帮助开发者根据具体需求选择合适的容器类型

一、底层数据结构

  1. vector(动态数组) 底层:连续内存数组,一块完整堆内存,自动扩容。
  2. list(双向链表) 底层:双向不连续链表,每个节点存数据 + 前后指针,内存分散。
  3. map(有序红黑树) 底层:红黑平衡二叉树,按键 key 自动升序排序,键唯一不可重复。

二、核心性能对比(时间复杂度)

表格

操作vectorlistmap
随机访问 []/at()O (1) 极快不支持随机访问不支持随机访问
头部插入 / 删除O (n)(整体移位)O (1) 极快O(log n)
尾部插入 / 删除均摊 O (1) 极快O(1)O(log n)
中间插入 / 删除O (n)(大量移位)O(1)O(log n)
按值查找O (n) 遍历O (n) 遍历按键查找 O (log n)
内存开销小,仅存数据大,额外存双向指针大,树平衡额外标记

三、基础代码示例

1. vector 动态数组(优先日常容器)

适用:频繁随机读写、尾部增删,很少中间插入

#include <vector>
#include <iostream>
using namespace std;

int main() {
    vector<int> vec;
    vec.push_back(10);  // 尾部添加
    vec.push_back(20);
    vec.insert(vec.begin(), 5); // 头部插入,效率低
    cout << vec[1]; // 随机访问 O(1)

    // 遍历
    for (int x : vec) cout << x;
    return 0;
}

2. list 双向链表

适用:频繁头部 / 中间增删,几乎不随机读取

#include <list>
int main() {
    list<int> lst;
    lst.push_back(1);
    lst.push_front(0); // 头部插入很快
    // 无 lst[0] 这种随机访问,只能迭代器遍历
    for (auto it = lst.begin(); it != lst.end(); ++it) {}
    return 0;
}

3. map 有序键值对

适用:需要key 自动排序、按键快速查找、键不重复

#include <map>
int main() {
    map<string, int> mp;
    mp["张三"] = 18;
    mp["李四"] = 20;
    // 自动按字符串升序排列,按键查询O(logn)
    cout << mp["张三"];
    return 0;
}

四、优缺点总结

vector

✅ 优点:随机访问超快、缓存友好、内存紧凑、遍历速度最快

❌ 缺点:头部 / 中间插入删除大量元素移位,扩容会拷贝数据

场景:数组、缓存、数据批量存储、绝大多数业务首选

list

✅ 优点:任意位置插入删除仅修改指针,无内存拷贝

❌ 缺点:不支持随机访问,遍历慢、内存碎片多、缓存不命中

场景:频繁中间增删、队列节点管理、极少查询下标

map

✅ 优点:key 有序,按键二分查找,插入删除稳定 logn 复杂度

❌ 缺点:不能下标随机遍历 value,树结构内存开销大

场景:字典、有序映射、需要按 key 快速检索的配对数据

五、选型快速口诀

  1. 要下标随机取数据 → vector
  2. 频繁在中间 / 头部删改,不用下标 → list
  3. 存 key-value、需要自动排序、按键查找 → map

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

您可能感兴趣的文章:
阅读全文