📜  C ++中set,multiset,unordered_set,unordered_multiset之间的区别(1)

📅  最后修改于: 2023-12-03 15:13:45.535000             🧑  作者: Mango

C++中set,multiset,unordered_set,unordered_multiset之间的区别

在C++中,STL提供了set,multiset,unordered_set和unordered_multiset四种关联式容器。这些容器在存储方面非常类似,但在查找、插入和删除等操作的效率和方式上有所不同。下面将对它们进行详细介绍。

set

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

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

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_multiset

与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适用于无序集合的场景。在实际使用中,应根据具体的需求选择合适的容器。