2.3、vector 与 list 区别
底层结构差异
vector
- • 底层实现:动态数组,内存连续分配。
- • 访问特性:支持高效随机访问,时间复杂度为 O(1)(通过下标
operator[]
或迭代器)。 - • 内存管理:预分配机制,
capacity ≥ size
;扩容时需重新申请更大连续内存,并复制原有元素。
list
- • 底层实现:双向链表,内存非连续(节点通过指针连接)。
- • 访问特性:不支持随机访问,只能顺序遍历,元素访问时间复杂度为 O(n)。
- • 操作特性:插入/删除操作只需修改指针指向,时间复杂度为 O(1)(已定位迭代器位置时)。
性能对比
操作类型 | vector | list |
随机访问 | O(1),支持operator[] |
O(n),需顺序遍历 |
头部插入/删除 | O(n),需移动后续元素 | O(1),直接修改指针 |
尾部插入/删除 | 均摊 O(1)(预分配空间) | O(1) |
中间插入/删除 | O(n),移动后续元素 | O(1)(已定位迭代器) |
内存布局 | 连续,缓存友好 | 不连续,内存开销大(额外指针) |
适用场景
vector 更适合:
- • 需要频繁随机访问元素(如数组下标式操作)。
- • 主要操作集中在尾部插入/删除(如
push_back
/pop_back
)。 - • 元素数量变化可预测,或可通过
reserve
提前分配空间。 - • 追求缓存友好性和高内存利用率(无额外指针开销)。
list 更适合:
- • 需要频繁在中间或头部插入/删除元素(如链表式增删)。
- • 对随机访问性能无要求,仅需顺序遍历。
- • 元素数量动态变化剧烈,且插入/删除操作位置不确定。
实践建议
- • 优先选用vector:尽管传统理论认为list在插入删除场景更优,但vector的连续内存布局带来的缓存优势和高效内存管理,使其在大多数场景下性能更优,且代码更简洁。
- • 仅当确实存在大量非尾部插入/删除操作(如频繁在容器中间增删元素)时,才考虑使用list。
总结
vector和list的设计体现了时间与空间的权衡:
- • vector以连续内存和预分配机制换取随机访问效率和缓存友好性;
- • list以非连续内存和指针操作换取灵活的插入/删除效率。
选择容器时,需结合具体场景的访问模式、操作频率和内存效率需求,这是C++容器选型的核心要点。
本文首发于【讳疾忌医-note】公众号,未经授权,不得转载。
(加入我的知识星球,免费获取账号,解锁所有文章。)
阅读剩余
版权声明:
作者:讳疾忌医-note
链接:https://www.1217zy.vip/archives/1801
文章版权归作者所有,未经允许请勿转载。
THE END