domingo, 22 de noviembre de 2015

Metodos de Ordenamiento:

1) Ordenamiento de la burbuja

Este es el algoritmo más sencillo probablemente. Ideal para empezar. Consiste en ciclar repetidamente a través de la lista, comparando elementos adyacentes de dos en dos. Si un elemento es mayor que el que está en la siguiente posición se intercambian.

Algoritmo

for i = 1:n,
    swapped = false
    for j = n:i+1, 
        if a[j] < a[j-1], 
            swap a[j,j-1]
            swapped = true
    → invariant: a[1..i] in final position
    break if not swapped
end


2) Ordenamiento por Selección
-Buscas el elemento más pequeño de la lista.
-Lo intercambias con el elemento ubicado en la primera posición de la lista.
-Buscas el segundo elemento más pequeño de la lista.
-Lo intercambias con el elemento que ocupa la segunda posición en la lista.
-Repites este proceso hasta que hayas ordenado toda la lista.

Algoritmo

for i = 1:n,
    k = i
    for j = i+1:n, if a[j] < a[k], k = j
    → invariant: a[k] smallest of a[i..n]
    swap a[i,k]
    → invariant: a[1..i] in final position
end


3) Ordenamiento por Quick
Esta es probablemente la técnica más rápida conocida. Fue desarrollada por C.A.R. Hoare en 1960. El algoritmo original es recursivo, pero se utilizan versiones iterativas para mejorar su rendimiento (los algoritmos recursivos son en general más lentos que los iterativos, y consumen más recursos). El algoritmo fundamental es el siguiente:

-Eliges un elemento de la lista. Puede ser cualquiera Lo llamaremos elemento de división.
-Buscas la posición que le corresponde en la lista ordenada
-Acomodas los elementos de la lista a cada lado del elemento de división, de manera que a un lado queden todos los menores que él y al otro los mayores. En este momento el elemento de división separa la lista en dos sublistas .
-Realizas esto de forma recursiva para cada sublista mientras éstas tengan un largo mayor que 1. Una vez terminado este proceso todos los elementos estarán ordenados.

Algoritmo


# choose pivot
swap a[1,rand(1,n)]

# 2-way partition
k = 1
for i = 2:n, if a[i] < a[1], swap a[++k,i]
swap a[1,k]
→ invariant: a[1..k-1] < a[k] <= a[k+1..n]

# recursive sorts
sort a[1..k-1]
sort a[k+1,n]


4) Ordenamiento por inserción
Se guarda una copia del elemento actual y desplazar todos los elementos mayores hacia la derecha. Luego copiamos el elemento guardado en la posición del último elemento que se desplazó.

Algoritmo

for i = 2:n,
    for (k = i; k > 1 and a[k] < a[k-1]; k--) 
        swap a[k,k-1]
    → invariant: a[1..i] is sorted
end


5) Ordenamiento por Shell
Adaptación y mejora del método por inserción directa. Se utiliza un array con gran número de elemento en el cual compara a cada elemento con el que está a cierto número de lugares a su izquierda. Este salto es constante a razón de N/2 (siendo N el número de elementos). Se realiza el ciclo hasta que no se intercambien mas elementos de sitio. Este salto se reduce a la mitad y se vuelven a dar pasadas hasta que no se intercambie nadie con nadie. El algoritmo finaliza en el momento en que el salto es 1.

Algoritmo

h = 1
while h < n, h = 3*h + 1
while h > 0,
    h = h / 3
    for k = 1:h, insertion sort a[k:h:n]
    → invariant: each h-sub-array is sorted
end

6) Ordenamiento por Heap
Este método es una variante del método por selección, donde la búsqueda del elemento máximo de un arreglo se realiza mediante técnicas basadas en la construcción de un montículo.
Puede ser un montículo ascendente o descendente.

Algoritmo

# heapify
for i = n/2:1, sink(a,i,n)
→ invariant: a[1,n] in heap order

# sortdown
for i = 1:n,
    swap a[1,n-i+1]
    sink(a,1,n-i)
    → invariant: a[n-i+1,n] in final position
end

# sink from i in a[1..n]
function sink(a,i,n):
    # {lc,rc,mc} = {left,right,max} child index
    lc = 2*i
    if lc > n, return # no children
    rc = lc + 1
    mc = (rc > n) ? lc : (a[lc] > a[rc]) ? lc : rc
    if a[i] >= a[mc], return # heap ordered
    swap a[i,mc]
    sink(a,mc,n)

7) Ordenamiento por Merge
  MergeSort es un algoritmo de ordenamiento muy eficiente que utliza la técnica "divide y venceras". Su orden asintótico es O(n*log(n)).

Para ordenar un vector lo divide por la mitad en dos segmentos y ordena cada segmento de forma recursiva osea nuevamente divide cada segmento y ordena los subsegmentos de forma recursiva... hasta que en algún momento los segmentos serán de longitud 1 es cuando se llama a la función "merge" (mezclar) que intercala los elementos del ultimo segmento dividido colocando primero los elementos menores.

Algoritmo

# split in half
m = n / 2

# recursive sorts
sort a[1..m]
sort a[m+1..n]

# merge sorted sub-arrays using temp array
b = copy of a[1..m]
i = 1, j = m+1, k = 1
while i <= m and j <= n,
    a[k++] = (a[j] < b[i]) ? a[j++] : b[i++]
    → invariant: a[1..k] in final position
while i <= m,
    a[k++] = b[i++]
    → invariant: a[1..k] in final position

No hay comentarios:

Publicar un comentario