📜  set,multiset,unordered_set,unordered_multiset之间的差异(1)

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

set,multiset,unordered_set,unordered_multiset之间的差异

在C++ STL中,set,multiset,unordered_set 和unordered_multiset都是关联容器(集合和多重集合),基于哈希表和红黑树实现,它们有相似之处,但也存在差异。

红黑树实现

set和multiset都是基于红黑树实现,其中set是值的唯一集合(元素不会重复),而multiset是值的多重集合(元素可以重复)。

红黑树是一棵自平衡二叉查找树,所有操作的平均时间复杂度都是O(log n)。因此,当需要使用有序集合时,set和multiset是不错的选择。

#include <set>
#include <iostream>
using namespace std;

int main()
{
    set<int> s;
    s.insert(10);
    s.insert(5);
    s.insert(15);
    s.insert(5);  // 5重复,不会被插入

    cout << "set: ";
    for (set<int>::iterator it = s.begin(); it != s.end(); ++it)
        cout << *it << " ";  // 输出: 5 10 15
    cout << endl;

    multiset<int> ms;
    ms.insert(10);
    ms.insert(5);
    ms.insert(15);
    ms.insert(5);  // 5可以重复被插入

    cout << "multiset: ";
    for (multiset<int>::iterator it = ms.begin(); it != ms.end(); ++it)
        cout << *it << " ";  // 输出: 5 5 10 15
    cout << endl;

    return 0;
}
哈希表实现

unordered_set和unordered_multiset是基于哈希表的实现,相比红黑树,哈希表具有更快的平均查找时间(常数时间O(1)),但是由于哈希冲突的存在,哈希表的最坏查找时间是O(n)。另外,哈希表需要使用哈希函数来计算元素的存储位置,不支持排序。

#include <unordered_set>
#include <iostream>
using namespace std;

int main()
{
    unordered_set<int> us;
    us.insert(10);
    us.insert(5);
    us.insert(15);
    us.insert(5);  // 5重复,不会被插入

    cout << "unordered_set: ";
    for (int x : us)
        cout << x << " ";  // 输出: 5 10 15
    cout << endl;

    unordered_multiset<int> ums;
    ums.insert(10);
    ums.insert(5);
    ums.insert(15);
    ums.insert(5);  // 5可以重复被插入

    cout << "unordered_multiset: ";
    for (int x : ums)
        cout << x << " ";  // 输出: 5 5 10 15
    cout << endl;

    return 0;
}

总结:

  1. set和multiset是基于红黑树实现,适合有序集合的使用场景。

  2. unordered_set和unordered_multiset是基于哈希表实现,适合无序集合的使用场景。

  3. set和unordered_set是值的唯一集合,multiset和unordered_multiset是值的多重集合。

  4. 访问无序容器中的元素的速度通常比有序容器要更快,但无序容器的查找时间可能会比有序容器慢。