当我们处理数据时,有时需要使用一些高效的数据结构来存储和管理元素。在C++中,我们有许多与此相关的容器类,如 树型结构:set
,map
,multiset
,multimap
; 哈希结构: unordered_set
和unordered_map
。这些容器提供了不同的特性和适用性,下面我们将逐个介绍它们。
1. set
:
set
是一个有序的容器,它只包含唯一的元素。当我们需要存储一组元素,并确保没有重复值时,set
是一个很好的选择。它基于红黑树实现,因此插入、删除和查找操作的时间复杂度都是O(log n)。set
的元素按升序排列。
#include <iostream>
#include <set>
using namespace std;
int main() {
// 创建一个set容器
set<int> mySet;
// 插入元素
mySet.insert(10);
mySet.insert(20);
mySet.insert(30);
// 查找元素
int key = 20;
auto it = mySet.find(key);
if (it != mySet.end()) {
cout << key << " is found in the set." << endl; // 20 is found in the set.
}
else {
cout << key << " is not found in the set." << endl;
}
// 删除元素
mySet.erase(20);
// 修改元素(set不支持直接修改元素值,需要先删除再插入)
mySet.erase(10);
mySet.insert(100);
// 遍历输出set中的元素
cout << "Set contains:";
for (const auto& elem : mySet) {
cout << " " << elem;
}
cout << std::endl; // Set contains : 30 100
return 0;
}
对于set
,可以在声明时传入自定义的比较函数或函数对象,来指定元素的排序规则。例如:
struct CustomCompare {
bool operator() (int a, int b) const {
// 自定义排序规则,这里以元素大小作为排序依据
return a > b;
}
};
std::set<int, CustomCompare> mySet;
2. map
:
map
是一个关联容器,它包含键值对(key-value)。每个键对应一个唯一的值,即每个键在map
中是唯一的。map
也是基于红黑树实现的,因此插入、删除和查找操作的时间复杂度都是O(log n)。
#include <iostream>
#include <map>
using namespace std;
int main() {
// 创建一个map容器,键为string类型,值为int类型
map<string, int> myMap;
// 插入键值对
myMap["apple"] = 5;
myMap["banana"] = 10;
myMap["cherry"] = 15;
// 查找元素
string key = "banana";
auto it = myMap.find(key);
if (it != myMap.end()) {
cout << key << " is found in the map with value: " << it->second << endl;
// banana is found in the map with value : 10
}
else {
std::cout << key << " is not found in the map." << std::endl;
}
// 删除元素
myMap.erase("banana");
// 修改元素
myMap["cherry"] = 20;
// 遍历输出map中的键值对
cout << "Map contains:";
for (const auto& pair : myMap) {
cout << " (" << pair.first << ", " << pair.second << ")";
}
cout << endl; // Map contains : (apple, 5) (cherry, 20)
return 0;
}
对于map
,同样可以使用自定义的比较函数或函数对象来定义键的排序规则。例如:
struct CustomCompare {
bool operator() (const std::string& a, const std::string& b) const {
// 自定义排序规则,这里以字符串长度作为排序依据
return a.length() < b.length();
}
};
std::map<std::string, int, CustomCompare> myMap;
3. multiset
:
multiset
是一个有序的容器,它允许存储多个相同的元素。与set
不同,multiset
可以包含重复值。它也是基于红黑树实现的,因此插入、删除和查找操作的时间复杂度都是O(log n)。multiset
的元素按升序排列。
4. multimap
:
multimap
是一个关联容器,它允许存储多个相同的键值对。与map
不同,multimap
可以包含重复的键。它也是基于红黑树实现的,因此插入、删除和查找操作的时间复杂度都是O(log n)。
5. unordered_set
:
unordered_set
是一个无序的容器,它包含唯一的元素。与set
类似,unordered_set
也用于存储一组唯一的值,但它使用哈希表来实现,因此插入、删除和查找操作的平均时间复杂度是O(1)。元素在容器中的位置并不固定。
6. unordered_map
:
unordered_map
是一个关联容器,它包含键值对(key-value)。与map
类似,unordered_map
也用于存储键值对,但它使用哈希表来实现,因此插入、删除和查找操作的平均时间复杂度是O(1)。元素在容器中的位置并不固定。
总结
综上所述,选择使用哪种容器取决于具体的需求。如果需要有序性和快速查找,可以选择set
和map
;如果需要快速查找且不需要有序性,可以选择unordered_set
和unordered_map
;如果需要允许重复元素或键,可以选择multiset
和multimap