主题
set 和 unordered_set
C++ 提供了两种常用的集合类型:set
和 unordered_set
。这两者都用于存储唯一的元素,但它们在底层实现、元素的存储顺序和操作效率上有所不同。了解它们的特点和使用场景,可以帮助开发者根据需要选择合适的容器。
set
set
是一个基于红黑树实现的有序集合。它自动将元素按照键的顺序排列,并保证集合中的元素是唯一的。由于使用红黑树,set
提供对元素的对数时间复杂度查找、插入和删除操作。
1. 创建 set
cpp
#include <iostream>
#include <set>
int main() {
// 创建一个空的 set
std::set<int> set1;
// 使用初始化列表初始化
std::set<int> set2 = {3, 1, 4, 1, 5, 9};
// 打印 set,元素按升序排序
for (const auto& item : set2) {
std::cout << item << " ";
}
return 0;
}
2. 插入元素
cpp
#include <iostream>
#include <set>
int main() {
std::set<int> set = {3, 1, 4};
// 插入新元素
set.insert(5);
set.insert(1); // 插入重复元素将失败
// 打印 set
for (const auto& item : set) {
std::cout << item << " ";
}
return 0;
}
3. 查找元素
cpp
#include <iostream>
#include <set>
int main() {
std::set<int> set = {3, 1, 4, 5};
// 查找元素
auto it = set.find(4);
if (it != set.end()) {
std::cout << "Found: " << *it << std::endl;
} else {
std::cout << "Not found!" << std::endl;
}
return 0;
}
4. 删除元素
cpp
#include <iostream>
#include <set>
int main() {
std::set<int> set = {3, 1, 4, 5};
// 删除指定元素
set.erase(4);
// 打印 set
for (const auto& item : set) {
std::cout << item << " ";
}
return 0;
}
unordered_set
unordered_set
是基于哈希表实现的集合,它不像 set
那样按照元素的顺序存储,而是根据哈希值来存储元素。unordered_set
提供常数时间复杂度的插入、查找和删除操作,适用于对元素顺序无要求的场景。
1. 创建 unordered_set
cpp
#include <iostream>
#include <unordered_set>
int main() {
// 创建一个空的 unordered_set
std::unordered_set<int> set1;
// 使用初始化列表初始化
std::unordered_set<int> set2 = {3, 1, 4, 1, 5, 9};
// 打印 unordered_set,元素顺序不确定
for (const auto& item : set2) {
std::cout << item << " ";
}
return 0;
}
2. 插入元素
cpp
#include <iostream>
#include <unordered_set>
int main() {
std::unordered_set<int> set = {3, 1, 4};
// 插入新元素
set.insert(5);
set.insert(1); // 插入重复元素将失败
// 打印 unordered_set,元素顺序不确定
for (const auto& item : set) {
std::cout << item << " ";
}
return 0;
}
3. 查找元素
cpp
#include <iostream>
#include <unordered_set>
int main() {
std::unordered_set<int> set = {3, 1, 4, 5};
// 查找元素
auto it = set.find(4);
if (it != set.end()) {
std::cout << "Found: " << *it << std::endl;
} else {
std::cout << "Not found!" << std::endl;
}
return 0;
}
4. 删除元素
cpp
#include <iostream>
#include <unordered_set>
int main() {
std::unordered_set<int> set = {3, 1, 4, 5};
// 删除指定元素
set.erase(4);
// 打印 unordered_set,元素顺序不确定
for (const auto& item : set) {
std::cout << item << " ";
}
return 0;
}
set 与 unordered_set 的区别
排序顺序:
set
是有序的,元素会按照键的顺序(升序)排列。unordered_set
是无序的,元素的顺序是根据哈希值决定的,不保证按任何顺序排列。
底层实现:
set
基于红黑树(自平衡二叉搜索树)实现,提供对数时间复杂度的查找、插入和删除操作。unordered_set
基于哈希表实现,提供常数时间复杂度的查找、插入和删除操作,但元素顺序不可预测。
性能:
set
适用于需要保持元素有序的场景,但它的操作复杂度较高(O(log n))。unordered_set
适用于不关心元素顺序、只关心快速查找和插入的场景,提供更好的性能(O(1) 平均时间复杂度)。
何时选择 set
或 unordered_set
使用
set
:- 当需要保持元素的有序性时。
- 当需要进行范围查找(如查找一个范围内的所有元素)时。
使用
unordered_set
:- 当不关心元素顺序,只需要快速查找、插入和删除时。
- 当对性能要求较高,且元素数量较大时。