vector 和 list 都是C++ 标准模板库(STL)中的容器,它们的区别如下:
内存结构
- vector :是连续的内存空间,就像数组一样,元素在内存中依次排列。
- list :是由节点组成的双向链表,每个节点包含数据和指向前一个及后一个节点的指针,节点在内存中不连续。
随机访问
- vector :支持随机访问,可以通过下标快速访问元素,时间复杂度为 O(1)。
- list :不支持随机访问,要访问某个元素,需要从链表头或尾开始逐个遍历,时间复杂度为 O(n)。
插入和删除操作
- vector :在尾部插入和删除元素效率较高,时间复杂度为 O(1)。但在中间或头部插入和删除元素时,需要移动大量元素,效率较低,时间复杂度为 O(n)。
- list :在任何位置插入和删除元素都非常高效,只需修改相应节点的指针,时间复杂度为 O(1)。
迭代器
- vector :迭代器是普通指针,支持 ++ 、 -- 、 +n 、 -n 等操作,可以直接进行算术运算来访问不同位置的元素。
- list :迭代器是双向链表的节点指针,只支持 ++ 和 -- 操作来逐个遍历链表。
空间占用
- vector :由于是连续内存,可能会预分配一些额外空间,以减少重新分配内存的次数,因此实际占用空间可能比存储元素所需空间略大。
- list :每个节点除了存储数据外,还需要额外的空间存储指针,所以对于大量数据, list 的空间占用可能比 vector 大。
在实际应用中,如果需要频繁随机访问元素, vector 是较好的选择;如果需要频繁在容器中间插入和删除元素, list 更为合适。
#include <iostream>
#include <vector>
#include <list>
void printVector(const std::vector<int>& vec) {
for (const auto& num : vec) {
std::cout << num << " ";
}
std::cout << std::endl;
}
void printList(const std::list<int>& lst) {
for (const auto& num : lst) {
std::cout << num << " ";
}
std::cout << std::endl;
}
int main() {
// vector用法示例
std::vector<int> vec;
// 尾部插入元素
vec.push_back(1);
vec.push_back(2);
vec.push_back(3);
std::cout << "Vector: ";
printVector(vec);
// 随机访问元素
std::cout << "Element at index 1: " << vec[1] << std::endl;
// 在中间插入元素
vec.insert(vec.begin() + 1, 4);
std::cout << "Vector after insertion: ";
printVector(vec);
// 删除元素
vec.erase(vec.begin() + 2);
std::cout << "Vector after deletion: ";
printVector(vec);
// list用法示例
std::list<int> lst;
// 头部插入元素
lst.push_front(5);
lst.push_front(4);
lst.push_front(3);
std::cout << "List: ";
printList(lst);
// 在中间插入元素
auto it = lst.begin();
std::advance(it, 1);
lst.insert(it, 6);
std::cout << "List after insertion: ";
printList(lst);
// 删除元素
it = lst.begin();
std::advance(it, 2);
lst.erase(it);
std::cout << "List after deletion: ";
printList(lst);
return 0;
}