1.Vector(动态数组):
特点:
- 存储结构:连续的内存空间,动态扩展。
- 随机访问:支持 O(1) 时间复杂度的随机访问(通过下标)。
- 有序性:按照插入顺序存储元素,不自动排序。
- 重复元素:允许重复元素。
- 时间复杂度:
- 插入/删除(末尾):O(1)(摊销复杂度)。
- 插入/删除(中间/开头):O(n)。
- 随机访问:O(1)。
适用场景:
- 需要高效随机访问的场景。
- 插入和删除操作主要发生在末尾。
- 适合存储大小变化较为频繁但顺序敏感的数据。
示例代码:
#include <vector>
#include <iostream>
int main() {
std::vector<int> vec = {1, 2, 3};
vec.push_back(4); // 在末尾插入
vec[1] = 5; // 随机访问和修改
return 0;
}
2.list(双向链表) :
特点:
- 存储结构:非连续的内存,元素通过指针链接,形成双向链表。
- 随机访问:不支持随机访问,只能通过迭代器遍历。
- 有序性:按照插入顺序存储元素,不自动排序。
- 重复元素:允许重复元素。
- 时间复杂度:
- 插入/删除(任意位置):O(1)。
- 随机访问:O(n)(必须从链表头部或尾部遍历)。
适用场景:
- 需要频繁在中间或开头插入和删除元素的场景。
- 不关心随机访问,只关心顺序操作。
示例代码:
#include <list>
#include <iostream>
int main() {
std::list<int> lst = {1, 2, 3};
lst.push_back(4); // 在末尾插入
lst.push_front(0); // 在头部插入
lst.erase(lst.begin()); // 删除头部元素
return 0;
}
3. Set(集合):
特点:
- 存储结构:基于红黑树的平衡二叉搜索树,元素有序且唯一。
- 随机访问:不支持随机访问,只能通过迭代器遍历。
- 有序性:元素按升序(或自定义顺序)自动排序。
- 重复元素:不允许重复元素。
- 时间复杂度:
- 插入/删除/查找:O(log n)。
适用场景:
- 需要自动排序和去重的场景。
- 适用于集合操作(如并集、交集、差集)。
示例代码:
#include <set>
#include <iostream>
int main() {
std::set<int> s = {1, 2, 3};
s.insert(4); // 插入元素,自动排序
s.insert(2); // 插入重复元素,无效
return 0;
}
4.map:
特点:
- 存储结构:基于红黑树的键值对(key-value pair)结构。
- 随机访问:通过键访问对应的值,O(log n) 时间复杂度。
- 有序性:键按升序(或自定义顺序)自动排序。
- 重复元素:键唯一,值可以重复。
- 时间复杂度:
- 插入/删除/查找:O(log n)。
适用场景:
- 需要通过键快速查找对应值的场景。
- 键值对数据结构,适合字典、关联数组的使用场景。
示例代码:
#include <map>
#include <iostream>
int main() {
std::map<std::string, int> m;
m["apple"] = 3; // 插入键值对
m["banana"] = 5;
std::cout << m["apple"] << std::endl; // 查找值
return 0;
}
总结对比:
特性 | vector | list | set | map |
---|---|---|---|---|
存储结构 | 动态数组,连续内存 | 双向链表,非连续内存 | 平衡二叉搜索树 | 平衡二叉搜索树 |
有序性 | 按插入顺序存储 | 按插入顺序存储 | 自动排序(升序) | 键自动排序(升序) |
重复元素 | 允许 | 允许 | 不允许 | 键不允许重复,值可以重复 |
随机访问 | 支持(O(1)) | 不支持 | 不支持 | 不支持 |
插入/删除效率 | O(1)(末尾),O(n)(中间/开头) | O(1) | O(log n) | O(log n) |
查找效率 | O(n) | O(n) | O(log n) | O(log n) |
使用场景总结:
vector
:适合需要随机访问且插入/删除主要在末尾发生的场景。list
:适合频繁在中间或开头插入/删除的场景,不关心随机访问。set
:适合去重并需要有序集合的场景,适合集合操作。map
:适合键值对存储和快速通过键查找值的场景,适合字典或关联数组。