En el desarrollo de software, los algoritmos son el conjunto de instrucciones definidas que transforman una estructura de datos de entrada en una de salida. A continuación, se exploran algoritmos fundamentales y comunes en JavaScript.
Algoritmos de Ordenamiento
Bubble Sort
Este método compara repetidamente elementos adyacentes y los intercambia si están en el orden incorrecto.
function bubbleSort(array) {
let len = array.length;
for (let i = 0; i < len; i++) {
for (let j = 0; j < len - 1 - i; j++) {
if (array[j] > array[j+1]) {
[array[j], array[j+1]] = [array[j+1], array[j]];
}
}
}
return array;
}
Isnertion Sort
Construye el array ordenado final un elemento a la vez, insertando cada nuevo elemento en su posición correcta dentro de la porción ya ordenaad. Su complejidad temporal promedio es O(n²), lo que lo hace adecuado para conjuntos de datos pequeños.
function insertionSort(arr) {
let n = arr.length;
for (let i = 1; i < n; i++) {
let current = arr[i];
let j = i - 1;
while (j >= 0 && arr[j] > current) {
arr[j + 1] = arr[j];
j--;
}
arr[j + 1] = current;
}
return arr;
}
Quick Sort
Es un algoritmo eficiente que utiliza la estrategia de "divide y vencerás". Una implementación simple elige un pivote, particiona el array en elementos menores y mayores que el pivote, y luego ordena recursivamente las particiones.
function quickSort(arr) {
if (arr.length <= 1) return arr;
const pivot = arr[0];
const left = [];
const right = [];
for (let i = 1; i < arr.length; i++) {
arr[i] < pivot ? left.push(arr[i]) : right.push(arr[i]);
}
return [...quickSort(left), pivot, ...quickSort(right)];
}
Para optimizar el uso de memoria, se puede implementar una partición en el lugar (in-place), que modifica el array original sin crear nuevos arrays en cada recursión.
function quickSortInPlace(arr, left = 0, right = arr.length - 1) {
if (left < right) {
const pivotIndex = partition(arr, left, right);
quickSortInPlace(arr, left, pivotIndex - 1);
quickSortInPlace(arr, pivotIndex + 1, right);
}
return arr;
}
function partition(arr, left, right) {
const pivot = arr[right];
let i = left;
for (let j = left; j < right; j++) {
if (arr[j] < pivot) {
[arr[i], arr[j]] = [arr[j], arr[i]];
i++;
}
}
[arr[i], arr[right]] = [arr[right], arr[i]];
return i;
}
Operaciones con Cadenas (Strings)
Palíndromo
Verifica si una cadena se lee igual hacia adelante y hacia atrás, ignorando mayúsculas y caracteres no alfanuméricos.
function esPalindromo(str) {
const limpio = str.toLowerCase().replace(/[\W_]/g, '');
return limpio === limpio.split('').reverse().join('');
}
Invertir una Cadena
function invertirCadena(str) {
return str.split('').reverse().join('');
}
Carácter con Mayor Frecuencia
function maxFrecuencia(str) {
const contador = {};
let maxChar = '';
let maxCont = 0;
for (const char of str) {
contador[char] = (contador[char] || 0) + 1;
if (contador[char] > maxCont) {
maxCont = contador[char];
maxChar = char;
}
}
return maxChar;
}
Operaciones con Arrays
Eliminar Duplicados
function uniqArray(arr) {
return [...new Set(arr)];
}
// Alternativa sin Set
function uniqArrayManual(arr) {
const sinDuplicados = [];
for (const item of arr) {
if (!sinDuplicados.includes(item)) {
sinDuplicados.push(item);
}
}
return sinDuplicados;
}
Algoritmos de Búsqueda
Búsqueda Binaria
Requiere un array ordenado. Reduce a la mitad el espacio de búsqueda en cada paso, alcanzando una complejidad temporal de O(log n).
function busquedaBinaria(arr, valor) {
let inicio = 0;
let fin = arr.length - 1;
while (inicio <= fin) {
const medio = Math.floor((inicio + fin) / 2);
if (arr[medio] === valor) return medio;
else if (arr[medio] < valor) inicio = medio + 1;
else fin = medio - 1;
}
return -1;
}
Recorrido de Árboles
Búsqueda en Profundidad (DFS)
function dfsIterativo(raiz) {
const resultado = [];
const pila = [raiz];
while (pila.length > 0) {
const nodo = pila.pop();
resultado.push(nodo);
if (nodo.children) {
for (let i = nodo.children.length - 1; i >= 0; i--) {
pila.push(nodo.children[i]);
}
}
}
return resultado;
}
Búsqueda en Amplitud (BFS)
function bfsIterativo(raiz) {
const resultado = [];
const cola = [raiz];
while (cola.length > 0) {
const nodo = cola.shift();
resultado.push(nodo);
if (nodo.children) {
for (const hijo of nodo.children) {
cola.push(hijo);
}
}
}
return resultado;
}
Algoritmos con Funciones de Orden Superior
Deduplicación con Filter
const arrOriginal = ['a', 'b', 'c', 'a', 'b'];
const arrUnico = arrOriginal.filter((elemento, indice, self) => {
return self.indexOf(elemento) === indice;
});
Ordenamiento Personalizado con Sort
El método sort() por defecto convierte elementos a cadenas y ordena según el código Unicode. Para un ordenamiento numérico correcto, se debe proporcionar una función de comparación.
const numeros = [10, 20, 1, 2];
numeros.sort((a, b) => a - b); // Orden ascendente: [1, 2, 10, 20]
Es importante notar que sort() modifica el array original y retorna una referencia al mismo.