📅  最后修改于: 2023-12-03 15:13:45.535000             🧑  作者: Mango
在C++中,STL提供了set,multiset,unordered_set和unordered_multiset四种关联式容器。这些容器在存储方面非常类似,但在查找、插入和删除等操作的效率和方式上有所不同。下面将对它们进行详细介绍。
set是一种基于红黑树(Red-Black Tree)实现的关联式容器,在每个结点中保存一个关键字,且所有结点都按照关键字进行排序。因此,set中的元素不允许出现重复。set支持O(log n)的查找、插入和删除操作。
#include <set>
#include <iostream>
using namespace std;
int main() {
set<int> s;
s.insert(1);
s.insert(3);
s.insert(2);
s.insert(3);
for (auto x : s) {
cout << x << " "; // 输出 1 2 3
}
return 0;
}
multiset与set非常类似,也是一种基于红黑树实现的关联式容器,但multiset中允许出现重复元素。因此,查找、插入和删除操作的效率与set相同。与set相比,multiset多了count()函数,可以快速得到某个元素在multiset中的出现次数。
#include <set>
#include <iostream>
using namespace std;
int main() {
multiset<int> ms;
ms.insert(1);
ms.insert(2);
ms.insert(2);
cout << ms.count(2) << endl; // 输出 2
return 0;
}
unordered_set是一种基于哈希表(Hash Table)实现的关联式容器,其中的元素不排序,也不保证存储的顺序。因此,unordered_set支持O(1)的查找、插入和删除操作,但效率不如set和multiset。在哈希表中,每个元素都对应着一个哈希值,这个哈希值决定了该元素的存储位置。不同的元素可能会有相同的哈希值,这个现象称为哈希冲突(Hash Collision)。unordered_set使用拉链法(Chaining)来解决哈希冲突。
#include <unordered_set>
#include <iostream>
using namespace std;
int main() {
unordered_set<int> us;
us.insert(1);
us.insert(3);
us.insert(2);
us.insert(3);
for (auto x : us) {
cout << x << " "; // 输出 1 2 3
}
return 0;
}
与unordered_set相似,unordered_multiset也是基于哈希表实现的关联式容器,其中允许出现重复元素。
#include <unordered_set>
#include <iostream>
using namespace std;
int main() {
unordered_multiset<int> ums;
ums.insert(1);
ums.insert(2);
ums.insert(2);
cout << ums.count(2) << endl; // 输出 2
return 0;
}
总的来说,set和multiset适用于有序集合的场景,unordered_set和unordered_multiset适用于无序集合的场景。在实际使用中,应根据具体的需求选择合适的容器。