C++11 新特性: unordered_map 与 map 的对比

原创
2022/03/08 16:36
阅读数 210

unordered_map和map类似,都是存储的key-value的值,可以通过key快速索引到value。不同的是unordered_map不会根据key的大小进行排序,
存储时是根据key的hash值判断元素是否相同,即unordered_map内部元素是无序的,而map中的元素是按照二叉搜索树存储,进行中序遍历会得到有序遍历。
所以使用时map的key需要定义operator<。而unordered_map需要定义hash_value函数并且重载operator==。但是很多系统内置的数据类型都自带这些,
那么如果是自定义类型,那么就需要自己重载operator<或者hash_value()了。

unordered_map和map类似,都是存储的key-value的值,可以通过key快速索引到value。不同的是unordered_map不会根据key的大小进行排序,存储时是根据key的hash值判断元素是否相同,即unordered_map内部元素是无序的。unordered_map的底层是一个防冗余的哈希表(开链法避免地址冲突)。unordered_map的key需要定义hash_value函数并且重载operator ==。
哈希表最大的优点,就是把数据的存储和查找消耗的时间大大降低,时间复杂度为O(1);
unordered_map使用
unordered_map内部使用哈希表进行存储与搜索。由于需要使用hash来进行映射,因此需要判断两个关键字是否相等,对于内部类型,可以直接进行判断,如果是用户自定义类型,则需要重载"=="运算符,指定如何判断两个关键字是否相等。以下是在网上摘录的一段代码,个人觉得比较详细的unordered_map的使用方法,这里只是其中一种使用方法:利用函数对象。(若有侵权,请联系我删除)

 

结论:如果需要内部元素自动排序,使用map,不需要排序使用unordered_map

 

 

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

struct Person
{
    string name;
    int age;

    Person(string name, int age)
    {
        this->name =  name;
        this->age = age;
    }

};

/* the object of hash function */
struct PersonHash
{
    size_t operator()(const Person& per) const{
        return hash<string>()(per.name) ^ hash<int>()(per.age);
    }
};

/* the object of compare */
struct PersonCmp
{
    bool operator()(const Person& pera, const Person& perb) const{
        return pera.name == perb.name && pera.age == perb.age;
    }
};

/* define the unordered_map type */
typedef unordered_map<Person, int, PersonHash, PersonCmp> umap;


int main()
{

    umap m;


    Person p1("Tom1",20);
    Person p2("Tom2",22);
    Person p3("Tom3",22);
    Person p4("Tom4",23);
    Person p5("Tom5",24);
    m.insert(umap::value_type(p3, 100));
    m.insert(umap::value_type(p4, 100));
    m.insert(umap::value_type(p5, 100));
    m.insert(umap::value_type(p1, 100));
    m.insert(umap::value_type(p2, 100));        
    
    /* 这里打印出来的顺序于插入顺序并不相同,确切的说是完全无序的 */
    for(umap::iterator iter = m.begin(); iter != m.end(); iter++)
    {
        cout << iter->first.name << "\t" << iter->first.age << endl;
    }        


    return 0;
}

展开阅读全文
加载中
点击引领话题📣 发布并加入讨论🔥
0 评论
0 收藏
0
分享
返回顶部
顶部