区别
特性 | vector | list |
---|---|---|
底层实现 | 动态数组 | 双向链表 |
内存分配 | 连续内存块 | 非连续内存块 |
随机访问 | 支持,通过索引访问,时间复杂度O(1) | 不支持,需遍历,时间复杂度O(n) |
插入/删除 | 末尾操作效率高,时间复杂度O(1) | 任意位置操作效率高,时间复杂度O(1) |
内存开销 | 较低 | 较高,需要额外存储指针 |
迭代器稳定性 | 插入/删除迭代器会失效 | 插入/删除迭代器不会失效 |
使用场景
使用vector
的场景
1.需要频繁随机访问元素。
2.数据量较大且内存连续性有助于性能优化。
3.插入和删除操作主要集中在容器末尾。
使用list
的场景
1.需要频繁在中间插入或者删除元素。
2.数据量较小,内存开销不是主要考虑因素。
3.不需要随机访问,仅需顺序遍历。
示例代码
vector
的常用方法
- 初始化
std::vector<int> vec ={1,2,3};
std::vector<int> vec2(10,0);//初始化大小为10,所有元素为0
2.添加元素
vec.push_back(4);//在尾部添加元素
vec.insert(vec.begin()+1,10);//在指定位置插入一个或多个元素。
vec.emplace_back(5);//在末尾直接构造元素,避免不必要的拷贝
vec.emplace(vec.begin() + 1, 5, 6); // 指定位置直接构造元素,在索引 1 的位置直接构造 pair(5, 6)
vec.assign(3,7);//替换整个 vector 的内容,vec变为 {7,7,7}
3.删除元素
vec.pop_back();//删除尾部元素
vec.erase(vec.begin()+1);//删除指定位置的元素
4.访问元素
int vel=vec[0];//随机访问
int val2=vec.at(1);//带边界的访问
5.遍历
for(int val:vec){std::cout << val << " ";
}
6.修改大小
vec.resize(5)//调整大小为5
7.清空
vec.clear();
list
的用法
1.初始化
std::list<int> lst={1,2,3};
std::list<int> lst2(10,0);//初始化大小为10,所有元素为0
2.添加元素
lst.push_back(4);//在尾部添加元素
lst.push_front(0);//在开头添加元素
auto it = lst.begin();
std::advance(it,1);
lst.insert(it,5);//在指定位置插入元素
3.删除元素
lst.pop_back();
lst.pop_front();//删除开头元素
lst.erase(lst.begin());//删除指定位置的元素
4.访问元素
for(int val:lst){std::cout << val << " ";
}
- 修改大小
lst.resize(5);//调整大小为5
- 清空
lst.clear();
7.排序
lst.sort();//对列表进行排序
- 合并
std::list<int> lst2 = {4,5,6};
lst.merge(lst2);
9.反转
lst.reverse();//反转列表
通过以上总结,可以根据具体需求选择使用vector
或list