Introducción: ¿por qué estudiar algoritmos y estructuras de datos en JavaScript?
Cualquier programa no es solo un conjunto de instrucciones, sino una forma de gestionar datos de manera eficiente. Para los desarrolladores principiantes en JavaScript (especialmente en el entorno Node.js), comprender los algoritmos y estructuras de datos no es solo una tarea académica, sino una habilidad práctica que afecta directamente el rendimiento y la legibilidad del código.
JavaScript es un lenguaje de tipado dinámico, pero eso no elimina la necesidad de saber cómo funcionan los arreglos, las pilas o las colas. Sin estos conocimientos, tu código puede volverse lento y la lógica, confusa. En este artículo, analizaremos las estructuras de datos y algoritmos básicos con ejemplos en Node.js que te ayudarán a escribir aplicaciones más eficientes.
Estructuras de datos principales en JavaScript (Node.js)
JavaScript incluye varias estructuras de datos integradas, pero para una comprensión profunda es necesario saber implementarlas manualmente. Esto te da control sobre la memoria y la velocidad de ejecución.
Arreglos (Array)
Los arreglos en JS son listas dinámicas. Son ideales para almacenar datos ordenados. Sin embargo, es importante recordar que insertar o eliminar un elemento al inicio del arreglo (unshift/shift) es una operación O(n), ya que requiere desplazar todos los elementos.
// Creación de un arregloconst fruits = ['apple', 'banana', 'cherry'];
// Agregar al final (O(1))fruits.push('orange');
// Eliminar del final (O(1))fruits.pop();
// Búsqueda de un elemento (O(n))const index = fruits.indexOf('banana');console.log(index); // 1Pilas (Stack)
La pila funciona bajo el principio LIFO (Last In, First Out). Es una estructura indispensable para procesar llamadas a funciones, deshacer acciones (undo) o verificar paréntesis en el código.
class Stack { constructor() { this.items = []; }
push(element) { this.items.push(element); }
pop() { if (this.isEmpty()) return null; return this.items.pop(); }
peek() { return this.items[this.items.length - 1]; }
isEmpty() { return this.items.length === 0; }}
// Ejemplo de uso: verificación de paréntesisconst stack = new Stack();const str = '({[]})';let isValid = true;
for (let char of str) { if (char === '(' || char === '{' || char === '[') { stack.push(char); } else { const last = stack.pop(); if ( (char === ')' && last !== '(') || (char === '}' && last !== '{') || (char === ']' && last !== '[') ) { isValid = false; break; } }}
console.log(isValid && stack.isEmpty()); // trueColas (Queue)
La cola funciona bajo el principio FIFO (First In, First Out). Se utiliza para gestionar tareas, procesar solicitudes en servidores web con Node.js o para implementar búferes.
class Queue { constructor() { this.items = {}; this.front = 0; this.rear = 0; }
enqueue(element) { this.items[this.rear] = element; this.rear++; }
dequeue() { if (this.isEmpty()) return null; const item = this.items[this.front]; delete this.items[this.front]; this.front++; return item; }
isEmpty() { return this.front === this.rear; }
size() { return this.rear - this.front; }}
// Ejemplo: procesamiento de tareasconst taskQueue = new Queue();taskQueue.enqueue('Tarea 1');taskQueue.enqueue('Tarea 2');console.log(taskQueue.dequeue()); // Tarea 1Algoritmos de búsqueda en JavaScript
La búsqueda de datos es una de las operaciones más comunes. Veamos dos algoritmos básicos: búsqueda lineal y búsqueda binaria.
Búsqueda lineal (Linear Search)
Recorre