set 和 unordered_set
C++ 提供了两种常用的集合类型:set 和 unordered_set。这两者都用于存储唯一的元素,但它们在底层实现、元素的存储顺序和操作效率上有所不同。了解它们的特点和使用场景,可以帮助开发者根据需要选择合适的容器。
set
set 是一个基于红黑树实现的有序集合。它自动将元素按照键的顺序排列,并保证集合中的元素是唯一的。由于使用红黑树,set 提供对元素的对数时间复杂度查找、插入和删除操作。
1. 创建 set
#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. 插入元素
#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. 查找元素
#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. 删除元素
#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
#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. 插入元素
#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. 查找元素
#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. 删除元素
#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:- 当不关心元素顺序,只需要快速查找、插入和删除时。
- 当对性能要求较高,且元素数量较大时。
相关内容
- 算术运算符 本节将介绍 C++ 中的算术运算符,包括加法、减法、乘法、除法、取余等,帮助你理解如何进行基本的数学运算。
- 位运算符 本节将介绍 C++ 中的位运算符,帮助你理解如何操作整数的二进制位,并进行高效的数据处理。
- 类型转换 本节将介绍 C++ 中的类型转换,包括隐式转换、显式转换和强制类型转换等方式,帮助你理解如何处理不同类型的转换。
- 条件语句 本节将深入探讨 C++ 中的条件语句,包括 `if`、`else`、`else if` 以及 `switch` 语句。通过条件语句,程序可以根据不同的输入或状态...
- 分支跳转 本节将讲解 C++ 中的分支跳转语句,包括 `if`、`else`、`switch`、`break`、`continue` 和 `goto`,这些语句有助于控制...
- 逻辑与关系运算符 本节将介绍 C++ 中的逻辑运算符和关系运算符,帮助你理解如何处理布尔值以及进行条件判断。