Comparación del uso de map y unordered_map

Tanto la plantilla de clase unordered_map como la plantilla de clase de mapa describen dicho objeto: es un contenedor de longitud variable compuesto por std::pair<const Key, value>. Cada elemento en este contenedor almacena dos objetos, es decir, clave-valor. par.

mapa

Al usar el mapa, debe hacer referencia al archivo de encabezado ,它的类模板声明以及部分函数声明如下:

/**
 * 程序来自C++源码 bits/stl_map.h
 */
template<typename _Key,  // key 类型
        typename _Tp,    // value 类型
        typename _Compare = std::less<_Key>, // 用于比较两个元素的比较函数
        typename _Alloc = std::allocator<std::pair<const _Key, _Tp> > > // 分配器,同样的描述了容器在内存管理上的细节,不应该自己来处理,除非写自己的容器
class map {
    
    
private:
    /// 将一个红黑树转换成 [multi]map.
    typedef typename __gnu_cxx::__alloc_traits<_Alloc>::template
    rebind<value_type>::other _Pair_alloc_type;

    typedef _Rb_tree<key_type, value_type, _Select1st<value_type>,
    key_compare, _Pair_alloc_type> _Rep_type;
};

Dentro del mapa, se utiliza un árbol rojo y negro para organizar los datos, por lo que la clasificación de datos se implementa de forma predeterminada. Como se puede ver en el siguiente ejemplo, implementa el incremento de forma predeterminada ordenando por clave:

int main() {
    
    
    map<int, string> mapper;
    mapper.insert(make_pair(0, "Alice"));
    mapper[1] = "Bob";
    mapper.insert(map<int, string>::value_type(2, "Candy"));
    for (auto &iter : mapper) {
    
    
        cout << iter.first << " - " << iter.second << endl;
        /*
         * >: 输出如下,很明显的,它们在 key 的排序上是递增排列的
         * 0 - Alice
         * 1 - Bob
         * 2 - Candy
         */
    }
}

Sin embargo, el mapa ocupa más espacio en términos de almacenamiento, porque en un árbol rojo-negro, cada nodo debe guardar adicionalmente la conexión entre el nodo padre y el nodo hijo, por lo que cada nodo ocupa un gran espacio para mantener las propiedades del árbol rojo-negro.

mapa_desordenado

En el archivo de encabezado, introduzca <unordered_map> para usarlo. Para unordered_map, la característica más importante es la implementación interna, que utiliza una tabla hash (tabla hash, hash_table) para el almacenamiento de mapas. Su declaración de clase de plantilla y sus parámetros son los siguientes:

/**
 * 程序来自STL源码 bits/unordered_map.h
 */
template<typename _Key,  // key 类型 
        typename _Tp,    // value 类型
        typename _Hash = hash <_Key>,     // 哈希函数
        typename _Pred = equal_to <_Key>, // 用于比较两者是否相同的函数
        typename _Alloc = allocator <std::pair<const _Key, _Tp>>> // 分配器,描述了容器在内存管理上的细节,不应该自己来处理,除非写自己的容器
class unordered_map {
    
    
};

Dentro de unordered_map, la tabla hash se usa para organizar los datos y la clave de valor clave se asigna a una ubicación en la tabla hash para acceder. De acuerdo con las características de la función hash, la complejidad temporal de unordered_map para la búsqueda de elementos puede alcanzar O (1) Sin embargo, la disposición de sus elementos está desordenada. Los ejemplos específicos son los siguientes:

int main() {
    
    
    using namespace std;
    // 首先创建一个无序 map,它的 key 使用 int 类型,value 使用 string 类型
    unordered_map<int, string> unorderedMap;    
   
    // 三种插入新元素的方法,“茴”字有三种写法~
    unorderedMap.insert(make_pair(0, "Alice")); 
    unorderedMap[1] = "Bob";
    unorderedMap.insert(unordered_map<int, string>::value_type(2, "Candy"));
 
    // 对内部元素挨个输出
    for (auto iter = unorderedMap.begin(); iter != unorderedMap.end(); iter++) {
    
    
        cout << iter->first << " - " << iter->second << endl;
        /*
         * >: 输出如下,可以得知它们在 key 的排序上并没有顺序
         * 2 - Candy
         * 0 - Alice
         * 1 - Bob
         */
    }
}

Dado que unordered_map crea una tabla hash, lleva mucho tiempo crearla al principio, pero su velocidad de consulta es rápida ~ En circunstancias normales, no hay problema al usar unordered_map.

Resumir

mapa:

元素有序,并且具有自动排序的功能(因为红黑树具有自动排序的功能)
元素按照二叉搜索树存储的,也就是说,其左子树上所有节点的键值都小于根节点的键值,右子树所有节点的键值都大于根节点的键值,使用中序遍历可将键值按照从小到大遍历出来
空间占用率高,因为map内部实现了红黑树,虽然提高了运行效率,但是因为每一个节点都需要额外保存父节点、孩子节点和红/黑性质,使得每一个节点都占用大量的空间
适用情况:对顺序有要求的情况下,如排序等

mapa_desordenado:

元素无序。
查找速度非常的快。
哈希表的建立比较耗费时间
适用情况:对于查找问题
对于unordered_map或者unordered_set容器,其遍历顺序与创建该容器时输入元素的顺序是不一定一致的,遍历是按照哈希表从前往后依次遍历的
运行效率:unordered_map最高,而map效率较低但提供了稳定效率和有序的序列。

占用内存:map内存占用略低,unordered_map内存占用略高,而且是线性成比例的。

什么时候使用哪个? 需要无序容器,快速查找删除,不担心略高的内存时用unordered_map;有序容器稳定查找删除效率,内存很在意时候用map。

Supongo que te gusta

Origin blog.csdn.net/xiaojinger_123/article/details/127802340
Recomendado
Clasificación