fix(guide): simplify directory structure

This commit is contained in:
Mrugesh Mohapatra
2018-10-16 21:26:13 +05:30
parent f989c28c52
commit da0df12ab7
35752 changed files with 0 additions and 317652 deletions

View File

@@ -0,0 +1,154 @@
---
title: Bubble Sort
localeTitle: Ordenamiento de burbuja
---
## Ordenamiento de burbuja
Bubble Sort es el algoritmo de clasificación más simple que funciona intercambiando repetidamente los elementos adyacentes si están en el orden incorrecto.
Este es un algoritmo de clasificación muy lento en comparación con algoritmos como quicksort, con la peor complejidad O (n ^ 2). Sin embargo, la desventaja es que la clasificación por burbuja es uno de los algoritmos de clasificación más fáciles de implementar desde cero.
### Ejemplo:
#### Primer pase:
(5 1 4 2 8) -> (1 5 4 2 8), Aquí, el algoritmo compara los dos primeros elementos, y cambia desde 5> 1.
(1 5 4 2 8) -> (1 4 5 2 8), Swap desde 5> 4
(1 4 5 2 8) -> (1 4 2 5 8), Swap desde 5> 2
(1 4 2 5 8) -> (1 4 2 5 8), Ahora, como estos elementos ya están en orden (8> 5), el algoritmo no los intercambia.
#### Segundo paso:
(1 4 2 5 8) -> (1 4 2 5 8)
(1 4 2 5 8) -> (1 2 4 5 8), Swap desde 4> 2
(1 2 4 5 8) -> (1 2 4 5 8)
(1 2 4 5 8) -> (1 2 4 5 8)
Ahora, la matriz ya está ordenada, pero nuestro algoritmo no sabe si está completado. El algoritmo necesita un pase completo sin ningún tipo de cambio para saber que está ordenado.
#### Tercer paso:
(1 2 4 5 8) -> (1 2 4 5 8)
(1 2 4 5 8) -> (1 2 4 5 8)
(1 2 4 5 8) -> (1 2 4 5 8)
(1 2 4 5 8) -> (1 2 4 5 8)
#### Propiedades
* Complejidad del espacio: O (1)
* Mejor rendimiento de caso: O (n)
* Rendimiento promedio del caso: O (n \* n)
* El peor desempeño de caso: O (n \* n)
* Estable: si
### Explicación del video
[Burbuja de manera fácil.](https://www.youtube.com/watch?v=Jdtq5uKz-w4)
Este código utilizará la ordenación de burbujas para ordenar la matriz.
```js
let arr = [1, 4, 7, 45, 7,43, 44, 25, 6, 4, 6, 9];
let sorted = false
while(!sorted) {
sorted = true
for(var i=0; i < arr.length; i++) {
if(arr[i] < arr[i-1]) {
let temp = arr[i];
arr[i] = arr[i-1];
arr[i-1] = temp;
sorted = false;
}
}
}
```
### Propiedades:
* Complejidad del espacio: O (1)
* Complejidad de tiempo: O (n), O (n \* n), O (n \* n) para los casos Best, Average y Worst respectivamente.
* En el lugar: si
* Estable: si
\======= Aquí está el algoritmo escrito en Java.
```java
public class bubble-sort {
static void sort(int[] arr) {
int n = arr.length;
int temp = 0;
for(int i=0; i < n; i++){
for(int x=1; x < (ni); x++){
if(arr[x-1] > arr[x]){
temp = arr[x-1];
arr[x-1] = arr[x];
arr[x] = temp;
}
}
}
}
public static void main(String[] args) {
for(int i=0; i < 15; i++){
int arr[i] = (int)(Math.random() * 100 + 1);
}
System.out.println("array before sorting\n");
for(int i=0; i < arr.length; i++){
System.out.print(arr[i] + " ");
}
bubbleSort(arr);
System.out.println("\n array after sorting\n");
for(int i=0; i < arr.length; i++){
System.out.print(arr[i] + " ");
}
}
}
```
\=======
### La implementación recursiva del Bubble Sort.
```c++
void bubblesort(int arr[], int n)
{
if(n==1) //Initial Case
return;
for(int i=0;i<n-1;i++) //After this pass the largest element will move to its desired location.
{
if(arr[i]>arr[i+1])
{
temp=arr[i];
arr[i]=arr[i+1];
arr[i+1]=temp;
}
}
bubblesort(arr,n-1); //Recursion for remaining array
}
```
### Más información
* [Wikipedia](https://en.wikipedia.org/wiki/Bubble_sort)
* [Algoritmo de clasificación de burbuja - CS50](https://youtu.be/Ui97-_n5xjo)
* [Bubble Sort Algorithm - GeeksForGeeks (artículo)](http://www.geeksforgeeks.org/bubble-sort)
* [Algoritmo de ordenamiento de burbujas - MyCodeSchool (video)](https://www.youtube.com/watch?v=Jdtq5uKz-w4)
* [Algoritmos: Bubble Sort - HackerRank (video)](https://www.youtube.com/watch?v=6Gv8vg0kcHc)
* [Bubble Sort Algorithm - GeeksForGeeks (video)](https://www.youtube.com/watch?v=nmhjrI-aW5o)
* [Visualización del orden de burbuja](https://www.hackerearth.com/practice/algorithms/sorting/bubble-sort/visualize/)

View File

@@ -0,0 +1,46 @@
---
title: Bucket Sort
localeTitle: Tipo de cubo
---
## ¿Qué es Bucket Sort?
La ordenación de cubos es un algoritmo de ordenación comparativa que opera sobre elementos al dividirlos en diferentes compartimientos y luego clasificarlos individualmente. Cada grupo se clasifica individualmente mediante un algoritmo de clasificación independiente o aplicando el algoritmo de clasificación de grupo de forma recursiva. La clasificación de la cuchara es principalmente útil cuando la entrada se distribuye uniformemente en un rango.
## Supongamos que uno tiene el siguiente problema delante de ellos:
A uno se le ha dado una gran variedad de enteros de punto flotante que se encuentran uniformemente entre el límite inferior y superior. Esta matriz ahora necesita ser ordenado Una forma sencilla de resolver este problema sería utilizar otro algoritmo de clasificación, como la ordenación de mezcla, la ordenación de pila o la ordenación rápida. Sin embargo, estos algoritmos garantizan una complejidad en el mejor de los casos de O (NlogN). Sin embargo, utilizando la ordenación de cubetas, la tarea anterior se puede completar en tiempo O (N).
Vamos a echarle un vistazo más de cerca.
Considere la necesidad de crear una serie de listas, es decir, de grupos. Ahora es necesario insertar elementos en estos cubos en función de sus propiedades. Cada uno de estos cubos se puede clasificar individualmente utilizando el orden de inserción.
### Pseudo código para la clasificación del cubo:
```
void bucketSort(float[] a,int n)
{
for(each floating integer 'x' in n)
{
insert x into bucket[n*x];
}
for(each bucket)
{
sort(bucket);
}
}
```
### Más información:
* [Wikipedia](https://en.wikipedia.org/wiki/Bucket_sort)
* [GeeksForGeeks](http://www.geeksforgeeks.org/bucket-sort-2/)

View File

@@ -0,0 +1,56 @@
---
title: Counting Sort
localeTitle: Orden de conteo
---
## Orden de conteo
Counting Sort es una técnica de clasificación basada en claves entre un rango específico. Funciona contando el número de objetos que tienen valores clave distintos (tipo de hashing). Luego, hacer algo de aritmética para calcular la posición de cada objeto en la secuencia de salida.
### Ejemplo:
```
For simplicity, consider the data in the range 0 to 9.
Input data: 1, 4, 1, 2, 7, 5, 2
1) Take a count array to store the count of each unique object.
Index: 0 1 2 3 4 5 6 7 8 9
Count: 0 2 2 0 1 1 0 1 0 0
2) Modify the count array such that each element at each index
stores the sum of previous counts.
Index: 0 1 2 3 4 5 6 7 8 9
Count: 0 2 4 4 5 6 6 7 7 7
The modified count array indicates the position of each object in
the output sequence.
3) Output each object from the input sequence followed by
decreasing its count by 1.
Process the input data: 1, 4, 1, 2, 7, 5, 2. Position of 1 is 2.
Put data 1 at index 2 in output. Decrease count by 1 to place
next data 1 at an index 1 smaller than this index.
```
### Implementación
```js
let numbers = [1, 4, 1, 2, 7, 5, 2];
let count = [];
let i, z = 0;
let max = Math.max(...numbers);
// initialize counter
for (i = 0; i <= max; i++) {
count[i] = 0;
}
for (i=0; i < numbers.length; i++) {
count[numbers[i]]++;
}
for (i = 0; i <= max; i++) {
while (count[i]-- > 0) {
numbers[z++] = i;
}
}
// output sorted array
for (i=0; i < numbers.length; i++) {
console.log(numbers[i]);
}
```

View File

@@ -0,0 +1,133 @@
---
title: Heapsort
localeTitle: Heapsort
---
## Heapsort
Heapsort es un algoritmo de clasificación eficiente basado en el uso de montones de max / min. Un montón es una estructura de datos basada en árbol que satisface la propiedad del montón, es decir, para un montón máximo, la clave de cualquier nodo es menor o igual que la clave de su padre (si tiene un padre). Esta propiedad se puede aprovechar para acceder al elemento máximo en el montón en tiempo O (logn) utilizando el método maxHeapify. Realizamos esta operación n veces, cada vez moviendo el elemento máximo en el montón a la parte superior del montón y extrayéndolo del montón a una matriz ordenada. Por lo tanto, después de n iteraciones tendremos una versión ordenada de la matriz de entrada. Este algoritmo se ejecuta en tiempo O (nlogn) y O (1) espacio adicional \[O (n), incluido el espacio requerido para almacenar los datos de entrada\], ya que todas las operaciones se realizan completamente en el lugar.
La complecidad de tiempo de caso peor y promedio de Heapsort es O (nlogn). A pesar de que heapsort tiene una complejidad de caso peor que la de quicksort, un quicksort bien implementado se ejecuta más rápido en la práctica. Este es un algoritmo basado en la comparación, por lo que se puede usar para conjuntos de datos no numéricos en la medida en que se pueda definir alguna relación (propiedad del montón) sobre los elementos.
Una implementación en Java se muestra a continuación:
```java
import java.util.Arrays;
public class Heapsort {
public static void main(String[] args) {
//test array
Integer[] arr = {1, 4, 3, 2, 64, 3, 2, 4, 5, 5, 2, 12, 14, 5, 3, 0, -1};
String[] strarr = {"hope you find this helpful!", "wef", "rg", "q2rq2r", "avs", "erhijer0g", "ewofij", "gwe", "q", "random"};
arr = heapsort(arr);
strarr = heapsort(strarr);
System.out.println(Arrays.toString(arr));
System.out.println(Arrays.toString(strarr));
}
//O(nlogn) TIME, O(1) SPACE, NOT STABLE
public static <E extends Comparable<E>> E[] heapsort(E[] arr){
int heaplength = arr.length;
for(int i = arr.length/2; i>0;i--){
arr = maxheapify(arr, i, heaplength);
}
for(int i=arr.length-1;i>=0;i--){
E max = arr[0];
arr[0] = arr[i];
arr[i] = max;
heaplength--;
arr = maxheapify(arr, 1, heaplength);
}
return arr;
}
//Creates maxheap from array
public static <E extends Comparable<E>> E[] maxheapify(E[] arr, Integer node, Integer heaplength){
Integer left = node*2;
Integer right = node*2+1;
Integer largest = node;
if(left.compareTo(heaplength) <=0 && arr[left-1].compareTo(arr[node-1]) >= 0){
largest = left;
}
if(right.compareTo(heaplength) <= 0 && arr[right-1].compareTo(arr[largest-1]) >= 0){
largest = right;
}
if(largest != node){
E temp = arr[node-1];
arr[node-1] = arr[largest-1];
arr[largest-1] = temp;
maxheapify(arr, largest, heaplength);
}
return arr;
}
}
```
implementación en C ++
```C++
#include <iostream>
using namespace std;
void heapify(int arr[], int n, int i)
{
int largest = i;
int l = 2*i + 1;
int r = 2*i + 2;
if (l < n && arr[l] > arr[largest])
largest = l;
if (r < n && arr[r] > arr[largest])
largest = r;
if (largest != i)
{
swap(arr[i], arr[largest]);
heapify(arr, n, largest);
}
}
void heapSort(int arr[], int n)
{
for (int i = n / 2 - 1; i >= 0; i--)
heapify(arr, n, i);
for (int i=n-1; i>=0; i--)
{
swap(arr[0], arr[i]);
heapify(arr, i, 0);
}
}
void printArray(int arr[], int n)
{
for (int i=0; i<n; ++i)
cout << arr[i] << " ";
cout << "\n";
}
int main()
{
int arr[] = {12, 11, 13, 5, 6, 7};
int n = sizeof(arr)/sizeof(arr[0]);
heapSort(arr, n);
cout << "Sorted array is \n";
printArray(arr, n);
}
```
### Visualización
* [USFCA](https://www.cs.usfca.edu/~galles/visualization/HeapSort.html)
* [HackerEarth](https://www.hackerearth.com/practice/algorithms/sorting/heap-sort/tutorial/)
#### Más información:
* [Wikipedia](https://en.wikipedia.org/wiki/Quicksort)

View File

@@ -0,0 +1,54 @@
---
title: Sorting Algorithms
localeTitle: Clasificación de los algoritmos
---
## Clasificación de los algoritmos
Los algoritmos de clasificación son un conjunto de instrucciones que toman una matriz o lista como entrada y organizan los elementos en un orden particular.
Las clasificaciones son más comúnmente en orden numérico o alfabético (llamado lexicográfico), y pueden ser en orden ascendente (AZ, 0-9) o descendente (ZA, 9-0).
### Por qué los algoritmos de clasificación son importantes
Dado que la clasificación a menudo puede reducir la complejidad de un problema, es un algoritmo importante en Ciencias de la Computación. Estos algoritmos tienen aplicaciones directas en algoritmos de búsqueda, algoritmos de bases de datos, métodos de dividir y conquistar, algoritmos de estructura de datos y muchos más.
### Algunos algoritmos de clasificación comunes
Algunos de los algoritmos de clasificación más comunes son:
* Selección de selección
* Ordenamiento de burbuja
* Tipo de inserción
* Combinar clasificación
* Ordenación rápida
* Heap Sort
* Orden de conteo
* Radix Sort
* Tipo de cubo
### Clasificación del algoritmo de clasificación
Los algoritmos de clasificación se pueden clasificar en función de los siguientes parámetros:
1. Basado en el número de swaps o inversión Este es el número de veces que el algoritmo intercambia elementos para ordenar la entrada. `Selection Sort` requiere el número mínimo de swaps.
2. Basado en el número de comparaciones Este es el número de veces que el algoritmo compara elementos para ordenar la entrada. Usando la [notación Big-O](https://guide.freecodecamp.org/computer-science/notation/big-o-notation/) , los ejemplos de algoritmo de clasificación mencionados anteriormente requieren al menos `O(nlogn)` comparaciones en el mejor de los casos y `O(n^2)` comparaciones en el peor de los casos para la mayoría de los resultados.
3. Basado en Recursión o No Recursión Algunos algoritmos de clasificación, como la `Quick Sort` , utilizan técnicas recursivas para ordenar la entrada. Otros algoritmos de clasificación, como la `Selection Sort` por `Selection Sort` o la `Insertion Sort` , utilizan técnicas no recursivas. Por último, algunos algoritmos de clasificación, como la `Merge Sort` , hacen uso de técnicas recursivas y no recursivas para ordenar la entrada.
4. Basado en la estabilidad Se dice que los algoritmos de clasificación son `stable` si el algoritmo mantiene el orden relativo de los elementos con claves iguales. En otras palabras, dos elementos equivalentes permanecen en el mismo orden en la salida ordenada que en la entrada.
* `Insertion sort` , el orden de `Merge Sort` y el `Insertion sort` `Bubble Sort` son estables
* `Heap Sort` y `Quick Sort` no son estables
1. Basado en el requisito de espacio adicional Se dice que los algoritmos de clasificación están `in place` si requieren un espacio adicional constante de `O(1)` para la clasificación.
* `Insertion sort` y la `Insertion sort` `Quick-sort` están `Quick-sort` `in place` medida que movemos los elementos sobre el pivote y no usamos una matriz separada, lo que NO es el caso en la ordenación por fusión, donde el tamaño de la entrada debe asignarse de antemano para almacenar la salida durante el ordenar.
* `Merge Sort` es un ejemplo de clasificación de `out place` ya que requiere espacio de memoria adicional para sus operaciones.
### La mejor complejidad de tiempo posible para cualquier clasificación basada en comparación
Cualquier algoritmo de ordenación basado en comparaciones debe realizar al menos comparaciones de nLog2n para ordenar la matriz de entrada, y Heapsort y merge sort son clasificaciones asintóticamente óptimas de comparación. Esto se puede demostrar fácilmente dibujando el diagrama del árbol de decisión.

View File

@@ -0,0 +1,191 @@
---
title: Insertion Sort
localeTitle: Tipo de inserción
---
## Tipo de inserción
La ordenación por inserción es el algoritmo de clasificación más simple y eficiente para una pequeña cantidad de elementos.
### Ejemplo:
En la ordenación por inserción, compara el elemento `key` con los elementos anteriores. Si los elementos anteriores son mayores que el elemento `key` , mueva el elemento anterior a la siguiente posición.
Comience desde el índice 1 hasta el tamaño de la matriz de entrada.
\[8 3 5 1 4 2\]
Paso 1 :
! [\[8 3 5 1 4 2\]](https://github.com/blulion/freecodecamp-resource/blob/master/insertion_sort/1.png?raw=true)
```
key = 3 //starting from 1st index.
Here `key` will be compared with the previous elements.
In this case, `key` is compared with 8. since 8 > 3, move the element 8
to the next position and insert `key` to the previous position.
Result: [ 3 8 5 1 4 2 ]
```
Paso 2 :
! [\[3 8 5 1 4 2\]](https://github.com/blulion/freecodecamp-resource/blob/master/insertion_sort/2.png?raw=true)
```
key = 5 //2nd index
8 > 5 //move 8 to 2nd index and insert 5 to the 1st index.
Result: [ 3 5 8 1 4 2 ]
```
Paso 3 :
! [\[3 5 8 1 4 2\]](https://github.com/blulion/freecodecamp-resource/blob/master/insertion_sort/3.png?raw=true)
```
key = 1 //3rd index
8 > 1 => [ 3 5 1 8 4 2 ]
5 > 1 => [ 3 1 5 8 4 2 ]
3 > 1 => [ 1 3 5 8 4 2 ]
Result: [ 1 3 5 8 4 2 ]
```
Etapa 4 :
! [\[1 3 5 8 4 2\]](https://github.com/blulion/freecodecamp-resource/blob/master/insertion_sort/4.png?raw=true)
```
key = 4 //4th index
8 > 4 => [ 1 3 5 4 8 2 ]
5 > 4 => [ 1 3 4 5 8 2 ]
3 > 4 ≠> stop
Result: [ 1 3 4 5 8 2 ]
```
Paso 5:
! [\[1 3 4 5 8 2\]](https://github.com/blulion/freecodecamp-resource/blob/master/insertion_sort/5.png?raw=true)
```
key = 2 //5th index
8 > 2 => [ 1 3 4 5 2 8 ]
5 > 2 => [ 1 3 4 2 5 8 ]
4 > 2 => [ 1 3 2 4 5 8 ]
3 > 2 => [ 1 2 3 4 5 8 ]
1 > 2 ≠> stop
Result: [1 2 3 4 5 8]
```
! [\[1 2 3 4 5 8\]](https://github.com/blulion/freecodecamp-resource/blob/master/insertion_sort/6.png?raw=true)
El algoritmo siguiente es una versión ligeramente optimizada para evitar el intercambio de elementos `key` en cada iteración. Aquí, el elemento `key` se intercambiará al final de la iteración (paso).
```Algorithm
InsertionSort(arr[])
for j = 1 to arr.length
key = arr[j]
i = j - 1
while i > 0 and arr[i] > key
arr[i+1] = arr[i]
i = i - 1
arr[i+1] = key
```
Aquí hay una implementación detallada en Javascript:
```
function insertion_sort(A) {
var len = array_length(A);
var i = 1;
while (i < len) {
var x = A[i];
var j = i - 1;
while (j >= 0 && A[j] > x) {
A[j + 1] = A[j];
j = j - 1;
}
A[j+1] = x;
i = i + 1;
}
}
```
Una implementación rápida en Swift es como se muestra a continuación:
```swift
var array = [8, 3, 5, 1, 4, 2]
func insertionSort(array:inout Array<Int>) -> Array<Int>{
for j in 0..<array.count {
let key = array[j]
var i = j-1
while (i > 0 && array[i] > key){
array[i+1] = array[i]
i = i-1
}
array[i+1] = key
}
return array
}
```
El ejemplo de Java se muestra a continuación:
```
public int[] insertionSort(int[] arr)
for (j = 1; j < arr.length; j++) {
int key = arr[j]
int i = j - 1
while (i > 0 and arr[i] > key) {
arr[i+1] = arr[i]
i -= 1
}
arr[i+1] = key
}
return arr;
```
### tipo de inserción en c….
```C
void insertionSort(int arr[], int n)
{
int i, key, j;
for (i = 1; i < n; i++)
{
key = arr[i];
j = i-1;
while (j >= 0 && arr[j] > key)
{
arr[j+1] = arr[j];
j = j-1;
}
arr[j+1] = key;
}
}
```
### Propiedades:
* Complejidad del espacio: O (1)
* Complejidad de tiempo: O (n), O (n \* n), O (n \* n) para los casos Best, Average, Worst respectivamente
* Clasificación en el lugar: Sí
* Estable: si
#### Otros recursos:
* [Wikipedia](https://en.wikipedia.org/wiki/Insertion_sort)
* [CS50 - YouTube](https://youtu.be/TwGb6ohsvUU)
* [SortInsertion - GeeksforGeeks, YouTube](https://www.youtube.com/watch?v=wObxd4Kx8sE)
* [Visualización de ordenación por inserción](https://www.hackerearth.com/practice/algorithms/sorting/insertion-sort/visualize/)

View File

@@ -0,0 +1,204 @@
---
title: Merge Sort
localeTitle: Combinar clasificación
---
## Combinar clasificación
Merge Sort es un algoritmo de [Dividir y Conquistar](https://guide.freecodecamp.org/algorithms/divide-and-conquer-algorithms) . Divide la matriz de entrada en dos mitades, se llama a sí misma para las dos mitades y luego combina las dos mitades clasificadas. A la mayor parte del algoritmo se le asignan dos matrices ordenadas, tenemos que fusionarlas en una sola matriz ordenada. Hay algo conocido como el [algoritmo de dos dedos](http://www.geeksforgeeks.org/merge-two-sorted-arrays/) que nos ayuda a unir dos matrices ordenadas juntas. Usar esta subrutina y llamar a la función de ordenamiento de combinación en las mitades de la matriz de forma recursiva nos dará la matriz ordenada final que estamos buscando.
Dado que este es un algoritmo basado en recursión, tenemos una relación de recurrencia para él. Una relación de recurrencia es simplemente una forma de representar un problema en términos de sus subproblemas.
`T(n) = 2 * T(n / 2) + O(n)`
Poniéndolo en un lenguaje sencillo, dividimos el subproblema en dos partes en cada paso y tenemos una cantidad lineal de trabajo que tenemos que hacer para unir las dos mitades clasificadas en cada paso.
```
T(n) = 2T(n/2) + n
= 2(2T(n/4) + n/2) + n
= 4T(n/4) + n + n
= 4(2T(n/8) + n/4) + n + n
= 8T(n/8) + n + n + n
= nT(n/n) + n + ... + n + n + n
= n + n + ... + n + n + n
```
Contando el número de repeticiones de n en la suma al final, vemos que hay lg n + 1 de ellas. Por lo tanto, el tiempo de ejecución es n (lg n + 1) = n lg n + n. Observamos que n lg n + n <n lg n + n lg n = 2n lg n para n> 0, por lo que el tiempo de ejecución es O (n lg n).
```Algorithm
MergeSort(arr[], left, right):
If right > l:
1. Find the middle point to divide the array into two halves:
mid = (left+right)/2
2. Call mergeSort for first half:
Call mergeSort(arr, left, mid)
3. Call mergeSort for second half:
Call mergeSort(arr, mid+1, right)
4. Merge the two halves sorted in step 2 and 3:
Call merge(arr, left, mid, right)
```
![Merge Sort Algorithm](https://upload.wikimedia.org/wikipedia/commons/thumb/e/e6/Merge_sort_algorithm_diagram.svg/300px-Merge_sort_algorithm_diagram.svg.png)
### Properties:
* Space Complexity: O(n)
* Time Complexity: O(n*log(n)). The time complexity for the Merge Sort might not be obvious from the first glance. The log(n) factor that comes in is because of the recurrence relation we have mentioned before.
* Sorting In Place: No in a typical implementation
* Stable: Yes
* Parallelizable :yes (Several parallel variants are discussed in the third edition of Cormen, Leiserson, Rivest, and Stein's Introduction to Algorithms.)
### Visualization:
* <a href='https://www.cs.usfca.edu/~galles/visualization/ComparisonSort.html'>USFCA</a>
* <a href='https://www.hackerearth.com/practice/algorithms/sorting/merge-sort/visualize/'>HackerEarth</a>
### Relavant videos on freeCodeCamp YouTube channel
* <a href='https://youtu.be/TzeBrDU-JaY'>Merge Sort algorithm - MyCodeSchool</a>
### Other Resources:
* <a href='https://en.wikipedia.org/wiki/Merge_sort' target='_blank' rel='nofollow'>Wikipedia</a>
* <a href='www.geeksforgeeks.org/merge-sort' target='_blank' rel='nofollow'>GeeksForGeeks</a>
* <a href='https://youtu.be/sWtYJv_YXbo' target='_blank' rel='nofollow'>Merge Sort - CS50</a>
### Implementaion in JS
```
js const list = \[23, 4, 42, 15, 16, 8, 3\]
const mergeSort = (list) => { if (list.length <= 1) return list; const middle = list.length / 2; const left = list.slice (0, middle); const right = list.slice (middle, list.length); devuelve merge (mergeSort (izquierda), mergeSort (derecha)); }
const merge = (izquierda, derecha) => { var resultado = \[\]; while (left.length || right.length) { if (left.length && right.length) { si (izquierda \[0\] <derecha \[0\]) { result.push (left.shift ()) } else { result.push (right.shift ()) } } else if (left.length) { result.push (left.shift ()) } else { result.push (right.shift ()) } } resultado de retorno }
console.log (mergeSort (lista)) // \[3, 4, 8, 15, 16, 23, 42\]
```
### Implementation in C
```
do
# incluir
# incluir
fusión de vacíos (int arr \[\], int l, int m, int r) { int i, j, k; int n1 = m - l + 1; int n2 = r - m;
```
int L[n1], R[n2];
for (i = 0; i < n1; i++)
L[i] = arr[l + i];
for (j = 0; j < n2; j++)
R[j] = arr[m + 1+ j];
i = 0;
j = 0;
k = l;
while (i < n1 && j < n2)
{
if (L[i] <= R[j])
{
arr[k] = L[i];
i++;
}
else
{
arr[k] = R[j];
j++;
}
k++;
}
while (i < n1)
{
arr[k] = L[i];
i++;
k++;
}
while (j < n2)
{
arr[k] = R[j];
j++;
k++;
}
```
}
void mergeSort (int arr \[\], int l, int r) { si (l <r) {
int m = l + (rl) / 2;
```
mergeSort(arr, l, m);
mergeSort(arr, m+1, r);
merge(arr, l, m, r);
}
```
} void printArray (int A \[\], tamaño int) { int i; para (i = 0; i <tamaño; i ++) printf ("% d", A \[i\]); printf ("\\ n"); } int main () { int arr \[\] = {12, 11, 13, 5, 6, 7}; int arr\_size = sizeof (arr) / sizeof (arr \[0\]);
```
printf("Given array is \n");
printArray(arr, arr_size);
mergeSort(arr, 0, arr_size - 1);
printf("\nSorted array is \n");
printArray(arr, arr_size);
return 0;
```
```
### Implementation in C++
Let us consider array A = {2,5,7,8,9,12,13}
and array B = {3,5,6,9,15} and we want array C to be in ascending order as well.
```
c ++ void mergesort (int A \[\], int tamaño _a, int B \[\], int tamaño_ b, int C \[\]) { int token _a, token_ b, token _c; para (token_ a = 0, token _b = 0, token_ c = 0; token _a_ _to && token _b__ __segundo; ) { if (A \[token _a\] <= B \[token_ b\]) C \[token _c ++\] = A \[token_ a ++\]; más C \[token _c ++\] = B \[token_ b ++\]; }__
```
if(token_a<size_a)
{
while(token_a<size_a)
C[token_c++]=A[token_a++];
}
else
{
while(token_b<size_b)
C[token_c++]=B[token_b++];
}
```
}
```
### Implementation in Python
```
pitón temp = ninguno def fusionar (arr, izquierda, derecha): temp global, inversiones mid = (izquierda + derecha) // 2 para i en rango (izquierda, derecha + 1): temp \[i\] = arr \[i\]
```
k, L, R = left, left, mid + 1
while L <= mid and R <= right:
if temp[L] <= temp[R]:
arr[k] = temp[L]
L += 1
else:
arr[k] = temp[R]
R += 1
k += 1
while L <= mid:
arr[k] = temp[L]
L += 1
k += 1
while R <= right:
arr[k] = temp[R]
R += 1
k += 1
```
def merge\_sort (arr, izquierda, derecha): si es izquierdo> = derecho: regreso
```
mid = (left + right) // 2
merge_sort(arr, left, mid)
merge_sort(arr, mid + 1, right)
merge(arr, left, right)
```
arr = \[1,6,3,1,8,4,2,9,3\] temp = \[Ninguno para \_ en rango (len (arr))\] merge\_sort (arr, 0, len (arr) - 1) imprimir (arr, inversiones) \`\` \`

View File

@@ -0,0 +1,146 @@
---
title: Quick Sort
localeTitle: Ordenación rápida
---
## Ordenación rápida
La clasificación rápida es un eficiente algoritmo de clasificación de división y conquista. La complejidad media de tiempo de caso de Ordenación rápida es O (nlog (n)) y O (n ^ 2) es la complejidad de tiempo de peor caso.
Los pasos involucrados en Quick Sort son:
* Elija un elemento para servir como un pivote, en este caso, el último elemento de la matriz es el pivote.
* Partición: Ordene la matriz de tal manera que todos los elementos menos que el pivote estén a la izquierda, y todos los elementos mayores que el pivote estén a la derecha.
* Llame a Quicksort de forma recursiva, teniendo en cuenta el pivote anterior para subdividir correctamente los arreglos izquierdo y derecho. (Una explicación más detallada se puede encontrar en los comentarios a continuación)
Una implementación rápida en JavaScript:
```javascript
const arr = [6, 2, 5, 3, 8, 7, 1, 4]
const quickSort = (arr, start, end) => {
if(start < end) {
// You can learn about how the pivot value is derived in the comments below
let pivot = partition(arr, start, end)
// Make sure to read the below comments to understand why pivot - 1 and pivot + 1 are used
// These are the recursive calls to quickSort
quickSort(arr, start, pivot - 1)
quickSort(arr, pivot + 1, end)
}
}
const partition = (arr, start, end) => {
let pivot = end
// Set i to start - 1 so that it can access the first index in the event that the value at arr[0] is greater than arr[pivot]
// Succeeding comments will expound upon the above comment
let i = start - 1
let j = start
// Increment j up to the index preceding the pivot
while (j < pivot) {
// If the value is greater than the pivot increment j
if (arr[j] > arr[pivot]) {
j++
}
// When the value at arr[j] is less than the pivot:
// increment i (arr[i] will be a value greater than arr[pivot]) and swap the value at arr[i] and arr[j]
else {
i++
swap(arr, j, i)
j++
}
}
//The value at arr[i + 1] will be greater than the value of arr[pivot]
swap(arr, i + 1, pivot)
//You return i + 1, as the values to the left of it are less than arr[i+1], and values to the right are greater than arr[i + 1]
// As such, when the recursive quicksorts are called, the new sub arrays will not include this the previously used pivot value
return i + 1
}
const swap = (arr, firstIndex, secondIndex) => {
let temp = arr[firstIndex]
arr[firstIndex] = arr[secondIndex]
arr[secondIndex] = temp
}
quickSort(arr, 0, arr.length - 1)
console.log(arr)
```
Una implementación de clasificación rápida en C
```C
#include<stdio.h>
void swap(int* a, int* b)
{
int t = *a;
*a = *b;
*b = t;
}
int partition (int arr[], int low, int high)
{
int pivot = arr[high];
int i = (low - 1);
for (int j = low; j <= high- 1; j++)
{
if (arr[j] <= pivot)
{
i++;
swap(&arr[i], &arr[j]);
}
}
swap(&arr[i + 1], &arr[high]);
return (i + 1);
}
void quickSort(int arr[], int low, int high)
{
if (low < high)
{
int pi = partition(arr, low, high);
quickSort(arr, low, pi - 1);
quickSort(arr, pi + 1, high);
}
}
void printArray(int arr[], int size)
{
int i;
for (i=0; i < size; i++)
printf("%d ", arr[i]);
printf("n");
}
int main()
{
int arr[] = {10, 7, 8, 9, 1, 5};
int n = sizeof(arr)/sizeof(arr[0]);
quickSort(arr, 0, n-1);
printf("Sorted array: n");
printArray(arr, n);
return 0;
}
```
La complejidad del espacio de ordenación rápida es O (n). Esta es una mejora sobre otros algoritmos de clasificación de división y conquista, que ocupan espacio O (nlong (n)). La ordenación rápida logra esto al cambiar el orden de los elementos dentro de la matriz dada. Compare esto con el algoritmo de [ordenamiento de fusión](https://guide.freecodecamp.org/algorithms/sorting-algorithms/merge-sort) que crea 2 matrices, cada longitud n / 2, en cada llamada de función.
#### Más información:
* [Wikipedia](https://en.wikipedia.org/wiki/Quicksort)
* [GeeksForGeeks](http://www.geeksforgeeks.org/quick-sort)
* [Youtube: una explicación visual de Quicksort](https://www.youtube.com/watch?v=MZaf_9IZCrc)
* [Youtube: Gayle Laakmann McDowell (autora de Cracking The Coding Interview) explica los conceptos básicos de quicksort y muestra algunas implementaciones.](https://www.youtube.com/watch?v=SLauY6PpjW4)

View File

@@ -0,0 +1,111 @@
---
title: Radix Sort
localeTitle: Radix Sort
---
## Radix Sort
Requisito Previo: Contar Ordenar
QuickSort, MergeSort, HeapSort son algoritmos de clasificación basados en comparación. CountSort no es un algoritmo basado en comparación. Tiene la complejidad de O (n + k), donde k es el elemento máximo de la matriz de entrada. Entonces, si k es O (n), CountSort se convierte en ordenación lineal, lo cual es mejor que los algoritmos de ordenación basados en comparación que tienen complejidad de tiempo O (nlogn). La idea es extender el algoritmo CountSort para obtener una mejor complejidad de tiempo cuando k va O (n2). Aquí viene la idea de Radix Sort.
Algoritmo:
Para cada dígito donde i varía entre el dígito menos significativo y el dígito más significativo de un número Ordene la matriz de entrada utilizando un algoritmo de conteo de acuerdo con un dígito. Usamos el orden de conteo porque es un ordenamiento estable.
Ejemplo: Supongamos que la matriz de entrada es:
10,21,17,34,44,11,654,123
Según el algoritmo, ordenaremos la matriz de entrada según el dígito de uno (el dígito menos significativo).
0: 10
1: 21 11
2:
3: 123
4: 34 44 654
5:
6:
7: 17
8:
9:
Así, la matriz se convierte en 10,21,11,123,24,44,654,17 Ahora, vamos a ordenar de acuerdo con el dígito de diez:
0:
1: 10 11 17
2: 21 123
3: 34
4: 44
5: 654
6:
7:
8:
9:
Ahora, la matriz se convierte en: 10,11,17,21,123,34,44,654 Finalmente, ordenamos según el dígito del centenario (el dígito más significativo):
0: 010 011 017 021 034 044
1: 123
2:
3:
4:
5:
6: 654
7:
8:
9:
La matriz se convierte en: 10,11,17,21,34,44,123,654 que está ordenada. Así es como funciona nuestro algoritmo.
Una implementación en C:
```
void countsort(int arr[],int n,int place){
int i,freq[range]={0}; //range for integers is 10 as digits range from 0-9
int output[n];
for(i=0;i<n;i++)
freq[(arr[i]/place)%range]++;
for(i=1;i<range;i++)
freq[i]+=freq[i-1];
for(i=n-1;i>=0;i--){
output[freq[(arr[i]/place)%range]-1]=arr[i];
freq[(arr[i]/place)%range]--;
}
for(i=0;i<n;i++)
arr[i]=output[i];
}
void radixsort(ll arr[],int n,int maxx){ //maxx is the maximum element in the array
int mul=1;
while(maxx){
countsort(arr,n,mul);
mul*=10;
maxx/=10;
}
}
```
### Más información:
* [Wikipedia](https://en.wikipedia.org/wiki/Radix_sort)
* [GeeksForGeeks](http://www.geeksforgeeks.org/radix-sort/)

View File

@@ -0,0 +1,67 @@
---
title: Selection Sort
localeTitle: Selección de selección
---
## Selección de selección
El ordenamiento por selección es uno de los algoritmos de clasificación más simples. Funciona de la siguiente manera,
1. Encuentra el elemento más pequeño. Intercambia con el primer elemento.
2. Encuentra el segundo elemento más pequeño. Intercambia con el segundo elemento.
3. Encuentra el tercer elemento más pequeño. Intercambiala con el tercer elemento.
4. Repita la búsqueda del siguiente elemento más pequeño y colóquelo en la posición correcta correspondiente hasta que se clasifique la matriz.
Como puede adivinar, este algoritmo se denomina Selección de selección porque selecciona repetidamente el siguiente elemento más pequeño y lo intercambia en su lugar.
Pero, ¿cómo escribiría el código para encontrar el índice del segundo valor más pequeño en una matriz?
* Una forma fácil es notar que el valor más pequeño ya se ha cambiado al índice 0, por lo que el problema se reduce a encontrar el elemento más pequeño en la matriz que comienza en el índice 1.
### Implementación en C / C ++
```C
for(int i = 0; i < n; i++)
{
int min_index = i;
int min_element = a[i];
for(int j = i +1; j < n; j++)
{
if(a[j] < min_element)
{
min_element = a[j];
min_index = j;
}
}
swap(&a[i], &a[min_index]);
}
```
### Implementación en Javascript
\`\` \`Javascript selección de función _ordenar (A) { var len =_ longitud de la _matriz_ (A); para (var i = 0; i <len - 1; i = i + 1) { var j _min = i; para (var j = i + 1; j <len; j = j + 1) { si (A \[j\] <A \[j_ min\]) { j _min = j; } else {} } si (j_ min! == i) { swap (A, i, j\_min); } else {} } }
función de intercambio (A, x, y) { temp temp = A \[x\]; A \[x\] = A \[y\]; A \[y\] = temp; }
```
### Implementation in Python
```
pitón orden de selección _(arr): si no arr volver arr para i en rango (len (arr)): min_ i = i para j en rango (i + 1, len (arr)): si arr \[j\] <arr \[min _i\]: min_ i = j arr \[i\], arr \[min _i\] = arr \[min_ i\], arr \[i\] \`\` \`
### Propiedades
* Complejidad del espacio: **O (n)**
* Complejidad del tiempo: **O (n 2 )**
* Clasificación en el lugar: **Sí**
* Estable: **no**
### Visualización
* [USFCA](https://www.cs.usfca.edu/~galles/visualization/ComparisonSort.html)
* [HackerEarth](https://www.hackerearth.com/practice/algorithms/sorting/selection-sort/visualize/)
### Referencias
* [Wikipedia](https://en.wikipedia.org/wiki/Selection_sort)
* [Academia Khan](https://www.khanacademy.org/computing/computer-science/algorithms#sorting-algorithms)

View File

@@ -0,0 +1,112 @@
---
title: Timsort
localeTitle: Timsort
---
## Timsort
Timsort es un algoritmo de clasificación rápida que trabaja con una complejidad estable de O (N log (N))
Timsort es una mezcla de Insertion Sort y Mergesort. Este algoritmo se implementa en Arrays.sort () de Java, así como en ordenado () y sort () de Python. La parte más pequeña se clasifica utilizando el orden de inserción y luego se fusiona utilizando Mergesort.
Una implementación rápida en Python:
```
def binary_search(the_array, item, start, end):
if start == end:
if the_array[start] > item:
return start
else:
return start + 1
if start > end:
return start
mid = round((start + end)/ 2)
if the_array[mid] < item:
return binary_search(the_array, item, mid + 1, end)
elif the_array[mid] > item:
return binary_search(the_array, item, start, mid - 1)
else:
return mid
"""
Insertion sort that timsort uses if the array size is small or if
the size of the "run" is small
"""
def insertion_sort(the_array):
l = len(the_array)
for index in range(1, l):
value = the_array[index]
pos = binary_search(the_array, value, 0, index - 1)
the_array = the_array[:pos] + [value] + the_array[pos:index] + the_array[index+1:]
return the_array
def merge(left, right):
"""Takes two sorted lists and returns a single sorted list by comparing the
elements one at a time.
[1, 2, 3, 4, 5, 6]
"""
if not left:
return right
if not right:
return left
if left[0] < right[0]:
return [left[0]] + merge(left[1:], right)
return [right[0]] + merge(left, right[1:])
def timsort(the_array):
runs, sorted_runs = [], []
length = len(the_array)
new_run = [the_array[0]]
# for every i in the range of 1 to length of array
for i in range(1, length):
# if i is at the end of the list
if i == length - 1:
new_run.append(the_array[i])
runs.append(new_run)
break
# if the i'th element of the array is less than the one before it
if the_array[i] < the_array[i-1]:
# if new_run is set to None (NULL)
if not new_run:
runs.append([the_array[i]])
new_run.append(the_array[i])
else:
runs.append(new_run)
new_run = []
# else if its equal to or more than
else:
new_run.append(the_array[i])
# for every item in runs, append it using insertion sort
for item in runs:
sorted_runs.append(insertion_sort(item))
# for every run in sorted_runs, merge them
sorted_array = []
for run in sorted_runs:
sorted_array = merge(sorted_array, run)
print(sorted_array)
timsort([2, 3, 1, 5, 6, 7])
```
#### Complejidad:
Tim sort tiene una Complejidad estable de O (N log (N)) y se compara realmente bien con Quicksort. Se puede encontrar una combinación de complejidades en este [cuadro.](https://cdn-images-1.medium.com/max/1600/1*1CkG3c4mZGswDShAV9eHbQ.png)
#### Más información:
* [Wikipedia](https://en.wikipedia.org/wiki/Timsort)
* [GeeksForGeeks](https://www.geeksforgeeks.org/timsort/)
* [Youtube: una explicación visual de Quicksort](https://www.youtube.com/watch?v=jVXsjswWo44)
#### Créditos:
[Implementación de Python](https://hackernoon.com/timsort-the-fastest-sorting-algorithm-youve-never-heard-of-36b28417f399)