Upgrade to Pro — share decks privately, control downloads, hide ads and more …

How to sort your socks using Javascript

How to sort your socks using Javascript

No matter your experience in JS, you have probably came across the Array#sort method at some point. Do you remember the first time you tried sorting numbers? You were probably astonished that the sort method does not sort things out quite as we might expect.

Believe it or not, there is actually much more going on than meets the eye! Let’s get our computer science hat on and explore some useful sorting algorithms currently implemented by JS engines used by Node such as Chrome's V8 and Microsoft's Chakra. As a developer, learning how these algorithms work, why and when to use them will help you create more performant and consistent applications!

Claudia Hernández

October 28, 2017
Tweet

More Decks by Claudia Hernández

Other Decks in Technology

Transcript

  1. @koste4 Algoritmo que acomoda elementos de una lista en cierto

    orden. Los ordenes más usados son numérico y lexicográfico ALGORITMO
 DE ORDENAMIENTO
  2. @koste4 ARRAY SORT EN JS # 1 myArray = [33,

    2, 98, 25, 4] 2 myArray.sort() // [ 2, 25, 33, 4, 98 ]
  3. @koste4 ORDENAMIENTO LEXICOGRÁFICO Si no se provee , los elementos

    son ordenados convirtiéndolos a strings y comparando la posición del valor Unicode de dichos strings compareFunction D
  4. @koste4 VALOR UNICODE 1 colors = ['red', 'blue'] 2 colors.sort()

    3 // ['blue', 'red'] 4 5 numbers = [80, 9] 6 numbers.sort() 7 // [80, 9] 80 9 = = 56 48 57 00
  5. @koste4 1 colors = ['red', 'blue'] 2 colors.sort() 3 //

    ['blue', 'red'] 4 5 numbers = ['80', '9'] 6 numbers.sort() 7 // [80, 9] VALOR UNICODE 80 9 = = 56 48 57 00
  6. @koste4 ARRAY SORT EN JS # 1 myArray = [33,

    2, 98, 25, 4] 2 myArray.sort( (a,b) => a - b ) 3 // [ 2, 4, 25, 33, 98 ]
  7. @koste4 ¿ALGUNA VEZ TE HAS CUÁL ES PREGUNTADO EL ALGORITMO

    USADO EN LA FUNCIÓN SORT NATIVA DE ? JAVASCRIPT
  8. @koste4 Motor JS Algoritmo de Ordenamiento SpiderMonkey F I R

    E F O X Insertion Sort (arreglos pequeños)
 Merge Sort V8 C H R O M E Insertion Sort (arreglos pequeños)
 Quick Sort Nitro S A F A R I Merge Sort Chakra I N T E R N E T E X P L O R E R QuickSort
  9. @koste4 ESTABILIDAD Un algoritmo de ordenamiento estable es aquel en

    el cual elementos iguales conservan sus posiciones iniciales después del ordenamiento
  10. @koste4 INSERTION SORT El arreglo es recorrido de manera secuencial

    y los elementos no ordenados son movidos e insertados en una sub-lista ordenada que se encuentra en el mismo arreglo
  11. @koste4 1 function InsertionSort(arr) { 2 3 let len =

    arr.length, // número de elementos en el arreglo 4 value, // valor a comparar 5 i, // index de la sección sin ordenar 6 j; // index de la sección ordenada 7 8 for(i = 1; i < len; i++) { 9 10 // guarda el valor actual porque puede cambiar después 11 value = arr[i] 12 13 // Cuando el valor de la sección ordenada es mayor que el valor en la 14 // sección no ordenada, mover todos los elementos en la sección uno 15 // por uno. Esto crea un espacio en el cual insertar el valor. 16 for (j = i - 1; j >= 0 && arr[j] > value; j--) { 17 arr[j+1] = arr[j] 18 } 19 arr[j+1] = value 20 } 21 22 return arr 23 24 }
  12. @koste4 DIVIDE Y VENCERÁS Tácticas de Napoleón Bonaparte "Genio Militar"

    Dividir al enemigo en dos y sorprender por un costado 1 3 2 Vencer (atacar) al enemigo pues éste será reducido a la mitad de su tamaño original Concentrar artillería y recursos en un sólo flanco
  13. @koste4 MERGE SORT Divide el arreglo en 2 sub- arreglos

    con n/2 elementos cada uno 1 3 2 Vence (ordena) cada sub- arreglo. Al menos que el arreglo sea suficientemente pequeño, usa recursión Combina las soluciones de los sub-arreglos fusionándolos en un sólo arreglo
  14. 1 function MergeSort(arr) { 2 3 let len = arr.length,

    // número de elementos en el arreglo 4 middle, // mitad del arreglo 5 left, // lado izquierdo del arreglo 6 right // lado derecho del arreglo 7 8 // Arreglos de tamaño 0 y 1 no necesitan ser ordenados 9 if (len < 2) { 10 return arr 11 } 12 13 middle = Math.floor(len/2) 14 15 left = arr.slice(0, middle) // lado izquierdo, de 0 a la mitad 16 right = arr.slice(middle) // lado derecho, de la mitad al final 17 18 return merge(MergeSort(left), MergeSort(right)) 19 20 }
  15. 1 // Fusiona 2 arreglos ya ordenados 2 function merge(left,

    right) { 3 let result = [], 4 i = 0, 5 j = 0 6 7 while(i < left.length && j < right.length) { 8 9 // Elementos en ambos arreglos son comparados uno contra el otro. 10 // El elemento más pequeño es insertado en los resultados. 11 12 // Cada ves que un valor de un arreglo es agregado, su 13 // índice correspondiente es incrementado. 14 15 if(left[i] < right[j]) { 16 result.push(left[i++]) 17 } else { 18 result.push(right[j++]) 19 } 20 } 21 22 // Una vez que uno de los arreglos haya terminado, los elementos 23 // restantes del otro arreglo son agregados a los resultados. 24 25 return result.concat(left.slice(i)).concat(right.slice(j)) 26 27 }
  16. @koste4 QUICK SORT Encuentra un pivote 1 3 2 Divide

    el arreglo de manera que todos los elementos menores al pivote estén a la izquierda y los mayores a la derecha del pivote Vence (ordena) los arreglos
  17. 1 // Encuentra un “pivote” en el arreglo para comparar

    2 // todos sus elementos y moverlos antes o después de 3 // dicho pivote dependiendo de sus valores 4 function QuickSort(arr, left = 0, right = arr.length - 1) { 5 let len = arr.length, 6 index 7 8 if(len > 1) { 9 10 index = partition(arr, left, right) 11 12 if(left < index - 1) { 13 QuickSort(arr, left, index - 1) 14 } 15 16 if(index < right) { 17 QuickSort(arr, index, right) 18 } 19 20 } 21 22 return arr 23 24 }
  18. 1 function partition(arr, left, right) { 2 let middle =

    Math.floor((right + left) / 2), 3 pivot = arr[middle], 4 i = left, // Inicializa el apuntador en el primer elemento del arreglo 5 j = right // Inicializa el apuntador en el último elemento del arreglo 6 7 while(i <= j) { 8 // Mueve el apuntador izquierdo a la derecha hasta que el valor 9 // a la isquierda sea más grande que el pivote 10 while(arr[i] < pivot) { 11 i++ 12 } 13 14 // Mueve el apuntador derecho a la izquierda hasta que el valor 15 // a la derecha sea menor que el pivote 16 while(arr[j] > pivot) { 17 j-- 18 } 19 20 // Si el apuntador izquierdo es menor o igual al apuntador derecho, 21 // intercambia valores 22 if(i <= j) { 23 [arr[i], arr[j]] = [arr[j], arr[i]] // ES6 destructuring swap 24 i++ 25 j-- 26 } 27 } 28 29 return i 30 31 }
  19. 1 Array.prototype.InsertSort = function() { 2 /* tu implementación aquí

    */ 3 } 4 5 Array.prototype.MergeSort = function() { 6 /* tu implementación aquí */ 7 } 8 9 Array.prototype.QuickSort = function() { 10 /* tu implementación aquí */ 11 } 12 13 myArray.InsertSort() 14 myArray.MergeSort() 15 myArray.QuickSort()
  20. const people = [ { name: 'Yamil Asusta', age: 26

    }, { name: 'Mathias Bynens', age: 54 }, { name: 'Arunesh Chandra', age: 17 }, { name: 'Julián Duque', age: 12 }, { name: 'Michele Garrett', age: 32 }, { name: 'Daniel Gimenez', age: 26 }, { name: 'Claudia Hernández', age: 26 }, { name: 'Jeff Lembeck', age: 11 }, { name: 'Kat Marchán', age: 6 }, { name: 'Karisa McKelvey', age: 26 }, { name: 'Kassandra Perch', age: 26 }, { name: 'Nikhila Ravi', age: 26 }, { name: 'Athan Reines', age: 42 }, { name: 'Bert Spaan', age: 11 }, { name: 'Mariano Vazquez', age: 32 }, ]
  21. [{ name: 'Kat Marchán', age: 6 }, { name: 'Jeff

    Lembeck', age: 11 }, { name: 'Bert Spaan', age: 11 }, { name: 'Julián Duque', age: 12 }, { name: 'Arunesh Chandra', age: 17 }, { name: 'Daniel Gimenez', age: 26 }, { name: 'Claudia Hernández', age: 26 }, { name: 'Nikhila Ravi', age: 26 }, { name: 'Yamil Asusta', age: 26 }, { name: 'Karisa McKelvey', age: 26 }, { name: 'Kassandra Perch', age: 26 }, { name: 'Michele Garrett', age: 32 }, { name: 'Mariano Vazquez', age: 32 }, { name: 'Athan Reines', age: 42 }, { name: 'Mathias Bynens', age: 54 }]
  22. [{ name: 'Kat Marchán', age: 6 }, { name: 'Jeff

    Lembeck', age: 11 }, { name: 'Bert Spaan', age: 11 }, { name: 'Julián Duque', age: 12 }, { name: 'Arunesh Chandra', age: 17 }, { name: 'Yamil Asusta', age: 26 }, { name: 'Daniel Gimenez', age: 26 }, { name: 'Claudia Hernández', age: 26 }, { name: 'Karisa McKelvey', age: 26 }, { name: 'Nikhila Ravi', age: 26 }, { name: 'Kassandra Perch', age: 26 }, { name: 'Michele Garrett', age: 32 }, { name: 'Mariano Vazquez', age: 32 }, { name: 'Athan Reines', age: 42 }, { name: 'Mathias Bynens', age: 54 }]
  23. @koste4 PERO… ¿NO ES LENTO? Los arreglos en JS tienen

    metódos cómo
 , , y por supuesto
 
 forEach map reduce sort Todos éstos métodos reciben una 
 función callback como argumento
  24. @koste4 PERO… ¿NO ES LENTO? Iteran sobre una lista e

    invocan la función
 callback para cada elemento La ejecución cambia entre C++ compilado 
 y JS interpretado
  25. @koste4 PERO… ¿NO ES LENTO? El cambio de contexto cuesta

    caro Mantenerse en el mismo contexto de
 ejecución y en el mismo lenguaje 
 permite mejor rendimiento
  26. @koste4 Motor JS Algoritmo de Ordenamiento Self-Host ? SpiderMonkey F

    I R E F O X Insertion Sort (arreglos pequeños)
 Merge Sort No V8 C H R O M E Insertion Sort (arreglos pequeños)
 Quick Sort Sí Nitro S A F A R I Merge Sort Sí Chakra I N T E R N E T E X P L O R E R QuickSort No
  27. @koste4 MÁS SOBRE EL TEMA… The Algorithm Design Manual by

    Steven S. Skiena Foundations of Algorithms by Richard Neapolitan & Kumarss Naimipour