Algoritmos en JavaScript
Arreglos (Arrays)
Estructura de datos que organiza datos secuencialmente en memoria contigua.
- O(1) lectura indexada
- O(n) inserción/eliminación aleatoria
- O(n) búsqueda
|
|
Ordenamiento
El ordenamiento es el proceso de reorganizar los datos en un arreglo, de modo que se almacenen en orden ascendente o descendente. Existen muchos algoritmos para ordenar, pero la mejor complejidad es O(nlogn).
|
|
Quicksort
El algoritmo de ordenamiento más común, es la implementación incorporada en muchos lenguajes. Este algoritmo es muy adecuado para ordenar arreglos en su lugar.
Esta técnica utiliza divide y vencerás para dividir el problema en subproblemas más pequeños seleccionando un pivote en el arreglo y comparando el resto con el pivote.
- O(nlogn) - complejidad
|
|
Merge Sort
Es una técnica recursiva para ordenar un arreglo, es muy común para el ordenamiento paralelo porque puede dividir los datos entre muchos procesos.
Este algoritmo utiliza una técnica de divide y vencerás y funciona muy bien porque fusionar arreglos ya ordenados es una operación O(n).
- O(nlogn) - complejidad
|
|
Búsqueda Binaria
Este algoritmo mejora la búsqueda en listas que están ordenadas. Generalmente, buscar un valor en una lista tiene complejidad O(n), pero si la lista ya está ordenada, esta técnica puede hacerlo en O(logn), lo cual es mucho mejor.
Esta técnica utiliza un enfoque de divide y vencerás para reducir el espacio de búsqueda saltando valores irrelevantes.
- O(logn) - complejidad
Si el elemento no se encuentra, el elemento debería estar en la posición anotada con left.
|
|
Dos Punteros
Técnica para recorrer un arreglo y encontrar un subarreglo, es útil en problemas donde la solución ingenua es un doble bucle. Los problemas comunes están relacionados con subarreglos o intervalos, aprovechando un arreglo ordenado.
|
|
Intervalos
Los intervalos representan rangos definidos por un punto de inicio y fin, comúnmente usados en problemas de programación y rango. Un enfoque común es ordenar los intervalos por tiempos de inicio o fin para simplificar las comparaciones y reducir la complejidad temporal.
|
|
Lista Enlazada (Linked List)
Una Lista Enlazada es una estructura de datos que almacena elementos secuencialmente, pero con nodos dispersos aleatoriamente en memoria. Cada nodo contiene un valor y un puntero al siguiente nodo.
Las Listas Enlazadas permiten una inserción/eliminación eficiente en ambos extremos, pero no admiten acceso indexado.
|
|
La lista enlazada puede ser doblemente enlazada y almacenar un puntero al elemento anterior también.
Para iterar a través de una lista, puede verificar los siguientes nodos hasta que no pueda.
|
|
Pila y Cola (Stack and Queue)
Estas son estructuras de datos enfocadas en acceder a un extremo. La pila es una colección de tipo Último en Entrar, Primero en Salir (LIFO), mientras que una cola es una colección de tipo Primero en Entrar, Primero en Salir (FIFO). Pueden implementarse fácilmente, pero JavaScript ya tiene una implementación.
- O(1) - agregar o eliminar de los extremos
- O(n) - búsqueda y acceso indexado
|
|
Hashmap
El Hashmap es una estructura de datos que almacena pares clave/valor. Los valores pueden leerse eficientemente usando la clave. Funciona hashando la clave para almacenar valores en una tabla.
- O(1) - lectura y escritura si se proporciona la clave
- O(n) - si no se proporciona la clave
|
|
Conjunto (Hashset)
Es un caso especial de hashmap en el cual los valores son de tipo booleanos. Esta estructura de datos se utiliza para representar conjuntos y generalmente viene con operaciones de álgebra de conjuntos eficientes.
- O(1) - leer y escribir un valor particular
- O(n) - la mayoría de las operaciones de conjunto
|
|
Diccionario Ordenado (Ordered Dictionary)
Los diccionarios regulares no garantizan ningún orden en particular al iterar sus valores. Sin embargo, un Diccionario Ordenado es un Hashmap especializado que mantiene el orden de inserción, permitiendo la iteración sobre los elementos en la misma secuencia en que fueron agregados.
Esto se logra utilizando memoria adicional para almacenar el orden de inserción, típicamente usando una lista enlazada.
|
|
Cola de Prioridad (Priority Queue)
La Cola de Prioridad, también conocida como PQ, es una estructura de datos cuyo objetivo es dar acceso a elementos basados en su prioridad asignada. La cola mantiene un orden de prioridad tal que los elementos con mayor prioridad (o menor, dependiendo de la implementación) siempre se acceden primero.
Esta estructura de datos se implementa comúnmente con montículos (heaps), un tipo especial de árbol binario que asegura que el elemento de mayor prioridad sea accesible eficientemente después de operaciones de agregar o eliminar.
- O(1) - leer el elemento de mayor prioridad
- O(logn) - insertar o eliminar un elemento
JavaScript no tiene una Cola de Prioridad incorporada en su biblioteca estándar, pero puedes implementar una usando una clase personalizada o utilizar bibliotecas de terceros.
|
|
Mapas de Bits (Bitmaps)
Estructura de datos que almacena eficientemente valores de bits en un arreglo, los bits pueden representar valores booleanos y el propio arreglo puede representar conjuntos. Esta estructura de datos es menos flexible que un conjunto, pero puede ser muy eficiente en memoria y tiempo.
- O(1) - escribir y leer un valor binario
- O(1) - álgebra de conjuntos
|
|
Grafos
Estructura de datos que organiza datos en términos de sus relaciones.
Árbol
Estructura de datos de grafo que organiza datos en formato jerárquico y no tiene ciclos. A menudo se representa como una clase con punteros recursivos a sus hijos.
|
|
Árbol Binario
Es un caso especial de un árbol donde cada nodo tiene como máximo 2 hijos. Esta estructura de datos se suele representar con hijos izquierdo y derecho.
|
|
Búsqueda en Profundidad (Depth-First Search)
También conocido como DFS, es una técnica algorítmica para recorrer un grafo o árbol visitando cada ruta en profundidad y luego visitando otras rutas. Es útil cuando el problema requiere una comparación de escenarios finales de cada ruta.
Al recorrer un árbol, el procesamiento del valor puede ocurrir antes de visitar el resto de la ruta o después; esto se llama recorrido en preorden o postorden.
- O(n) - complejidad temporal
- O(h) - complejidad de memoria, donde h es la altura del árbol
- O(n) - peor caso de complejidad de memoria, si el árbol está sesgado
- O(logn) - complejidad de memoria si el árbol está equilibrado
|
|
Búsqueda en Anchura (Breadth-First Search)
También llamada BFS, es una técnica para recorrer un grafo o árbol en niveles. Puede ser útil para encontrar el camino más corto desde la raíz, pero también puede ser menos eficiente en memoria para rutas largas.
- O(n) - complejidad temporal
|
|
Backtracking
Una técnica algorítmica para recorrer un arreglo y procesar no solo el valor sino el camino tomado hasta el valor. Esto es especialmente útil al modelar decisiones como un árbol y comparar resultados, por ejemplo en juegos.
|
|
El backtracking también puede implementarse de manera recursiva, y a veces puede ser un poco más fácil pensar en este algoritmo de esta manera.
|
|