您好,登录后才能下订单哦!
密码登录
登录注册
点击 登录注册 即表示同意《亿速云用户服务条款》
# C++中vector和list区别是什么
## 引言
在C++标准模板库(STL)中,`vector`和`list`是两种最常用的顺序容器,它们虽然都能存储元素集合,但在底层实现、性能特性和适用场景上存在显著差异。本文将深入分析两者的核心区别,帮助开发者根据具体需求做出合理选择。
## 1. 底层数据结构差异
### 1.1 vector的连续内存布局
```cpp
std::vector<int> vec = {1, 2, 3};
capacity()和size()管理内存std::list<int> lst = {1, 2, 3};
| 操作 | vector | list |
|---|---|---|
| operator[] | O(1) | O(n) |
| at() | O(1) | O(n) |
示例说明:
vec[100]; // 直接计算偏移量访问
auto it = lst.begin();
advance(it, 100); // 需要遍历100次
| 场景 | vector | list |
|---|---|---|
| 尾部插入 | 均摊O(1) | O(1) |
| 头部插入 | O(n) | O(1) |
| 中间插入 | O(n) | O(1)* |
| 尾部删除 | O(1) | O(1) |
| 头部删除 | O(n) | O(1) |
| 中间删除 | O(n) | O(1)* |
*注:list的O(1)前提是已获得迭代器位置
vector:
shrink_to_fit()可减少内存占用list:
// 测试缓存命中率
void traverse_vector(std::vector<int>& v) {
for(auto& item : v) item *= 2; // 高速缓存友好
}
void traverse_list(std::list<int>& l) {
for(auto& item : l) item *= 2; // 可能频繁缓存缺失
}
| 特性 | vector | list |
|---|---|---|
| 迭代器类型 | 随机访问迭代器 | 双向迭代器 |
| 支持的操作 | +, -, +=, -=, [] | ++, – |
vector:
list:
示例:
std::vector<int> v = {1,2,3};
auto vit = v.begin() + 1;
v.insert(v.begin(), 0); // vit可能失效
std::list<int> l = {1,2,3};
auto lit = ++l.begin();
l.insert(l.begin(), 0); // lit仍然有效
std::list<int> lst;
// 高效合并(转移节点)
lst.splice(lst.end(), other_list);
// 无需拷贝的排序
lst.sort();
// 去重(需先排序)
lst.unique();
std::vector<int> vec;
// 预留内存
vec.reserve(1000);
// 快速清空(不释放内存)
vec.clear();
// 直接访问底层数组
int* arr = vec.data();
// 在中间位置插入10000个元素
void test_insert() {
std::vector<int> v;
std::list<int> l;
auto start = std::chrono::high_resolution_clock::now();
for(int i=0; i<10000; ++i) {
v.insert(v.begin() + v.size()/2, i);
}
auto vec_time = /* 计算时间 */;
for(int i=0; i<10000; ++i) {
auto pos = l.begin();
std::advance(pos, l.size()/2);
l.insert(pos, i);
}
auto list_time = /* 计算时间 */;
}
// 遍历求和100万个元素
void test_traversal() {
std::vector<int> v(1000000, 1);
std::list<int> l(1000000, 1);
// vector遍历通常快3-10倍
}
vector增加emplace_back减少拷贝list支持范围构造函数deque:折衷的随机访问和头尾操作forward_list:更节省内存的单向链表array:固定大小数组| 特性 | vector | list |
|---|---|---|
| 底层结构 | 动态数组 | 双向链表 |
| 内存连续性 | 连续 | 非连续 |
| 随机访问 | O(1) | O(n) |
| 中间插入 | O(n) | O(1) |
| 迭代器类型 | 随机访问 | 双向 |
| 迭代器失效 | 易失效 | 稳定 |
| 内存开销 | 较低(仅需存储元素) | 较高(每个元素+2指针) |
| 缓存友好性 | 优秀 | 较差 |
| 推荐场景 | 随机访问为主 | 频繁插入删除 |
reserve()减少重新分配理解vector和list的底层差异是成为优秀C++开发者的关键。在实际工程中,应当根据具体的访问模式、数据特性和性能需求来选择合适的容器,有时甚至需要组合使用多种容器。C++17引入的并行算法和后续标准中的新特性可能会进一步影响容器的选择策略,保持学习是掌握STL容器的永恒主题。 “`
注:本文实际字数为约2300字(含代码示例),完整版本可扩展包含更多性能测试数据和实际案例。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。