STL中几种set和map的区别

460 阅读2分钟

1. 底层实现

map/multimap:底层实现是红黑树

set/multiset:底层实现是红黑树

unordered_map/unordered_multimap:底层实现是哈希表

unordered_set/unordered_multiset:底层实现是哈希表

2. 关联容器类型

按关键字有序保存元素
map关联数组:保存关键字-值对
set关键字即值,即只保存关键字的容器
multimap关键字可重复出现的 map
multiset关键字可重复出现的 set
无序集合
unordered_map用哈希函数组织的 map
unordered_set用哈希函数组织的 set
multimap哈希组织的 map:关键字可以重复出现
multiset哈希组织的 set:关键字可以重复出现

3. 使用

map、unordered_map 和 multimap

(1)由于map和unordered_map不允许两个元素具有相同的关键字,而multimap允许若干元素具有相同的关键字。

因此,map和unordered_map都能够使用下标运算符,通过关键字直接访问元素的值,而multimap则不允许。

示例

我们遍历字符串"abcdefghhh",并将每个字符和其下标存储到map、unordered_map和multimap中。

使用下标运算符向map和unordered_map中插入元素,使用insert()函数向multimap中插入元素,

通过输出观察不同map的区别。

#include <iostream>
#include <map>
#include <unordered_map>
using namespace std;

int main()
{
    string s = "abcdefghhh";
    map<char, int> m1;
    unordered_map<char, int> m2;
    multimap<char, int> m3;

    for (int i = 0; i < s.size(); ++i)
    {
        m1[s[i]] = i;
        m2[s[i]] = i;
        m3.insert(make_pair(s[i], i));
    }

    cout << "map的键值:" << endl;
    for (auto e : m1)
    {
        cout << e.first << " " << e.second << endl;
    }
    cout << endl;

    cout << "unordered_map的键值:" << endl;
    for (auto e : m2)
    {
        cout << e.first << " " << e.second << endl;
    }
    cout << endl;

    cout << "multimap的键值:" << endl;
    for (auto e : m3)
    {
        cout << e.first << " " << e.second << endl;
    }
}

image.png

(2)对map使用下标运算符,若key不存在,访问仍然成功,取得value对象默认构造的值。

具体如下

用[]访问,但key不存在时,C++会利用该key及默认构造的value,组成{key,value}对,插入到map中。

因此在访问map元素时,应先用map.find查找该元素,找到后再访问。