39. Aplicaciones de conjuntos en estructuras de datos

Las estructuras de datos implementan ideas de conjuntos para almacenar valores únicos, asociar claves, indexar información, representar grafos y optimizar búsquedas.

39.1 Introducción

Las estructuras de datos permiten organizar información para consultarla, modificarla y recorrerla eficientemente. Muchas de ellas están basadas en ideas de teoría de conjuntos.

Un conjunto matemático se refleja en estructuras como Set, tablas hash, índices, mapas, grafos y colecciones de claves únicas.

39.2 Arreglos y conjuntos

Un arreglo almacena elementos en orden y puede contener duplicados. Un conjunto almacena valores únicos y no se centra en posiciones.

Estructura Orden Duplicados Uso típico
Array Importa Permite Secuencias, listas ordenadas
Set No es el criterio principal No permite Unicidad y pertenencia

39.3 Set en JavaScript

Set representa una colección de valores únicos.

const lenguajes = new Set(["JavaScript", "SQL", "JavaScript", "HTML"]);

console.log([...lenguajes]);
console.log(lenguajes.has("SQL"));
console.log(lenguajes.size);

La estructura elimina duplicados y permite consultar pertenencia.

39.4 Tablas hash

Muchas implementaciones de conjuntos usan internamente tablas hash. Una tabla hash permite ubicar elementos rápidamente a partir de una clave.

clave → función hash → posición interna

El objetivo es que operaciones como agregar, buscar y eliminar sean eficientes.

39.5 Map como relación clave-valor

Un Map asocia claves con valores. Puede interpretarse como una relación funcional donde cada clave tiene un único valor asociado.

const precios = new Map();

precios.set("teclado", 12000);
precios.set("mouse", 8000);

console.log(precios.get("teclado"));
console.log(precios.has("mouse"));

Las claves del mapa forman un conjunto de valores únicos.

39.6 Conjunto de claves

Las claves de un mapa pueden verse como un conjunto.

const precios = new Map();

precios.set("teclado", 12000);
precios.set("mouse", 8000);

const productos = new Set(precios.keys());

console.log([...productos]);

Este conjunto contiene los productos que tienen precio registrado.

39.7 Índices

Un índice permite encontrar datos rápidamente. Conceptualmente, un índice puede verse como una relación entre una clave y los elementos que cumplen una propiedad.

const usuarios = [
  { id: 1, nombre: "Ana", rol: "admin" },
  { id: 2, nombre: "Luis", rol: "editor" },
  { id: 3, nombre: "Carla", rol: "admin" }
];

const idsPorRol = new Map();

for (const usuario of usuarios) {
  if (!idsPorRol.has(usuario.rol)) {
    idsPorRol.set(usuario.rol, new Set());
  }
  idsPorRol.get(usuario.rol).add(usuario.id);
}

console.log([...idsPorRol.get("admin")]);

El índice asocia cada rol con el conjunto de usuarios que lo tienen.

39.8 Grafos como conjuntos

Un grafo puede representarse mediante un conjunto de nodos y un conjunto de aristas.

G = (V, E) V: conjunto de vértices E: conjunto de aristas

Las aristas pueden verse como pares ordenados o no ordenados, según el grafo sea dirigido o no dirigido.

39.9 Lista de adyacencia

Una lista de adyacencia puede usar mapas y conjuntos para representar vecinos.

const grafo = new Map();

grafo.set("A", new Set(["B", "C"]));
grafo.set("B", new Set(["C"]));
grafo.set("C", new Set());

console.log([...grafo.get("A")]);

Cada nodo se asocia con el conjunto de nodos alcanzables directamente.

39.10 Conjuntos para recorrido de grafos

Durante el recorrido de un grafo, un conjunto de visitados evita procesar el mismo nodo más de una vez.

const grafo = new Map();

grafo.set("A", new Set(["B", "C"]));
grafo.set("B", new Set(["C"]));
grafo.set("C", new Set());

function recorrer(inicio, grafo) {
  const visitados = new Set();
  const pila = [inicio];

  while (pila.length) {
    const nodo = pila.pop();
    if (visitados.has(nodo)) continue;
    visitados.add(nodo);

    for (const vecino of grafo.get(nodo) ?? []) {
      pila.push(vecino);
    }
  }

  return visitados;
}

console.log([...recorrer("A", grafo)]);

El conjunto visitados controla pertenencia y evita ciclos infinitos.

39.11 Cachés y conjuntos

Un conjunto puede registrar elementos ya procesados para no repetir trabajo.

const procesados = new Set();

function procesar(id) {
  if (procesados.has(id)) {
    return "ya procesado";
  }
  procesados.add(id);
  return "procesado";
}

console.log(procesar(10));
console.log(procesar(10));

Esta técnica aparece en importaciones, sincronizaciones y tareas repetibles.

39.12 Colas de prioridad y conjuntos auxiliares

Algunas estructuras necesitan combinar una cola o lista ordenada con un conjunto auxiliar para consultas rápidas de pertenencia.

Cola: mantiene orden de procesamiento Set: indica si un elemento ya está en espera

Combinar estructuras permite aprovechar fortalezas distintas.

39.13 Conjuntos y normalización de datos

Los conjuntos ayudan a normalizar datos cuando necesitamos valores únicos.

const correos = [
  "ANA@correo.com",
  "ana@correo.com",
  "luis@correo.com"
];

const correosNormalizados = new Set(
  correos.map(correo => correo.toLowerCase())
);

console.log([...correosNormalizados]);

Primero se normalizan los valores y luego se eliminan duplicados.

39.14 Comparación de estructuras

Estructura Idea de conjuntos Uso
Set Colección de valores únicos Pertenencia y duplicados
Map Relación funcional clave-valor Índices y asociaciones
Grafo Conjunto de nodos y aristas Redes y dependencias
Índice invertido Clave asociada a conjunto de documentos Búsqueda
Caché de visitados Conjunto de elementos procesados Evitar repeticiones

39.15 Aplicaciones prácticas

  • Eliminar duplicados en listas de datos.
  • Controlar nodos visitados en recorridos de grafos.
  • Construir índices por categoría, rol o etiqueta.
  • Representar relaciones clave-valor con mapas.
  • Validar pertenencia a conjuntos de permisos o estados.
  • Comparar resultados esperados y obtenidos en pruebas.

39.16 Errores frecuentes

  • Usar un arreglo cuando se necesita consulta rápida de pertenencia.
  • Olvidar que Set compara objetos por referencia.
  • Confundir clave única con valor único en un Map.
  • No normalizar datos antes de agregarlos a un conjunto.
  • Usar una sola estructura para todo cuando conviene combinar varias.

39.17 Qué debes recordar de este tema

  • Set implementa la idea de colección de valores únicos.
  • Map puede interpretarse como una relación funcional entre claves y valores.
  • Los grafos usan conjuntos de nodos y aristas.
  • Los conjuntos auxiliares ayudan a evitar duplicados y ciclos.
  • Los índices relacionan claves con conjuntos de elementos.
  • Las ideas de conjuntos ayudan a elegir estructuras de datos adecuadas.

39.18 Conclusión

Las estructuras de datos aplican conceptos de teoría de conjuntos para representar unicidad, pertenencia, relaciones, índices y conexiones. Entender estas ideas permite elegir estructuras más adecuadas y diseñar algoritmos más claros.

En el próximo tema estudiaremos aplicaciones de conjuntos en bases de datos y SQL.