Cómo elegir una estructura de datos
Entre 1023 claves, una búsqueda lineal de una clave ausente hace 1023 comparaciones, la búsqueda binaria hace 10 y una tabla hash con 1023 cubetas hizo 6 como máximo en el laboratorio.
Empieza por las preguntas que vas a hacer
Ninguna estructura es la mejor para todo. Cada una abarata algunas operaciones encareciendo otras, así que la forma de elegir es enumerar lo que tu programa hará con más frecuencia. El 6.006 del MIT divide las posibilidades en dos interfaces. Una secuencia guarda los elementos en un orden que tú decides (primero, segundo, tercero), y los pides por posición. Un conjunto (set) guarda los elementos por clave, y preguntas si una clave está, o cuál es la más pequeña, o cuál sigue después de una clave dada. Un conjunto sin las preguntas de orden se llama diccionario.
Algunas situaciones comunes y la respuesta habitual:
- Leer elementos por posición, agregar al final: un arreglo dinámico (un arreglo de JavaScript).
- Historial de deshacer, emparejar paréntesis, búsqueda en profundidad: una pila, que es un arreglo que solo se usa por el final.
- Trabajos atendidos en orden de llegada, búsqueda en anchura: una cola, con un índice head o un búfer circular en lugar de shift sobre un arreglo largo.
- Buscar cosas por nombre o id: una tabla hash, que en JavaScript significa Map o Set.
- Mantener las claves ordenadas mientras se insertan y eliminan, pedir la clave siguiente: un árbol binario de búsqueda equilibrado.
- Muchas inserciones y eliminaciones en un lugar que ya tienes ubicado: una lista enlazada.
La misma búsqueda en cinco estructuras
El laboratorio de abajo guarda las mismas claves de cinco maneras y cuenta las comparaciones necesarias para encontrar una de ellas. Las claves son 15, 127 o 1023 números enteros al azar. El arreglo sin ordenar usa búsqueda lineal. El arreglo ordenado usa búsqueda binaria. El árbol equilibrado se construyó insertando primero las claves del medio, así que es lo más bajo posible. El otro árbol se construyó con las claves en orden, así que es una cadena. La tabla hash tiene tantas cubetas como claves y cuenta 1 por calcular h(k).
Arrastra para girar. Desplaza o pellizca para acercar.
Con 15 claves las diferencias son pequeñas: la búsqueda lineal necesita 8 comparaciones en promedio y la binaria, unas 3.3. Con 1023 claves ya no lo son. La búsqueda lineal promedia 512 y necesita 1023 para una clave ausente, mientras que la búsqueda binaria y el árbol equilibrado nunca necesitan más de 10. El árbol en cadena es tan malo como la búsqueda lineal. La tabla hash se mantiene entre 2.3 y 2.5 en promedio en todos los tamaños porque sus cadenas siguen cortas, y en este laboratorio su peor caso con 1023 claves fue 6. Por eso Map es la opción predeterminada para las búsquedas, y por eso las estructuras ordenadas solo valen la pena cuando también necesitas el orden.
| Por posición | Obtener el elemento i | Insertar o eliminar al principio |
|---|---|---|
| Arreglo dinámico | 1 | n |
| Lista enlazada | n | 1 |
| Arreglo ordenado | 1 | n |
| Por clave | Buscar | Insertar | Clave siguiente |
|---|---|---|---|
| Arreglo o lista | n | n | n |
| Arreglo ordenado | log n | n | log n |
| Tabla hash | 1 en promedio | 1 en promedio | n |
| ABB equilibrado | log n | log n | log n |
Cada celda de estas dos tablas es la tasa de crecimiento del costo para n elementos, según las tablas de las notas de clase 2, 4 y 7 del MIT. Las tablas hash y los árboles de búsqueda solo aparecen en la segunda tabla porque trabajan por clave, no por posición. En un arreglo sin ordenar o en una lista, insertar una clave cuesta n porque primero hay que comprobar que no esté ya. El arreglo ordenado encuentra rápido, pero tiene que mover valores para hacer sitio a una clave nueva.
¿Map u objeto?
Los programas de JavaScript suelen usar un objeto normal como diccionario, escribiendo prices["apple"]. MDN da razones para preferir Map cuando las claves vienen de los datos: un objeto tiene un prototipo, así que contiene claves predeterminadas que podrían chocar con las tuyas; un Map puede usar cualquier valor como clave, no solo cadenas y símbolos; su tamaño es una sola propiedad, map.size; y se recorre en orden de inserción. Los objetos siguen siendo la opción natural para registros con un conjunto fijo de campos con nombre.
- 1953: El memorando de IBM de H. P. Luhn propone el hashing en cubetas con encadenamiento.
- Hacia 1956: El IPL de Newell, Shaw y Simon trae las listas enlazadas.
- 1957: Bauer y Samelson solicitan una patente del método de la pila; Fortran sale con arreglos.
- 1962: Adelson-Velsky y Landis publican el árbol AVL, el primer árbol de búsqueda equilibrado.
- 2015: ECMAScript 2015 agrega Map y Set a JavaScript.
- Una búsqueda lineal de una clave ausente entre 1023 claves, ¿cuántas comparaciones hace?
- Una búsqueda binaria entre 1023 claves ordenadas, ¿cuántas comparaciones hace como máximo?
- Búsqueda lineal sobre 15 claves: ¿cuál es el número promedio de comparaciones sobre las 15 claves?
- Un ABB construido con 127 claves insertadas en orden: ¿cuántas comparaciones para la clave más grande?
- Un editor de texto necesita Deshacer. ¿Qué estructura conviene?
- Cola
- Pila
- Tabla hash
- Arreglo ordenado
- Un servidor de impresión debe atender los trabajos en el orden en que llegan. ¿Qué estructura conviene?
- Cola
- Pila
- ABB
- Lista enlazada usada como pila
- Debes buscar el registro de un usuario por su id muchas veces por segundo. ¿Cuál es la opción habitual en JavaScript?
- Un arreglo recorrido con un bucle
- Un Map con el id como clave
- Una pila
- Una lista enlazada
- Necesitas mantener las claves ordenadas mientras insertas y eliminas, y a menudo pides la clave siguiente más grande. ¿Qué conviene más?
- Tabla hash
- ABB equilibrado
- Cola
- Arreglo sin ordenar
- En los términos del 6.006 del MIT, un conjunto sin las operaciones de orden se llama
- una secuencia
- un diccionario
- una pila
- una cola
- Según MDN, ¿por qué puede ser arriesgado usar un objeto normal como diccionario para claves que vienen de los datos?
- Los objetos no pueden contener cadenas
- Su prototipo trae claves predeterminadas que pueden chocar con las tuyas
- Los objetos siempre son más lentos que los arreglos
- Los objetos olvidan los valores al cabo de un segundo
- Elige según las operaciones que harás con más frecuencia.
- Secuencia: arreglo, lista enlazada, pila, cola. Conjunto: tabla hash, ABB.
- Con 1023 claves: búsqueda lineal hasta 1023 comparaciones, búsqueda binaria y árbol equilibrado hasta 10.
- Map es el diccionario habitual en JavaScript; usa un árbol equilibrado cuando también necesitas el orden.
Fuentes de este curso (11)
- MIT OpenCourseWare 6.006 Introduction to Algorithms, Spring 2020 (Demaine, Ku, Solomon)
- lecture notes 2 Data Structures (interface vs data structure, Sequence and Set interfaces, stack = insert_last/delete_last, queue = insert_last/delete_first, array, linked list, dynamic array, amortized Θ(1) append)
- 4 Hashing (chaining, pigeonhole collisions, chain length n/m)
- 6 Binary Trees Part 1 (height, traversal order, O(h) operations) and 7 Binary Trees Part 2: AVL (Adelson-Velsky and Landis, 1962) at ocw.mit.edu/courses/6-006-introduction-to-algorithms-spring-2020/pages/lecture-notes
- MDN Web Docs, Array.prototype.shift (shifts all values left by 1)
- Array.prototype.unshift, Map (insertion order, Map vs Object, spec requires sublinear average access) and Set (developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects)
- ECMAScript 2025 Language Specification (tc39.es/ecma262)
- 24.1 Map Objects and 24.2 Set Objects ("must be implemented using either hash tables or other mechanisms that, on average, provide access times that are sublinear on the number of elements")
- Array.prototype.shift steps (Repeat, while k < len: move element k to k - 1)
- D. E. Knuth, The Art of Computer Programming vol. 3 (2nd ed. 1998) section 6.4 History (H. P. Luhn, IBM internal memorandum January 1953, hashing with chaining; digit pairs added mod 10, 31415926 -> 4548) via gwern.net copy, and IEEE Spectrum, "Hans Peter Luhn and the Birth of the Hashing Algorithm" (2018)
- "A brief history of the stack", SIGCIS (sigcis.org/files/A brief history.pdf: Bauer and Samelson applied for the patent in 1957, US 3,047,228 granted July 31, 1962; IPL list processing by Newell, Simon and Shaw at RAND 1956) and Wikipedia, Information Processing Language (Newell, Shaw, Simon, RAND and Carnegie Institute of Technology, about 1956).
Fecha de consulta: 2026-10-18