Bubble sort, selection sort e insertion sort no suelen ser la mejor opción para ordenar grandes volúmenes. Su valor principal es educativo: hacen visibles comparaciones, intercambios, invariantes, estabilidad y análisis de casos.
También pueden ser útiles en segmentos pequeños o datos casi ordenados, especialmente insertion sort.
functionbubbleSort<T>(values:T[], compare: Comparator<T>):void{for(let end = values.length -1; end >0; end -=1){let swapped =false;for(let index =0; index < end; index +=1){if(compare(values[index], values[index +1])>0){[values[index], values[index +1]]=[
values[index +1],
values[index],];
swapped =true;}}if(!swapped)return;}}
functioninsertionSort<T>(values:T[], compare: Comparator<T>):void{for(let index =1; index < values.length; index +=1){const current = values[index];let position = index -1;while(position >=0&&compare(values[position], current)>0){
values[position +1]= values[position];
position -=1;}
values[position +1]= current;}}
En lugar de hacer un swap por paso, guarda current y desplaza el bloque. Esto reduce escrituras innecesarias.
Una inversión es una pareja (i, j) con i < j pero values[i] > values[j].
Insertion sort mueve cada elemento una posición por cada inversión que debe corregir. Su tiempo puede expresarse como O(n + I), donde I es la cantidad de inversiones.
Binary search puede encontrar la posición de inserción en O(log n) comparaciones, pero desplazar los elementos sigue costando O(n). El tiempo asintótico total continúa siendo O(n²).
Puede ayudar si comparar es muy costoso y mover referencias es barato.
¿Por qué insertion sort puede ser O(n) en un array ya ordenado?
Respuesta
Porque para cada elemento la primera comparación confirma que ya está después de un valor menor o igual. No realiza desplazamientos, así que hace una cantidad lineal de trabajo.