The difference and connection between unordered_map and map

The difference between map and unordered_map in c++

head File

  • map: #include < map >
  • unordered_map: #include < unordered_map >

Internal implementation mechanism

  • map: A red-black tree is implemented inside the map, which has the function of automatic sorting, so all the elements inside the map are ordered , and each node of the red-black tree represents an element of the map. Therefore, for the map A series of operations such as searching, deleting, and adding are equivalent to performing such operations on the red-black tree, so the efficiency of the red-black tree determines the efficiency of the map.
  • unordered_map: unordered_map implements a hash table internally, so the arrangement order of its elements is messy and unordered

Advantages and disadvantages and applicability

  • map 
    • Advantages
      • Ordering, which is the biggest advantage of the map structure, the ordering of its elements will simplify a lot of operations in many applications
      • A red-black tree, which implements a red-black book internally makes many operations of map in lgnIt can be realized under the time complexity of lgn , so the efficiency is very high
    • shortcoming: 
      • The space occupancy rate is high, because the red-black tree is implemented inside the map, although the operation efficiency is improved, but because each node needs to additionally save the parent node, child node and red/black properties, each node takes up a lot of space
    • Where applicable, for those problems with ordering requirements, it is more efficient to use map
  • unordered_map 
    • advantage: 
      • Because the hash table is implemented internally, its lookup speed is very fast
    • shortcoming: 
      • The establishment of the hash table is time-consuming
    • Where applicable, unordered_map will be more efficient for search problems, so when you encounter search problems, you will often consider using unordered_map

note:

  • For an unordered_map or unordered_set container, the traversal order is not necessarily the same as the order of input elements when the container was created. The traversal is performed from front to back according to the hash table.

Similar to map, unordered_map stores key-value values, which can be quickly indexed to value by key. The difference is that unordered_map will not be sorted according to the size of the key,

When storing, it is judged whether the elements are the same according to the hash value of the key, that is, the internal elements of the unordered_map are unordered, and the elements in the map are stored according to the binary search tree, and in-order traversal will result in ordered traversal.

Therefore, the key of the map needs to define operator< when using it. And unordered_map needs to define the hash_value function and overload operator==. But many built-in data types in the system come with these,

Then if it is a custom type, then you need to overload operator< or hash_value().

Conclusion: If you need automatic sorting of internal elements, use map, no need to sort use unordered_map

// map的使用
#include<string>  
#include<iostream>  
#include<map>  

using namespace std;  

struct person  
{  
    string name;  
    int age;  

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

    bool operator < (const person& p) const  
    {  
        return this->age < p.age;   
    }  
};  

map<person,int> m;  
int main()  
{  
    person p1("Tom1",20);  
    person p2("Tom2",22);  
    person p3("Tom3",22);  
    person p4("Tom4",23);  
    person p5("Tom5",24);  
    m.insert(make_pair(p3, 100));  
    m.insert(make_pair(p4, 100));  
    m.insert(make_pair(p5, 100));  
    m.insert(make_pair(p1, 100));  
    m.insert(make_pair(p2, 100));  

    for(map<person, int>::iterator iter = m.begin(); iter != m.end(); iter++)  
    {  
        cout<<iter->first.name<<"\t"<<iter->first.age<<endl;  
    }  

    return 0;  
} 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45

The output is: (results sorted by age)

Tom1 20 
Tom3 22 
Tom4 23 
Tom5 24 
Because the age of Tom2 and Tom3 is the same, the operator< defined by us is only the age of comparison, so Tom3 covers Tom2, and there is no Tom2 in the result.

If the overload of operator< is as follows:

bool operator < (const person &p)const{
    return this->name < p.name;  
}
  • 1
  • 2
  • 3
输出结果: 按照 那么进行的排序,如果有那么相同则原来的那么会被覆盖

Tom1    20

Tom2    22

Tom3    22

Tom4    23

Tom5    24
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
// unordered_map的使用:
#include<string>  
#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;  
    }  

    bool operator== (const person& p) const  
    {  
        return name==p.name && age==p.age;  
    }  
};  

size_t hash_value(const person& p)  
{  
    size_t seed = 0;  
    std::hash_combine(seed, std::hash_value(p.name));  
    std::hash_combine(seed, std::hash_value(p.age));  
    return seed;  
}  

int main()  
{  
    typedef std::unordered_map<person,int> umap;  
    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;  
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53

The overloading of hash_value was unsuccessful, and an error was reported on vs2013.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=326301413&siteId=291194637