Sobes.tech
Middle

¿Cuándo se debe usar std::set y cuándo std::unordered_set en C++?

sobes.tech AI

Respuesta de la IA

std::set y std::unordered_set se utilizan para almacenar elementos únicos. La elección entre ellos depende de las prioridades: ordenamiento o rendimiento en acceso/inserción/eliminación.

std::set se basa en un árbol binario de búsqueda equilibrado (generalmente un árbol rojo-negro).

Características de std::set:

  • Los elementos se almacenan en orden ordenado.
  • La inserción, eliminación y búsqueda de elementos toman tiempo O(log N), donde N es la cantidad de elementos.
  • Es adecuado cuando se requiere un ordenamiento de los elementos o cuando se necesita obtener elementos en un rango específico.

std::unordered_set se basa en una tabla hash.

Características de std::unordered_set:

  • Los elementos no se almacenan en orden ordenado.
  • La inserción, eliminación y búsqueda de elementos en promedio toman tiempo O(1), pero en el peor caso (con muchas colisiones en la función hash) puede llegar a O(N).
  • Requiere que el tipo de elemento tenga una función hash definida (std::hash) y un operador de comparación de igualdad (operator==).
  • Es adecuado cuando se requiere la inserción, eliminación y búsqueda más rápidas posibles, y el orden de los elementos no importa.

Tabla resumen:

Criterio std::set std::unordered_set
Estructura interna Árbol equilibrado Tabla hash
Orden de los elementos Ordenado No ordenado
Tiempo de búsqueda/inserción/eliminación (promedio) O(log N) O(1)
Tiempo de búsqueda/inserción/eliminación (peor caso) O(log N) O(N)
Requisitos del tipo Operador < std::hash, operator==

Ejemplo de uso de std::set:

#include <iostream>
#include <set>

int main() {
    std::set<int> ordered_set;
    ordered_set.insert(5);
    ordered_set.insert(2);
    ordered_set.insert(8);

    // Los elementos se imprimirán en orden: 2 5 8
    for (int val : ordered_set) {
        std::cout << val << " ";
    }
    std::cout << std::endl;

    return 0;
}

Ejemplo de uso de std::unordered_set:

#include <iostream>
#include <unordered_set>

int main() {
    std::unordered_set<int> unordered_set;
    unordered_set.insert(5);
    unordered_set.insert(2);
    unordered_set.insert(8);

    // El orden de salida puede variar
    for (int val : unordered_set) {
        std::cout << val << " ";
    }
    std::cout << std::endl;

    return 0;
}