Beruflich Dokumente
Kultur Dokumente
FACULTAD DE INGENIERÍA
CURSO: ALGORÍTMICA II
ALGORITMOS DE ORDENAMIENTO
ABANCAY – APURÍMAC
2018
Escuela Académico Profesional de Ingeniería Informática y Sistemas – UNAMBA
ÍNDICE
Pág.
I. BUBBLE SORT (BURBUJA) ............................................................................................................... 1
1.1 Concepto ..................................................................................................................................... 1
1.2 Descripción.................................................................................................................................. 1
1.3 Algoritmo de Burbuja ................................................................................................................. 1
1.4 Pseudocódigo de Algoritmo Burbuja ......................................................................................... 1
1.5 Algoritmo de Burbuja en C ++ .................................................................................................... 2
1.6 Análisis del Algoritmo ................................................................................................................. 2
1.7 Ventajas y Desventajas ............................................................................................................... 2
II. ORDENAMIENTO POR SELECCIÓN (SELECTION SORT) ................................................................... 3
2.1 Definición .................................................................................................................................... 3
2.2 Su funcionamiento:..................................................................................................................... 3
2.3 Características ............................................................................................................................. 3
2.4 Pseudocodigo .............................................................................................................................. 3
2.5 Análisis del Costo Computacional .............................................................................................. 4
2.6 Estabilidad, Ventajas y Desventajas........................................................................................... 4
III. COUNTING SHORT ...................................................................................................................... 7
3.1 Definición .................................................................................................................................... 7
3.2 Tipos de ordenamientos por cuentas ........................................................................................ 7
3.3 Análisis del algoritmo ................................................................................................................. 7
3.4 Pseudocódigo .............................................................................................................................. 8
3.5 código en c++ .............................................................................................................................. 9
IV. QUICK SORT .............................................................................................................................. 11
4.1 Definición .................................................................................................................................. 11
4.2 El ordenamiento de QuickSort ................................................................................................. 11
4.3 Pseudocodigo ............................................................................................................................ 13
4.4 Codificación en C++ ................................................................................................................. 14
4.5 Análisis del Algoritmo ............................................................................................................... 15
4.6 Técnicas de elección del Pivote ................................................................................................ 16
4.7 Técnicas de Reposicionamiento ............................................................................................. 16
V. MERGE SORT ................................................................................................................................. 17
5.1 Definición .................................................................................................................................. 17
5.2 Paso para realizar este algoritmo............................................................................................. 17
5.3 Descripción................................................................................................................................ 17
5.4 Pseudocódigo ............................................................................................................................ 17
Escuela Académico Profesional de Ingeniería Informática y Sistemas – UNAMBA
INTRODUCCIÓN
Esta guía nos permitirá conocer más a fondo cada método de ordenamiento,
desde uno que es más simple hasta el más complejo. Se realizaran
comparaciones en tiempo de ejecución, pre-requisitos de cada algoritmo,
funcionalidad, alcance, etc.
Escuela Académico Profesional de Ingeniería Informática y Sistemas – UNAMBA
1.1 Concepto
La Ordenación de burbuja (Bubble Sort en inglés) es un sencillo algoritmo de ordenamiento.
Revisa cada elemento de la lista que va a ser ordenada con el siguiente, intercambiándolos
de posición si están en el orden incorrecto. Es necesario revisar varias veces toda la lista
hasta que no se necesiten más intercambios, lo cual significa que la lista está ordenada. Este
algoritmo obtiene su nombre de la forma con la que suben por la lista los elementos durante
los intercambios, como si fueran pequeñas "burbujas". También es conocido como el
método del intercambio directo. Dado que solo usa comparaciones para operar elementos,
se lo considera un algoritmo de comparación, siendo el más sencillo de implementar.
Este algoritmo es esencialmente un algoritmo de fuerza bruta lógica.
1.2 Descripción
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.
aux ← V*j+
V*j+ ← V*j+1+
V*j+1+ ← aux
fin_si
fin_desde
fin_desde
fin
2.1 Definición
Algoritmo de ordenamiento por Selección (Selection Sort en inglés): Consiste en encontrar el
menor de todos los elementos del arreglo o vector e intercambiarlo con el que está en la
primera posición. Luego el segundo más pequeño, y así sucesivamente hasta ordenarlo todo.
Su implementación requiere O(n2) comparaciones e intercambios para ordenar una
secuencia de elementos.
2.2 Su funcionamiento:
Buscar el mínimo elemento de la lista
Intercambiarlo con el primero
Buscar el mínimo en el resto de la lista
Intercambiarlo con el segundo y en general:
Buscar el mínimo elemento entre una posición i y el final de la lista
Intercambiar el mínimo con el elemento de la posición i.
2.3 Características
Su tiempo de ejecución es O(N2) para el mejor, peor y caso promedio.
Si el array de datos es A y su tamaño es N, lo que hace el algoritmo, para cada i de
[0...N-2] es intercambiar A[i] con el mínimo elemento del subarray [A[i+1], ...,A[N]].
Dado que es muy simple de codificar, aunque no tiene los mejores tiempos de
ejecución, es apropiado utilizarlo para arrays de datos relativamente pequeños.
2.4 Pseudocodigo
Variables: i, j, k, A[100],menor,n
Inicio
Declarar i, menor, k, j: entero
Para i <- 1 hasta n-1 haga
Menor <- A[i]
k <- i
Para j <- i+1 hasta n haga
Si (A[j]<menor) entonces
Menor <- A[j]
k <- j
Fin si
Fin para
A[k] <- A[i]
A[i] <- menor
Fin para
Fin
Ventajas:
Este algoritmo realiza menos operaciones de intercambio que el de la burbuja, por lo que
lo mejora en algo.
Fácil implementación.
No requiere memoria adicional.
Realiza pocos intercambios.
Rendimiento constante: poca diferencia entre el peor y el mejor caso.
Desventajas:
Lento
poco eficiente cuando se usa en listas grandes o medianas
Realiza numerosas comparaciones
Otra desventaja de este algoritmo respecto a otros como el de burbuja o de inserción directa
es que no mejora su rendimiento cuando los datos ya están ordenados o parcialmente
ordenados.
Ejemplos:
Ejemplo 1: Vamos a ordenar la siguiente lista:
4-3-5-2-1
Empezamos tomando el primer elemento el cual es 4; se comparará con todo los elementos
del arreglo y de ello tomará el menor. Lo intercambiamos con el 4 y la lista queda así:
1-3-5-2-4
Ahora buscamos el menor elemento entre la segunda y la última posición. Es el 2. Lo
intercambiamos con el elemento en la segunda posición, es decir el 3. La lista queda así:
1-2-5-3-4
Buscamos el menor elemento entre la tercera posición y la última. Es el 3, que
intercambiamos con el 5:
1-2-3-5-4
El menor elemento entre la cuarta y quinta posición es el 4, que intercambiamos con el 5:
1-2-3-4-5
ya tenemos nuestra lista ordenada.
1° pasada: buscamos entre los últimos n (es decir, 5) elementos el menor de todos, y lo
intercambiaremos con la primera posición.
45, 52, 21, 37, 49 → Para buscar el menor, necesitaremos un bucle for que recorra los n
últimos elementos.
45, 52, 21, 37, 49 → El menor es el 21, colocado en tercera posición.
45, 52, 21, 37, 49 → Lo intercambiamos con el de la primera posición.
21, 52, 45, 37, 49 → Ya tenemos uno en orden. Nos quedan los n-1 últimos.
2° pasada: buscamos entre los últimos n-1 (es decir, 4) elementos el menor de todos, y lo
intercambiaremos con la segunda posición.
21, 52, 45, 37, 49 → Recorremos los cuatro últimos y el menor es el 37.
21, 37, 45, 52, 49 → Lo intercambiamos con la segunda posición y ya hay dos en orden.
3° pasada: buscamos entre los últimos n-2 (es decir, 3) elementos el menor de todos, y lo
intercambiaremos con la tercera posición.
21, 37, 45, 52, 49 → El menor es el 45, en tercera posición.
21, 37, 45, 52, 49 → El 45 ya estaba en 3ª posición, así que al intercambiarlo con él mismo,
se queda dónde está. Ya tenemos tres en orden.
4° y última pasada: buscamos entre los últimos n-3 (es decir, 2) elementos el menor de
todos, y lo intercambiaremos con la cuarta posición.
21, 37, 45, 52, 49 → El menor es el 49, en quinta posición.
21, 37, 45, 49, 52 → Lo intercambiamos con la cuarta posición. Ya hay cuatro en orden.
21, 37, 45, 49, 52 → El último está necesariamente en orden también.
CODIGO EN C++
#include<iostream.h>
#include<conio.h>
main()
{ int A[100],n,i,j,menor,k;
cout<<"ingrese la dimensión del vector";
cin>>n;
for(i=1;i<=n;i++)
{ cout<<"A["<<i<<"]:"; cin>>A[i];
}
for (i=1; i<=n-1;i++)
{ menor=A[i];
k=i;
for(j=i+1; j<=n;j++)
{ if(A[j]<menor)
{ menor=A[j];
k=j;
}
}
A[k]=A[i];
A[i]=menor;
}
for(k=1;k<=n;k++)
cout<<A[k]<<endl;
getch();
}
3.1 Definición
El ordenamiento por cuentas (counting sort en inglés) es un algoritmo de ordenamiento en
el que se cuenta el número de elementos de cada clase para luego ordenarlos. Sólo puede
ser utilizado por tanto para ordenar elementos que sean contables (como los números
enteros en un determinado intervalo, pero no los números reales, por ejemplo).
a) Los internos: Son aquellos en los que los valores a ordenar están en memoria
principal, por lo que se asume que el tiempo que se requiere para acceder
cualquier elemento sea el mismo (a[1], a[300], etc.).
b) Los externos: Son aquellos en los que los valores a ordenar están en memoria
secundaria (disco, cinta, cilindro magnético, etc.), por lo que se asume que el
tiempo que se requiere para acceder a cualquier elemento depende de la última
posición accesada (posición 1, posición 300, etc.).
3.4 Pseudocódigo
Inicio
Variables (A [15], aux [100], i, j, ma, me, ord;
//ingresamos la dimensión a leer dimensión: n
Hacer para i=1 hasta n
Leer A[i]
si(A[i] > k)
k = A[i]; INGRESO DE DATOS AL ARREGLO
finsi
me=A[i]
finhacer
hacer para i=me hasta ma PRIMER FOR RRECORRE DESDE EL VALOR MENOR
hacer para i=1 hasta n (PROCESO DE CONTEO
si j = A[i] SEGUNDO FOR RRECORRE LOS VALORES DEL ARREGLO A[i]
aux[ord]=A[i]; *DENTRO DEL CONDICIONAL SE REALIZARA LA
COMPARACION (VALOR A[i]CON LA POSICION i CONTEO QUE
ord=ord+1;
VA DESDE EL VALOR MENORMAYOR)
finsi *POR ULTIMO EL OTRO CONDICIONAL SI CUANDO SE DA EL
si A[i]==Aux[ord] CASO DE TENER 2 MISMOS VALORES DENTRO DEL ARREGLO
new_ord1=new_ord-1 DENTRO DEL CUAL COMPARA VALOR A[i] con la posición
finsi CONTEO Y EN EL CASO DE LOS DOS VALORES IGUALES ,UNA
VARIABLE new_ord1 QUE INTRODUCIRA EL VALOR DE LA
POSICION CONTEO EN EL NUEVO ARREGLO Aux[ord] QUE
fin hacer UNA VEZ SE DE EL CASO DE 2 VALORES IGUALES
fin hacer INTRODUCIRA EL PRIMER VALOR REPETIDO ,LUEGO SE
REDUCIRA EN 1 Y INSERTARA EL OTRO VALOR QUE SE REPITE
EN LA SIGUIENTE CASILLA
Ejemplo1
Lista a ordenar no se repite ningún elemento: 5 2 4 3 1
buscar el mínimo y el máximo:
Mínimo=1
Máximo=5
En Este caso no usaremos variables auxiliares puesto que los valores que tenemos en el
arreglo no se repiten
4.1 Definición
El algoritmo conocido como Quicksort (ordenamiento rápido) recibe el nombre de su
autor, Tony Hoare. La idea del algoritmo es simple, se basa en la división en particiones de la
lista a ordenar, por lo que se puede considerar que aplica la técnica divide y vencerás. Este
método es posiblemente el más pequeño en cuanto se refiere al código, más rápido, más
elegante, más interesante y eficiente de los algoritmos de ordenamiento conocidos, ya que
permite en promedio, ordenar n-elementos en un tiempo proporcional a n log n.
Este método de ordenamiento es una mejora del 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 método se basa en dividir los “n “ elementos de la lista de ordenar en dos partes o
particiones separadas por un elemento: una partición izquierda , un elemento central
denominado pivote o elemento de partición ,y una partición derecha . La partición o
división se hace de tal forma que todo los elementos de la primera sub-lista (partición
izquierda) son menores que todos los elemento de la segunda sub-lista (partición
derecha). Las dos sub-listas se ordenan entonces independientemente.
Para dividir la lista en particiones (sub-listas) se elige uno de los elementos de la lista y
se utiliza como pivote o elemento de partición .Si se elige una lista cualquiera con los
elementos en orden aleatoria, se puede seleccionar cualquier elemento de la lista como
pivote ,por ejemplo ,el primer elemento de la lista. Si la lista tiene algún orden parcial
conocido, se puede tomar otra decisión paralela pivote. Idealmente ,el pivote se debe
elegir de modo que se divida la lista exactamente por la mitad, de acuerdo al tamaño
relativo de las claves. Por ejemplo, si se tiene una lista de enteros de 1 a 10, 5 o 6 serían
pivotes ideales , mientras que 1 o 10 serían elecciones “pobres” de pivotes.
Una vez que el pivote ha sido elegido , se utiliza para ordenar el resto de la lista en
dos sub-listas : una tiene toda las claves menores que el pivote y la otra todos los
elementos ( claves ) mayores o iguales que el pivote ( o al revés ). Estas dos listas
parciales se ordenan recursivamente utilizando el mismo algoritmo; es decir, se llama
sucesivamente al propio algoritmo quicksort . La lista final ordenada se consigue
concatenando la primera sub-lista , el pivote y la segunda lista , en ese orden , en una
única lista .La primera etapa de quicksort es la división o “ particionado ” recursivo de la
lista hasta que todas las sub-listas constan de sólo un elemento.
La elección del pivote es muy importante, pues el buen funcionamiento del quicksort
depende en gran medida de lo balanceadas que queden las particiones.
Análises
1. Ingresamos 5 números cualquiera
8 0 3 1 4
2. Se elige el pivote
Pivote=(primero +ultimo)/2
Pivote=A[(0+4)/2]=A[2]=3
Pivote
8 0 3 1 4
Sub-lista derecha
8 4
Pivote
3
7. En la sub-lista izquierda como pivote se toma a cualquiera de ellos.
7.1. En este caso se va tomar 1 como pivote para luego comparar
0 1
4.3 Pseudocodigo
inicio
variables B: arreglo[100] entero
variables n,i,j,: entero
variables primero, ultimo: entero
escribir(ingrese dimensión de array)
leer (n)
escribir (ingrese elemento)
para i = 1 hasta n
leer(B[i])
Fin para
quicksort(B,0,n-1)
escribir (B,n)
Fin
j = j-1
fin si
fin hacer
mientras i <= j
si primero < j
quicksort(A,primero,j)
fin si
si i < ultimo
quicksort(A,i, ultimo)
fin si
fin funcion quicksort
funcion escribir(A[100],n: entero)
i: entero
escribir (arreglo ordenado ascendentemente)
para i=1 hasta n
escribir (A[i])
fin para
fin funcion escribir
#include<iostream.h>
#include<conio.h>
void quicksort(double [20],int, int);
void escribir(double [20],int );
main()
{ int i,nro;
double B[20];
cout<<" Ingrese la diomension del arreglo"<<endl;
cin>>nro;
cout<<" Ingree elementos del arreglo"<<endl;
for(i=0;i<nro;i++)
{ cout<<"B["<<i<<"]= ";
cin>>B[i];
}
cout<<" ARREGLO ORIGINAL "<<endl;
for(i=0;i<nro;i++)
{ cout<<" "<<B[i];
}
quicksort(B,0,nro-1);
escribir(B,nro);
getch();
}
Ventajas: El algoritmo básico Quicksort permite tomar cualquier elemento de la lista como
pivote, dependiendo de la partición n que se elija, el algoritmo será más o menos eficiente.
Tomar un elemento cualquiera como pivote tiene la ventaja de no requerir ningún cálculo
adicional, lo cual lo hace bastante rápido. Sin embargo, esta elección «a ciegas» siempre
provoca que el algoritmo tenga un orden de O(n²) para ciertas permutaciones de los
elementos en la lista.
Muy rápido.
No requiere memoria adicional.
Pero principalmente depende del pivote, si por ejemplo el algoritmo implementado toma
como pivote siempre el primer elemento del array, y el array que le pasamos está ordenado,
siempre va a generar a su izquierda un array vacío, lo que es ineficiente.
Implementación un poco más complicada.
Recursividad (utiliza muchos recursos).
Mucha diferencia entre el peor y el mejor caso
Tomar un elemento cualquiera como pivote tiene la ventaja de no requerir ningún cálculo
adicional, lo cual lo hace bastante rápido. Sin embargo, esta elección «a ciegas» siempre
provoca que el algoritmo tenga un orden de O(n²) para ciertas permutaciones de los
elementos en la lista.
Recorrer la lista simultáneamente con i y j: por la izquierda con i (desde el primer elemento),
y por la derecha con j (desde el último elemento).
V. MERGE SORT
5.1 Definición
El algoritmo de Ordenamiento por mezcla (Merge sort) es un algoritmo de ordenación
externo estable basado en la técnica divide y vencerás. Es de complejidad O(n log n).
Este algoritmo consiste: Consiste en dividir en dos partes iguales el vector a ordenar,
ordenar por separado cada una de las partes, y luego mezclar ambas partes, manteniendo el
orden, en un solo vector ordenado.
Creador: Este algoritmo fue desarrollado por el matemático Húngaro John Von Neumann en
1945.
VENCER: ordena las dos sub secuencias de manera recursiva mediante el algoritmo
MERGESORT.
COMBINAR: combina las dos sub secuencias ordenadas para generar la solución.
5.3 Descripción
Conceptualmente, el ordenamiento por mezcla funciona de la siguiente manera:
Si la longitud de la lista es 0 ó 1, entonces ya está ordenada. En otro caso:
Dividir la lista desordenada en dos sub listas de aproximadamente la mitad del
tamaño.
Ordenar cada sub lista recursivamente aplicando el ordenamiento por mezcla.
Mezclar las dos sub listas en una sola lista ordenada.
El ordenamiento por mezcla incorpora dos ideas principales para mejorar su tiempo de
ejecución:
1º Una lista pequeña necesitará menos pasos para ordenarse que una lista grande.
2º Se necesitan menos pasos para construir una lista ordenada a partir de dos listas
también ordenadas, que a partir de dos listas desordenadas. Por ejemplo, sólo será
necesario entrelazar cada lista una vez que están ordenadas.
A continuación se describe el algoritmo en pseudocódigo (se advierte de que no se
incluyen casos especiales para vectores vacíos, etc.; una implementación en un
lenguaje de programación real debería tener en cuenta estos detalles):
5.4 Pseudocódigo
#include <iostream>
using namespace std;
//modulo para llenar datos en el arreglo
orden_mergesort(der,mit,arregloA,arregloB);
orden_mergesort(mit+1,izq,arregloA,arregloB);
merge(arregloA,arregloB,der,mit+1,izq);
}
}
int main(int argc, char *argv[])
{ int dim;
int arregloA[50];
int arregloB[50];
cout<<"ingrese dimension del arreglo:"<<endl;
cin>>dim;
leeArreglo(arregloA,dim);//llamando al modulo para ingresar datos
cout<<"Los datos del arreglo son:"<<endl;
mostrar_arreglo(arregloA,dim);
cout<<endl;
cout<<endl;
cout<<"Aplicando mergesort:"<<endl;
orden_mergesort(1,dim,arregloA,arregloB);
mostrar_arreglo(arregloA,dim);
return 0;
}
5.6 Conclusiones
El estudio de algoritmos de ordenamiento tiene una gran importancia dentro de la Ciencia
de la Computación, pues una buena cantidad de los procesos realizados por medios
computacionales requieren que sus datos estén ordenados. Además, el hecho de
almacenar los datos de manera ordenada permite implementar algoritmos de búsqueda
muy rápidos (por ejemplo: búsqueda binaria). Esta y muchas otras razones de fin práctico
impulsaron el estudio y la búsqueda de algoritmos de ordenamiento eficientes.
6.1 Definición
El método de ordenamiento del Shell Sort es una generalización del ordenamiento por
inserción y mejora comparando elementos ingresados separados por un espacio de varias
posiciones. Esto permite que un elemento haga con saltos de mayor tamaño hacia su
posición esperada. Los pasos múltiples sobre los datos se hacen con tamaños de espacio
cada vez más pequeños.
Este método también se conoce con el nombre de inserción con incrementos decrecientes.
Shell modifico los saltos contiguos resultantes de las comparaciones por saltos de mayor
tamaño y con eso se conseguía la clasificación más rápida. El método se basa en fijar el
tamaño de los saltos constantes, pero de más de una posición.
El último paso del Shell Sort es un simple ordenamiento por inserción.
Ventajas
Fácil implementación
Es un algoritmo muy simple teniendo un tiempo de ejecución aceptable
Es uno de los algoritmos más rápidos.
No requiere memoria adicional.
Ordena de manera burbuja, pero más rápido
Desventajas
Su complejidad es difícil de calcular y depende mucho de la secuencia de Incrementos que
utilice.
Shell Sort es un algoritmo no es estable porque se puede perder el orden relativo
6.4 Complejidad
Dependiendo de la elección de la secuencia de espacios, Shell sort tiene un tiempo de
ejecución en el peor caso de O(n2) (usando los incrementos de Shell que comienzan con
1/2 del tamaño del vector y se dividen por 2 cada vez.
La existencia de una implementación O(nlogn) en el peor caso del Shell sort permanece
como una pregunta por resolver.
Ejemplo: ordenar las siguientes claves del arreglo A: 15, 67, 8, 16, 44, 27, 12,35.
Paso 1
Los elementos saltan de 4 en 4 y si cumple que a>b a toma el lugar de b y b toma el lugar
de a:
15, 67, 8, 16, 44, 27, 12, 35
La ordenación se produce:
15, 67, 8, 16, 44, 27, 12, 35
15, 67, 8, 16, 44, 27, 12, 35 No hay cambios a hacer
15, 27, 8, 16, 44, 67, 12, 35 El 67 se sustituye por el (67>27)
15, 67, 8, 16, 44, 27, 12, 35 No hay cambios a hacer
15, 67, 8, 16, 44, 27, 12, 35 No hay cambios a hacer
Paso 2
Los elementos van en saltos de 2 en 2; porque después de haber hecho la 1º pasada el salto
se divide entre 2.
15, 27, 8, 16, 44, 27, 12, 35
La ordenación se produce: 15, 27, 8, 16, 44, 27, 12, 35
8, 27, 15, 16, 44, 27, 12, 35 El 15 se sustituye por el 8 ,15>8
8, 16, 15, 27, 44, 67, 12, 35 El 27 se sustituye por el 16 ,27>16
8, 16, 15, 27, 44, 67, 12, 35 No hay cambios a hacer
8, 16, 15, 27, 44, 67, 12, 35 No hay cambios a hacer
8, 16, 15, 27, 12, 67, 44, 35 El 44 se sustituye por el 12,44>12
8, 16, 15, 27, 12, 35, 44, 67 El 67 se sustituye por el 35,67>35
Otra vez se procede con salto 2 hasta que no haya elementos a comparar.
8, 16, 15, 27, 12, 35, 44, 67 No hay cambios a hacer
8, 16, 15, 27, 12, 35, 44, 67 No hay cambios a hacer
8, 16, 15, 27, 12, 35, 44, 67 No hay cambios a hacer
8, 16, 12, 27, 15, 35, 44, 67 El 15 se sustituye por el 12,15>12
8, 16, 12, 27, 15, 35, 44, 67 No hay cambios a hacer
8, 16, 12, 27, 15, 35, 44, 67 No hay cambios a hacer
Paso 3
Los elementos van en saltos de 1 en 1 porque después de haber hecho la 2da pasada el salto
se divide entre 2; se realiza porque en la 2da pasada ya hay cambios.
Otra vez procede con salto 1 hasta que no haya elementos a comparar
8, 12, 16, 15, 27, 35, 44, 67 No hay cambios a hacer
8, 12, 16, 15, 27, 35, 44, 67 No hay cambios a hacer
8, 12, 15, 16, 27, 35, 44, 67 El 16 se sustituye por el 15,16>15
8, 12, 15, 16, 27, 35, 44, 67 No hay cambios a hacer
8, 12, 15, 16, 27, 35, 44, 67 No hay cambios a hacer
8, 12, 15, 16, 27, 35, 44, 67 No hay cambios a hacer
8, 12, 15, 16, 27, 35, 44, 67 No hay cambios a hacer
La ordenación produce:
8, 12, 15, 16, 27, 35, 44, 67 Ya está ordenado.
6.6 Pseudocódigo
6.8 Conclusiones
Este algoritmo eficaz, relativamente eficiente en la mayoría de los casos, fácil de
implementar, no consume memoria extra dinámicamente y se comporta bastante bien
para unos datos de entrada de mediano tamaño.
Es un algoritmo de ordenación interna muy sencillo pero muy ingenioso, basado en
comparaciones e intercambios, y con unos resultados radicalmente mejores que los que
se pueden obtener con el método de la burbuja, el de selección directa o el de inserción
directa.
Tiene una gran importancia dentro de la Ciencia de la Computación, pues una buena
cantidad de los procesos realizados por medios computacionales requieren que sus
datos estén ordenados.
7.1 Definición
Esta es una mejora al método de la burbuja, ya que su manera de trabajar de este algoritmo
es ir ordenado al mismo tiempo por los dos extremos del vector.
Se llama "Shaker", ya que da el efecto de un movimiento de agitación o sacudida a la matriz.
Aunque este método de sacudida es una mejora al método de la burbuja, su complejidad del
algoritmo sigue siendo O(n²).
Este método consta de dos etapas:
Este método consta de dos etapas:
La Primera.- “De Derecha A Izquierda” se traslada los elementos más pequeños hacia la
parte izquierda del arreglo, almacenando en una variable la posición del último elemento
intercambiado.
La Segunda.- “De Izquierda A Derecha” se traslada los elementos más grandes hacia la
parte derecha del arreglo, almacenando en otra variable la posición del último elemento
intercambiado.
Esto termina cuando en una etapa no se producen intercambios o bien cuando el contenido
de la variable que almacena el extremo izquierdo del arreglo es mayor que el contenido de la
variable que almacena el extremo derecho.
Factores que afectan directamente al tiempo de ejecución del algoritmo:
Las comparaciones entre los elementos.
Los intercambios entre los mismos.
Las pasadas que se realizan
Ejemplo:
//Sean los elementos que conforman el vector A:[7,6,2,8,1,5,3,4]
Primera pasada:
Trasladaremos el elemento menor a la izquierda comparando cada elemento
Primera etapa:
A:[7,6,2,8,1,5,3,4]
[3>4] no ==> No hay intercambio A:[6,7,2,8,1,5,3,4]
[5>3] si ==> Si hay intercambio A:[6,7,2,8,1,3,5,4]
[1>3] no ==> No hay intercambio A:[6,7,2,8,1,3,5,4]
[8>1] si ==> Si hay intercambio A:[6,7,2,1,8,3,5,4]
[2>1] si ==> Si hay intercambio A:[6,7,1,2,8,3,5,4]
[7>1] si ==> Si hay intercambio A:[6,1,7,2,8,3,5,4]
[6>1] si ==> Si hay intercambio A:[1,6,7,2,8,3,5,4]
A: [1, 6, 7, 2, 8, 3, 5, 4]
Segunda etapa:
A: [1,6,7,2,8,3,5,4]
[6>7] no ==> No hay intercambio A:[1,6,7,2,8,3,5,4]
Segunda Pasada
Trasladaremos el segundo elemento menor a la izquierda comparando cada elemento
Primera etapa:
A: [1,6,2,7,3,5,4,8]
[5>4] si ==> Si hay intercambio A:[1,6,2,7,3,4,5,8]
[3>4] no ==> No hay intercambio A:[1,6,2,7,3,4,5,8]
[7>3] si ==> Si hay intercambio A:[1,6,2,3,7,4,5,8]
[2>3] no ==> No hay intercambio A:[1,6,2,3,7,4,5,8]
[6>2] si ==> Si hay intercambio A:[1,2,6,3,7,4,5,8]
A:[1,2,6,3,7,4,5,8]
El tercer valor ordenado 2
Segunda etapa:
De izquierda a derecha
A: [1, 2, 6, 3, 7, 4, 5, 8]
[6>3] si ==> Si hay intercambio A:[1,2,3,6,7,4,5,8]
[6>7] no ==> No hay intercambio A:[1,2,3,6,7,4,5,8]
[7>4] si ==> Si hay intercambio A:[1,2,3,6,4,7,5,8]
[7>5] si ==> Si hay intercambio A:[1,2,3,6,4,5,7,8]
A: [1, 2, 3, 6, 4, 5, 7, 8]
El cuarto valor ordenado 7
De derecha a izquierda
[4>5] no ==> No hay intercambio A:[1,2,3,6,4,5,7,8]
[6>4] si ==> Si hay intercambio A:[1,2,3,4,6,5,7,8]
[3>4] no ==> No hay intercambio A:[1,2,3,4,6,5,7,8]
A: [1, ,3, 4, 6, 5, 7, 8]
El quinto valor ordenado 3
De izquierda a derecha
[4>6] no ==> No hay intercambio A:[1,2,3,4,6,5,7,8]
[6>5] si ==> Si hay intercambio A:[1,2,3,4,5,6,7,8]
A: [1, 2, 3, 4, 5, 6, 7, 8]
El sexto valor ordenado 6
De derecha a izquierda
[4>5] no ==> No hay intercambio A:[1,2,3,4,5,6,7,8]
El séptimo valor ordenado 4
Desventajas
- Muy lento.
- Realiza muchas comparaciones.
- Realiza numerosas intercambios.
- Es inestable, no mantiene el orden relativo de los registros
7.3 Pseudocódigo
Proceso ShakerSort
Escribir "Ingrese el número de elementos"
Leer tam
Dimension v[20]
Para i<-1 Hasta tam Hacer
Escribir "V[",i,"]"
Leer v[i]
FinPara
//Asignación de los Valores
izq <- 2
der <- tam
ultimo <- tam
Repetir
//Codigo del ordenamiento a la izquierda
Para i <- der hasta izq hacer//Los valores menores van a la izquierda
Si v[i-1] > v[i] entonces//der va disminuyendo en 1 hsta llegar a izq
aux <- v[i]
v[i] <- v[i-1]
v[i-1] <- aux
ultimo <- i
FinSi
FinPara
izq <- ultimo+1
// Codigo del ordenamiento a la derecha
Para j <- izq hasta der hacer //Los valores mayores van a la derecha
Si (v[j-1] > v[j]) entonces
aux <- v[j]
v[j] <- v[j-1]
v[j-1] <- aux
ultimo <- j
FinSi
FinPara
der <- ultimo-1
Hasta Que (izq > der)
//imprimimos el nuevo arreglo
Escribir "nuevo arreglo"
Para i<-1 Hasta tam Hacer
Escribir v[i]
FinPara
#include <iostream>
using namespace std;
int main(int argc, char *argv[])
{ int izq,der, aux,i,N,k;
float A[20];
cout<<"ingrese dimencion del arreglo ==> "; cin>>N;
k=N;
izq=2;
der=N;
for(i=1;i<=N;i++)
{ cout<<"A["<<i<<"]="; cin>>A[i];
}
while(izq<der)
{ for(i=der;i>=izq;i--)
{ if (A[i-1]>A[i])
{ aux=A[i-1];
A[i-1]=A[i];
A[i]=aux;
k=i;
}
}
izq=k+1;
for(i =izq ;i<=der;i++)
{ if(A[i-1]>A[i])
{ aux=A[i-1];
A[i-1]=A[i];
A[i]=aux;
k=i;
}
}
der=k-1;
}
for(i=1;i<=N;i++)
cout<<A[i]<<" ";
return 0;
}
7.5 Conclusiones
La utilización del Método Shaker o “sacudida” es el ordenamiento de un vector que se
requiere ordenar independiente de su tamaño, este ordenamiento se basa en la
implementación de comparaciones más completas entre todos los dígitos del vector, esto
hace más sencillo su uso y manera de entenderlo. Teniendo en cuenta la forma del algoritmo
que se desee utilizar, podemos ver e identificar, que utilizando este método por consola es
mucho más cortas las líneas de código que imprimiendo cada uno de los mensajes
requeridos.
8.1 Definición
El heap o montículo es un árbol binario donde todos los padres son mayores que sus hijos.
Este árbol binario tiene que ser completo, es decir, que debe tener todos los niveles llenos,
excepto el último y en este último nivel todos los hijos están en un mismo lado (por ejemplo
en la derecha).
8.4 Montículo
Un montículo (heap en inglés) es una estructura de datos del tipo árbol con información
perteneciente a un conjunto ordenado. Los montículos máximos tienen la característica de
que cada nodo padre tiene un valor mayor que el de todos sus nodos hijos, mientras que en
los montículos mínimos, el valor del nodo padre es siempre menor al de sus nodos hijos.Un
árbol cumple la condición de montículo si satisface dicha condición y además es un árbol
binario completo. Un árbol binario es completo cuando todos los niveles están llenos, con la
excepción del último, que se llena desde la izquierda hacia la derecha.
En un montículo de prioridad, el mayor elemento (o el menor, dependiendo de la relación de
orden escogida) está siempre en el nodo raíz. Por esta razón, los montículos son útiles para
implementar colas de prioridad. Una ventaja que poseen los montículos es que, por ser
árboles completos, se pueden implementar usando arreglos, lo cual simplifica su codificación
y libera al programador del uso de punteros.
Eliminar
En este caso eliminaremos el elemento máximo de un montículo. La forma más eficiente de
realizarlo sería buscar el elemento a borrar, colocarlo en la raíz e intercambiarlo por el
máximo valor de sus hijos satisfaciendo así la propiedad de montículos de máximos. En el
ejemplo anterior representado vemos que 20 es el elemento máximo y es el sujeto a
eliminar.
1. Eliminar el elemento máximo (colocado en la raíz).
2. Hemos de subir el elemento que se debe eliminar, para cumplir la condición de
montículo a la raíz, que ha quedado vacía.
3. Una vez hecho esto queda el último paso el cual es ver si la raíz tiene hijos mayores que
ella si es así, aplicamos la condición y sustituimos el padre por el mayor de sus
progenitores.
1
20 8
1
18 9
0
9
8
10
8
{ int i,j,k,n,item,temp;
int A[10];
Cout<<” ingrese la dimension ”<<endl;
Cin>>n;
for (i=1;i<=n;i++)
{ cin>>A[i];
}
for (k=n;k>0;k--)
{ for (i=1;i<=k;i++)
{ item=A[i];
j=j/2;
while (j>0 && A[i]<item)
{ A[i]=A[j];
i=j;
j=j/2;
}
A[i]=item;
}
temp=A[1];
A[1]=A[k];
A[k]=temp;
}
cout<<endl;
cout<<”el orden es ”<<endl;
for (i=1;i<=n;i++)
{ cout<<”*”<<i<<”+ valor es_:”<<””<<A*i+<<endl;
}
getch();
}
9.2 El Funcionamiento
Se basa en el concepto de que en la iteración i-ésima los i primeros elementos se encuentran
ordenados entre ellos.
De ello se deduce que no es necesario ejecutar el bucle con un valor i = 1, ya que un
elemento siempre está ordenado con respecto a si mismo; es por ello que el bucle en este
algoritmo debe de empezar por el valor 2.
En una iteración i concreta, la forma de llevar a cabo la ordenación consiste en colocar el
elemento i-ésimo en su posición correcta con respecto a los i-1 anteriores, que están
ordenados entre ellos.
Para proceder de esta manera se comparará el elemento i-ésimo con todos los anteriores,
hasta que se encuentre uno que sea menor o igual que él, o se llegue al principio del vector
(en este caso el elemento i-ésimo es el más pequeño).
3er. recorrido: Se toma 1 para comparar con los elementos anteriores. Los elementos
anteriores son: 3, 7, 10
1
3 7 10 9
La comparación 1<10, es verdadera, entonces desplazamos el 10 una posición a la derecha.
1
3 7 10 9
La comparación 1<7, es verdadera, entonces desplazamos el 7 una posición a la derecha.
1
3 7 10 9
La comparación 1<3, es verdadera, entonces desplazamos el 3 una posición a la derecha.
1
3 7 10 9
Al no haber más elementos a comparar colocamos el 1 en la posición del último elemento
desplazado.
1 3 7 10 9
4to. recorrido: Se toma 9 para comparar con los elementos anteriores. Los elementos
anteriores son: 1, 3, 7, 10
9
1 3 7 10
La comparación 9<10 es verdadera, entonces desplazamos el 10 una posición a la derecha.
9
1 3 7 10
La comparación 9<7 es falsa, entonces no desplazamos nada y se termina este recorrido,
colocando el 9 en la posición del último elemento desplazado.
1 3 7 9 10
Con este último recorrido la lista ya está ordenada. Tal como se puede observar, cada
recorrido termina cuando se encuentra una posición en donde colocar el elemento tomado
o cuando ya no haya elementos con que comparar. Bien ahora el siguiente procedimiento
sería la primera implementación del algoritmo:
#include <iostream>
using namespace std;
{ aux=A[i];
k=i-1;
while((k>=1)&&(aux<A[k]))
{ A[k+1]=A[k];
k=k-1;
}
A[k+1]=aux;
}
for(k=1;k<=n;k++)
{ cout<<"el orden es: ";
cout<<A[k]<<endl;
}
return 0;
}
9.7 Clasificaciones
El algoritmo de inserción directa se mejora fácilmente al notar que la secuencia
destino Aj...Ai-1, donde debe insertarse el nuevo elemento, ya está ordenada. Por eso
puede ser empleado un método más rápido para determinar el punto de inserción. La
elección obvia es una búsqueda binaria que prueba la secuencia destino en la mitad y
continúa buscando hasta encontrar el punto de inserción. El algoritmo de clasificación
modificado recibe el nombre de inserción binaria.
9.8 Características
La secuencia destino donde debe insertarse el nuevo elemento ya está ordenada.
Búsqueda Binaria para localizar el lugar de inserción.
Desplazar elementos.
Insertar.
9.9 Análisis
Al realizar la búsqueda binaria se divide una longitud L por la mitad un número determinado
de veces.
A. Hallamos el elemento central del área comprendida por la parte ordenada más la posición
del elemento a insertar.
B. Comparamos el elemento central con el elemento que queremos insertar. Si dicho
elemento central es menor o igual, nos quedamos con la parte derecha (Sin incluir el
elemento central). En caso contrario, nos quedamos con la parte izquierda incluyendo al
elemento central.
C. Repetimos el mismo proceso sobre el área con la que nos quedamos, hasta que dicha área
sea nula.
D. Cuando el área sea nula, tendremos la posición de inserción.
El proceso comienza comparando el elemento central del arreglo con el valor buscado. Si
ambos coinciden finaliza la búsqueda. Si no ocurre así, el elemento buscado será mayor o
menor en sentido estricto que el central del arreglo. Si el elemento buscado es mayor se
procede a hacer búsqueda binaria en el sub array superior, si el elemento buscado es menor
que el contenido de la casilla central, se debe cambiar el segmento a considerar al segmento
que está a la izquierda de tal sitio central.
15 67 08 16 44 27 12 35
Primera pasada:
15<67 no hay intercambio
15 67 08 16 44 27 12 35
Segunda pasada:
15<08 Si hay intercambio
15 67 08 16 44 27 12 35
Tercera pasada:
15<16 No hay intercambio
08 15 67 16 44 27 12 35
67<16 Si hay intercambio
08 15 16 67 44 27 12 35
Cuarta pasada:
15<44 No hay intercambio
16<44 No hay intercambio
67<44 Si hay intercambio
08 15 16 44 67 27 12 35
Quinta pasada:
16<27 No hay intercambio
44<27 No hay intercambio
08 15 16 27 44 67 12 35
Sexta pasada:
16<12 Si hay intercambio
08 15 12 16 27 44 67 35
08 12 15 16 27 44 67 35
Séptima pasada:
16<35 No hay intercambio
44<35 Si hay intercambio
08 12 15 16 27 35 44 67
9.12 Complejidad
Los métodos de ordenación por inserción lineal e inserción binaria, solo se diferencias entre
sí, conceptualmente, en el método de la búsqueda. Por lo tanto, el número de movimientos
de claves será el mismo en ambos casos es
n(n-1)
9.13 Conclusiones
Concluimos que la búsqueda binaria es un algoritmo muy eficiente para minimizar el tiempo
de búsqueda ,la cual consiste en dividir el intervalo de búsqueda en dos partes comparando
el elemento buscado con el elemento central, estos mismos pasos se repetirá hasta
encontrar el elemento buscado. Este método es más efectivo que la inserción directa porque
hay menos comparaciones al hacer la búsqueda. A diferencia no tiene que comparar con
todos los elementos anteriores hasta encontrar el bueno. Pero es también es un algoritmo
lento para números muy grande o sea “N” números.
9.14 Recomendaciones
Lo recomendable es que antes de usar este algoritmo este los numero en un orden
adecuado o arreglo ordenado parar poder pero puede ser de utilidad para listas que están
ordenadas o semi ordenadas, porque en ese caso realiza muy pocos desplazamientos.
10.1 Historia
Se dice que este método nació de la idea de Herman Hollerith en 1890 al crear la maquina
tabuladora, en la cual se empleaban tarjetas perforadas para realizar el censo de ese año en
Estados Unidos.
Al final, después de unas horas, la maquina entregaba todo un grupo de hojas listas para ser
procesadas en un computador.
En el censo de 1880 se tomaron 10 años para procesar toda la información, pero con las tarjetas
perforadas, en la máquina que incluía un “card sorter” se tomaron cerca de 6 semanas.
La idea original de Hollerith era ordenar empezando por el digito más significativo. Es de esta
forma que surgió una maquina ordenadora de tarjetas. La cual, utilizando el método de Radix-
Sort, concatenaba cada hoja dependiendo de la ubicación de las ultimas 3 columnas, que
contenían las cifras para el acomodo de tarjetas, estando numerado del 0 al 9.
10.4 Características
• El Radix trabaja en memoria principal y pertenece al grupo de intercambio.
• Efectúa sus operaciones sobre dígitos individuales de los números que representan a
las claves cuando estas pertenecen a un sistema numérico en cualquier base.
• Este método se puede considerar como una generalización de la clasificación por
urnas.
• La idea clave de la ordenación radix-sort es clasificar por urnas primero respecto al
digito de menor peso hasta alcanzar el digito más significativo.
• Si la cantidad de dígitos es grande, en ocasiones es más eficiente ordenar el archivo
aplicando primero el ordenamiento de raíz a los dígitos más significativos y después
utilizando inserción directa sobre el archivo ordenado.
• La característica de este algoritmo está en que no hace comparaciones para ordenar
las listas, simplemente se encarga de ir contando o agrupando los números que
tengan el mismo valor relativo en determinada cifra.
En este paso ya se diferencia notablemente dos grupos, el formado por las claves que
comienzan con 0, y el formado por las claves que comienzan con 1. Ahora se aplica de nuevo
el primer paso a cada grupo formado pero con el bit siguiente.
10.7 Clasificación
Existen dos clasificaciones de Radix Sort:
• Una secuencia como "b, c, d, e, f, g, h, i, j, ba" será ordenada léxicamente como "b, ba, c,
d, e, f, g, h, i, j".
Si se usa orden léxico para ordenar representaciones de enteros de longitud variable,
entonces la ordenación de las representaciones de los números del 1 al 10 será "1, 10, 2, 3,
4, 5, 6, 7, 8, 9", como si las claves más cortas estuvieran justificadas a la izquierda y
rellenadas a la derecha con espacios en blanco, para hacerlas tan largas como la clave más
larga, para el propósito de este ordenamiento.
Ejemplo:
Supongamos la siguiente lista de números enteros.
De ésta forma terminamos con una lista ordenada de forma ascendente. Hay que resaltar
que aunque el número 93 ya se encontraba ordenado desde antes de la concatenación de
igual forma se tuvo que mover de urna (Urna tres) para lograr la lista final.
#include <math.h>
#include <conio.h>
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#define NUMELTS 20
Desventajas
Se requiere conocer la cantidad de dígitos del valor máximo (para saber cuándo el
método ya acomodo todos los elementos).
Radix no es muy eficiente cuando las claves son extremadamente largas.
Se da gran pérdida de tiempo cuando son muy pocas claves, lo que se podría
implementar más eficientemente con otro ordenamiento.
Cuando las claves no están muy distribuidas entre ellas, si no son muy
secuenciales la clasificación Radix no es recomendable, debido a que podría estar
sujeto a pérdida de memoria y tiempo.
Se requiere de espacio para almacenar los punteros del frente y de la parte
posterior de la cola, además de un campo adicional en cada registro que se utiliza
como puntero a la lista encadenada.
10.12 Conclusión
Radix Sort es potencialmente un algoritmo muy eficiente gracias a una complejidad lineal en
el número de datos a ordenar. Desde un punto de vista del algoritmo secuencial Radix sort
muestra una pobre exploración de la jerarquía de memoria cuando los conjuntos quedan
en el segundo o en el tercer nivel. Desde un punto de vista del algoritmo paralelo la solución
básica puede tener un gran desequilibrio de carga en cada interacción del algoritmo
(ordenación de cada digito).
Radix sort es uno de los algoritmos de clasificación para lineales enteros. Funciona mediante
la clasificación de los números de entrada de cada dígito, para cada uno de los dígitos de los
números. Sin embargo, el proceso adoptado por este método de ordenación es poco
intuitivo, en el sentido de que los números se ordenan en el dígito menos significativo
primero, seguido por el segundo al menos dígitos significativos y así sucesivamente hasta
que el dígito más significativo.
BIBLIOGRAFÍA
Libros
Algotrabajo\Apuntes de Algoritmos y Programación Shell Sort.htm
Carrasco Muñoz Joel, (2006) “creación de programas con Borland C++”, primera edición,
Lima.
Micha Hofri, Analysis of Algorithms: Computational Methods and Mathematical
Robert Sedgewick (1998), Algorithms in C++, third edition, editorial Addison-Wesley
Savitch, Walter (2007), ”Resolución de problemas con C++”, quinta edición, Prentice Hall,
México.
Sara Baase (1999), Computer Algorithms: Introduction to Design and Analysis,
Editorial Pearson, 3rd edition
Páginas en internet
https://upcanalisisalgoritmos.wikispaces.com/file/view/ALGORITMOS+DE+ORDENAMIEN
TO+COUNTINGSORT.pdf
http://lwh.free.fr/pages/algo/tri/tri_es.htm
http://lwh.free.fr/pages/algo/tri/tri_insertion_es.html
http://lwh.free.fr/pages/algo/tri/tri_bulle_es.html
http://lwh.free.fr/pages/algo/tri/tri_shaker_es.html
http://lwh.free.fr/pages/algo/tri/tri_gnome_es.html
http://lwh.free.fr/pages/algo/tri/tri_selection_es.html
http://lwh.free.fr/pages/algo/tri/tri_peigne_es.html
http://lwh.free.fr/pages/algo/tri/tri_shell_es.html
http://lwh.free.fr/pages/algo/tri/tri_rapide_es.html
http://books.google.com.co/books?id=NLngYyWFl_YC&pg=PA168&lpg=PA168&dq=coun
ting+sort+cormen&source=bl&ots=BwVsEE-
http://www.angelfire.com/wy2/est_info/quicksort.html
http://algoritmia.net/articles.php?id=31
https://es.scribd.com/document/19540984/RADIX