SlideShare une entreprise Scribd logo
1  sur  30
Ordenamiento de burbuja
De Wikipedia, la enciclopedia libre
Saltar a navegación, búsqueda
El Ordenamiento de burbuja (Bubble Sort en inglés) es un sencillo algoritmo de
ordenamiento. Funciona revisando cada elemento de la lista que va a ser ordenada con
el siguiente, intercambiándolos de posición si están en el orden equivocado. 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.
Contenido
[ocultar]
1 Descripción
2 Análisis
o 2.1 Rendimiento en casos óptimos
o 2.2 Conejos y Tortugas (Yo-yos) (?)
3 En la práctica
4 Implementación
5 Véase también
6 Enlaces externos
[editar] Descripción
Una manera simple de expresar el ordenamiento de burbuja en pseudocódigo es la
siguient
e:
En este
algorit
mo se
trata de
ordenar
una
lista de
valores:
a, de n
término
s
numera
dos del termino 0 al n-1, consta de dos bucles anidados uno con el índice i, que acota el
recorrido de la burbuja en sentido inverso de 2 a n, y un segundo bucle con el índice j,
con un recorrido desde 0 hasta n-i, para cada iteración del primer bucle, que indica el
lugar de la burbuja.
La burbuja son dos términos de la lista seguidos, j y j+1, que se comparan, si el primero
es menor que el segundo sus valores se intercambian.
Esta comparación se repite en el centro de los dos bucles, dando lugar a la postre a una
lista ordenada, puede verse que el número de repeticiones sola depende de n, y no del
orden de los términos, esto es si pasamos al algoritmo una lista ya ordenada, realizara
todas las comparaciones exactamente igual que para una lista no ordenada, esta es una
característica de este algoritmo, luego veremos una variante que evita este problema.
Para comprender el funcionamiento, veamos un ejemplo sencillo:
Partimos de una lista de números que hay que ordenar:
Podemos ver que la lista tiene cinco términos, luego:
El índice i hará un recorrido de 2 hasta n:
Que en este caso será de 2 a 5. Para cada uno de los valores de i, j
tomara sucesivamente los valores de 0 hasta n-i:
Para cada valor de j, obtenido en ese orden, se compara el valor del índice j con el
siguiente:
Si el termino j es menor, en su caso podría se mayor, que el termino j+1, los valores se
permutan, en caso contrario se
continúa con la iteración.
Para el caso del ejemplo,
tenemos que:
Para la primera iteración del
primer bucle:
y j tomara los valores de 0 hasta 3:
Cuando j vale 0, se comparan , el 55 y el 86, dado que 55 < 86 no se permutan el
orden.
Ahora j vale 1 y se comparan el 86 y el 48 Como 86 > 48, se permutan, dando
lugar a una nueva lista.
Se repite el proceso hasta que j valga 3, dando lugar a una lista parcialmente ordenada,
podemos ver que el termino de mayor
valor esta en el lugar más alto.
Ahora i vale 3, y j hará un recorrido de 0
a 2.
Primero j vale 0, se comparan , el
55 y el 48, como 55 > 48 se permutan
dando lugar a la nueva lista.
Para j = 1 se compara el 55 con el 16 y se
cambian de orden.
Para j = 2 se compara el 55 y el 82 y se dejan como están, finalizando el bucle con una
lista mejor ordenada, puede verse que los dos valores más altos ya ocupan su lugar. No
se ha realizado ninguna comparación con el termino cuarto, dado que ya se sabe que
después del primer ciclo es el mayor de la lista.
El algoritmo consiste en comparaciones sucesivas de dos términos consecutivos,
ascendiendo de abajo a arriba en cada iteración, como la ascensión de las burbujas de
aire en el agua, de ahí el nombre del procedimiento, en la primera iteración el recorrido
ha sido completo, en el segundo se ha dejado él ultimo termino, al tener ya el mayor de
los valores, en los sucesivos sé ira dejando re realizar las ultimas comparaciones, como
se puede ver.
Ahora ya i vale 4 y j recorrerá los valores de 0 a 1.
Cuando j vale 0, se comparan esto es el 48 y
el 16 dado que 48 es mayor que 16 se permutan los
valores, dando lugar a una lista algo más ordenada
que la anterior, desde esta nueva ordenación, j
pasa a valer 1, con lo que se comparan los
términos el 48 y el 55 que quedan en el
mismo orden.
En este caso la burbuja ha ascendido menos que en los casos anteriores, y la lista esta ya
ordenada, pero el algoritmo tendrá que completarse, realizando una ultima iteración.
Hay que tener en cuenta que el bucle para realiza un número fijo de repeticiones y para
finalizar tendrán que completarse, aun en el caso extremo, de que la lista estaría
previamente ordenada.
Por ultimo i vale 5 y j solo puede vale 0, con lo que solo se realizara una comparación
de el 16 y el 48, que ya están ordenados y se dejan
igual.
Los bucles finalizan y también el procedimiento, dejando la
lista ordenada.
Una variante que finaliza en caso de que la lista este
ordenada, puede ser la siguiente, empleando un centinela
ordenado, que detecta que no se ha modificado la lista en
un recorrido de la burbuja, y que por tanto la lista ya esta
ordenada, finalizando.
[editar] Análisis
Ejemplo del ordenamiento de burbuja ordenando una lista de números aleatorios.
[editar] Rendimiento en casos óptimos
El ordenamiento de burbuja tiene una complejidadΩ(n²). Cuando una lista ya está
ordenada, a diferencia del ordenamiento por inserción que pasará por la lista una vez, y
encontrará que no hay necesidad de intercambiar las posiciones de los elementos, el
método de ordenación por burbuja está forzado a pasar por dichas comparaciones, lo
que hace que su complejidad sea cuadrática en el mejor de los casos, esto lo cataloga
como el algoritmo mas ineficiente que existe aunque para muchos programadores sea
el más sencillo de implementar.
[editar] Conejos y Tortugas (Yo-yos) (?)
La posición de los elementos en el ordenamiento de burbuja juegan un papel muy
importante en la determinación del rendimiento. Los elementos mayores al principio de
la lista son rápidamente movidos hacia abajo. En cambio, elementos menores en el
fondo de la lista, se mueven a la parte superior muy lentamente. Esto llevó a nombrar
estos elementos conejos y tortugas, respectivamente.
Varios esfuerzos se han realizado para eliminar las tortugas véase Exterminación y
mejorar la velocidad del ordenamiento de burbuja, la cual será más redonda que nunca.
El Ordenamiento por sacudida es un buen ejemplo, aunque aún mantiene, en el peor de
los casos, una complejidad O (n2
). El ordenamiento por combinación compara los
elementos primero en pedazos grandes de la lista, moviendo tortugas extremadamente
rápido, antes de proceder a pedazos cada vez más pequeños para alisar la lista. Su
velocidad promedio es comparable a algoritmos rápidos (y complejos) como el
ordenamiento rápido.
[editar] En la práctica
A pesar de que el ordenamiento de burbuja es uno de los algoritmos más sencillos de
implementar, su orden O (n2
) lo hace muy ineficiente para usar en listas que tengan más
que un número reducido de elementos. Incluso entre los algoritmos de ordenamiento de
orden O (n2
), otros procedimientos como el Ordenamiento por inserción son
considerados más eficientes.
Dada su simplicidad, el ordenamiento de burbuja es utilizado para introducir el
concepto de algoritmo, o de algoritmo de ordenamiento para estudiantes de ciencias de
la computación. Aunque algunos investigadores como Owen Astrachan han criticado al
ordenamiento de burbuja y su popularidad en la educación de la computación,
recomendando que ya no debe ser enseñado.
El ordenamiento de burbuja es asintóticamente equivalente, en tiempos de ejecución con
el Ordenamiento por inserción en el peor de los casos, pero ambos algoritmos difieren
principalmente en la cantidad de intercambios que son necesarios. Resultados
experimentales, como los descubiertos por Astrachan han demostrado que el
ordenamiento por inserción funcionan considerablemente mejor incluso con listas
aleatorias. Por esta razón, muchos libros de algoritmos modernos evitan usar el
ordenamiento de burbuja, utilizando en cambio el ordenamiento por inserción.
El ordenamiento de burbuja interactúa vagamente con el hardware de las CPU
modernas. Requiere al menos el doble de escrituras que el ordenamiento por inserción,
el doble de pérdidas de cache, y asintóticamente más predicción de saltos. Varios
experimentos, hechos por Astrachan, de ordenamiento de cadenas en Java, muestran que
el ordenamiento de burbuja es 5 veces más lento que el ordenamiento por inserción y
40% más lento que el ordenamiento por selección.
[editar] Implementación
A continuación se muestra el Ordenamiento de burbuja en distintos lenguajes de
programación:
LUA
function burbuja_ordenar(t)
for i=1, #t do
for j=i+1, #t do
if (t[i] > t[j]) then
temp = t[i]
t[i] = t[j]
t[j] = temp
end
end
end
end
QBASIC
CLS
RANDOMIZE TIMER
n = 10
DIM a(n)
REM Generar e imprimir de a(0) a a(n) números aleatorios
FOR i = 0 TO n
a(i) = INT(RND * 1000)
PRINT USING "a(##)=#####"; i; a(i)
NEXT
PRINT
REM algoritmo de la burbuja
FOR j = n TO 1 STEP -1
FOR i = 1 TO j
IF a(i - 1) > a(i) THEN
aux = a(i)
a(i) = a(i - 1)
a(i - 1) = aux
END IF
NEXT
NEXT
REM imprimir datos ordenados
FOR i = 0 TO n
PRINT USING "a(##)=#####"; i; a(i)
NEXT
C
//Ordenamiento por metodo de Burbujeo
// Por Leandro D Ferro
void ordenamientoBurbuja(int v[], int util_v) {
int temp, i, j;
for (i = 0; i < util_v ; i++) {
for (j = i + 1; j < util_v - 1; j++) {
if (v[i] > v[j]) {
temp = v[i];
v[i] = v[j];
v[j] = temp;
}
}
}
}
C++
template<typename _Ty>
void bubble_sort(vector<_Ty> & v){
for (size_t i = 0; i < v.size() - 1; ++i){
for (size_t j = i + 1; j < v.size(); ++j){
if (v[i] > v[j])
swap(v[i], v[j]);
}
}
}
C#
Public int[] OrdenarBurbuja(int[]x)
{
int t= x.Length, temp;
for(int i=1 ; i< t ; i++)
for(int j = t-1 ; j >= i; j--)
{
if(x[j] < x[j-1])
{
temp= x[j];
x[j]= x[j-1];
x[j-1]= temp;
}
}
}
Java
//Ordenamiento por Burbuja
// by ramses2999
public static int[] OrdenarBurbuja(int[] n){
int temp;
int t = n.length;
for (int i = 1; i < t; i++) {
for (int k = t- 1; k >= i; k--) {
if(n[k] < n[k-1]){
temp = n[k];
n[k] = n[k-1];
n[k-1]= temp;
}//fin if
}// fin 2 for
}//fin 1 for
return n;
}//fin
Visual Basic
Private Sub OrdenarBurbuja(ByRef VectorOriginal() As Integer)
Dim Temp, Longitud As Integer
Longitud = VectorOriginal.Length - 2
For b = 0 To Longitud
For a = 0 To Longitud
If VectorOriginal(a) > VectorOriginal(a + 1) Then
Temp = VectorOriginal(a + 1)
VectorOriginal(a + 1) = VectorOriginal(a)
VectorOriginal(a) = Temp
End If
Next
Next
End Sub
PHP
<?php
//Ordenamiento por burbuja
$numeros = array(9, 4, -1, 7, 8, 11, 6, 12, 10, 5);
$n = count($numeros);
for ($i = 1; $i<$n; $i++) {
for ($j = $n-1; $j >= $i; $j--) {
echo "i: $i, j: $jn";
echo "Comparando " . $numeros[$j-1] . " y " . $numeros[$j] .
"n";
if ($numeros[$j-1] > $numeros[$j]) {
$aux = $numeros[$j];
$numeros[$j] = $numeros[$j-1];
$numeros[$j-1] = $aux;
}
}
}
print_r($numeros);
Ordenamiento por inserción
De Wikipedia, la enciclopedia libre
Saltar a navegación, búsqueda
Ejemplo de ordenamiento por inserción ordenando una lista de números aleatorios.
El ordenamiento por inserción (insertion sort en inglés) es una manera muy natural
de ordenar para un ser humano, y puede usarse fácilmente para ordenar un mazo de
cartas numeradas en forma arbitraria. Requiere O(n²) operaciones para ordenar una lista
de n elementos.
Inicialmente se tiene un solo elemento, que obviamente es un conjunto ordenado.
Después, cuando hay k elementos ordenados de menor a mayor, se toma el elemento
k+1 y se compara con todos los elementos ya ordenados, deteniéndose cuando se
encuentra un elemento menor (todos los elementos mayores han sido desplazados una
posición a la derecha). En este punto se inserta el elemento k+1 debiendo desplazarse
los demás elementos.
Contenido
[ocultar]
1 Ejemplo de funcionamiento
2 Implementación
o 2.1 C
o 2.2 C++
o 2.3 Java
o 2.4 JavaScript
o 2.5 Perl
o 2.6 PHP
o 2.7 Pascal
o 2.8 Python
o 2.9 Visual Basic .NET
3 Véase también
4 Enlaces externos
[editar] Ejemplo de funcionamiento
En el siguiente ejemplo, 32 debe ser insertado entre 26 y 47, y por lo tanto 47, 59 y 96
deben ser desplazados.
k+1
11 26 47 59 96 32
11 26 47 59 96
11 26 32 47 59 96
En la implementación computacional, el elemento k+1 va comparándose de atrás para
adelante, deteniéndose con el primer elemento menor. Simultáneamente se van haciendo
los desplazamientos.
11 26 47 59 96 32
11 26 47 59 96
11 26 47 59 96
11 26 47 59 96
11 26 32 47 59 96
El algoritmo en pseudocódigo (con listas que empiezan por 0) debería ser como el
siguiente:
algoritmo insertSort( A : lista de elementos ordenables )
para i=1 hasta longitud(A) hacer
index=A[i]
j=i-1
mientras j>=0 y A[j]>index hacer
A[j+1] = A[j]
j = j - 1
fin mientras
A[j+1] = index
fin para
fin algoritmo
Aunque este algoritmo tiene un mejor orden de complejidad que el de burbuja, es muy
ineficiente al compararlo con otros algoritmos como quicksort. Sin embargo, para listas
relativamente pequeñas el orden por inserción es una buena elección, no sólo porque
puede ser más rápido para cantidades pequeñas de elementos sino particularmente
debido a su facilidad de programación.
[editar] Implementación
A continuación se muestra el Ordenamiento por inserción en distintos lenguajes de
programación:
[editar] C
void insertionSort(int numbers[], int array_size) {
int i, a, index;
for (i=1; i < array_size; i++) {
index = numbers[i];
a = i-1;
while (a >= 0 && numbers[a] > index) {
numbers[a + 1] = numbers[a];
a--;
}
numbers[a+1] = index;
}
}
[editar] C++
template <class T> void insertionSort(std::vector<T>& v, int fin) {
int i, j, index;
for (i=1; i <fin; i++)
{
index = v.at(i);
j = i-1;
while (j >= 0 && v.at(j)>index) {
v.at(j+1)=v.at(j);
j--;
}
v.erase(v.begin()+j+1);
v.insert(v.begin()+j+1,index);
}
}
[editar] Java
public static void insertSort (int[] v) {
for (int i=1; i<v.length; i++) {
int aux = v[i];
int j;
for (j=i-1; j>=0 && v[j]>aux; j--)
v[j+1] = v[j];
v[j+1] = aux;
}
}
[editar] JavaScript
for (var i=1; i < vector.length; i++) {
var temp = vector[i];
var j = i-1;
while (j >= 0 && vector[j] > temp) {
vector[j + 1] = vector[j];
j--;
}
vector[j+1] = temp;
}
[editar] Perl
sub insercion {
my $array = shift; # Recibimos una referencia a un array
my $i; # Índice del elemento a comparar
my $j; # Índice del valor mínimo a encontrar
for ( $i = 1; $i < @$array; $i++ ) {
my $x = $array->[$i]; # Elemento $i-ésimo
# Comparamos este elemento con todos los anteriores,
# hasta que lleguemos al principio de la lista o encontremos
# un elemento que sea menor o igual que él.
for ( $j = $i; $j > 0 and $array->[$j-1] > $x; $j-- ) {
;
}
# Hacemos la inserción del elemento a comparar (posición $i)
en la
# nueva posición encontrada (posición $j), pero sólo si son
distintas
# posiciones.
# El uso de splice (extraer/insertar) permite que la solución
sea mucho
# más rápida que el movimiento de los elementos uno a uno.
splice(@$array, $j, 0, splice(@$array, $i, 1))
if $i != $j;
}
}
[editar] PHP
function insert_sort($arr){
$count = count($arr);
for($i=1; $i<$count; $i++){
$tmp = $arr[$i];
for ($j=$i-1; $j>=0 && $arr[$j] > $tmp; $j--)
$arr[$j+1] = $arr[$j];
$arr[$j] = $tmp;
}
return $arr;
}
[editar] Pascal
Procedure InsertionSort(var insertion:Array_integer; array_size:
Integer);
Var
i, j, index : Integer;
Begin
For i := 1 to array_size do
Begin
index := insertion[i];
j := i-1;
While ((j >= 0) AND (insertion[j] > index)) do
Begin
insertion[j+1] := insertion[j];
j := j - 1;
End;
insertion[j+1] := index;
End;
End;
[editar] Python
def insertionSort(numeros): #numeros es una lista
tama = len(numeros) #creamos una variable igual al tamaño de la
lista
i=0
for i in range(tama):
indice = numeros[i]
a = i-1
while (a >= 0 and numeros[a] > indice):
numeros[a+1] = numeros[a]
a = a-1
numeros[a+1] = indice
print numeros #imprime la lista ordenada
[editar] Visual Basic .NET
Private Sub insertionSort(ByVal numbers() As Integer) ' Es una
función,
'debemos pasarle el array de números desde el Sub Main()
Dim i, j, index As Integer
i = 1
Do
index = numbers(i)
j = i - 1
While ((j >= 0) And (numbers(j) > index))
numbers(j + 1) = numbers(j)
j = j - 1
End While
numbers(j + 1) = index
i = i + 1
Loop Until i > (UBound(v))
End Sub
Ordenamiento Shell
De Wikipedia, la enciclopedia libre
Saltar a navegación, búsqueda
El ordenamiento Shell (Shell sort en inglés) es un algoritmo de ordenamiento. El
método se denomina Shell en honor de su inventor Donald Shell. Su implementación
original, requiere O(n2
) comparaciones e intercambios en el peor caso. Un cambio
menor presentado en el libro de V. Pratt produce una implementación con un
rendimiento de O(nlog2
n) en el peor caso. Esto es mejor que las O(n2
) comparaciones
requeridas por algoritmos simples pero peor que el óptimo O(n log n). Aunque es fácil
desarrollar un sentido intuitivo de cómo funciona este algoritmo, es muy difícil analizar
su tiempo de ejecución.
El Shell sort es una generalización del ordenamiento por inserción, teniendo en cuenta
dos observaciones:
1. El ordenamiento por inserción es eficiente si la entrada está "casi ordenada".
2. El ordenamiento por inserción es ineficiente, en general, porque mueve los
valores sólo una posición cada vez.
El algoritmo Shell sort mejora el ordenamiento por inserción comparando elementos
separados por un espacio de varias posiciones. Esto permite que un elemento haga
"pasos más grandes" 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. El último paso del Shell sort es
un simple ordenamiento por inserción, pero para entonces, ya está garantizado que los
datos del vector están casi ordenados.
Contenido
[ocultar]
1 Ejemplo
2 Secuencia de espacios
3 Implementaciones
o 3.1 ActionScript
o 3.2 C
o 3.3 C#
o 3.4 Java
o 3.5 Perl
o 3.6 Python
o 3.7 Visual Basic
4 Referencias
5 Enlaces externos
[editar] Ejemplo
Considere un pequeño valor que está inicialmente almacenado en el final del vector.
Usando un ordenamiento O(n2
) como el ordenamiento de burbuja o el ordenamiento por
inserción, tomará aproximadamente n comparaciones e intercambios para mover este
valor hacia el otro extremo del vector. El Shell sort primero mueve los valores usando
tamaños de espacio gigantes, de manera que un valor pequeño se moverá bastantes
posiciones hacia su posición final, con sólo unas pocas comparaciones e intercambios.
Uno puede visualizar el algoritmo Shell sort de la siguiente manera: coloque la lista en
una tabla y ordene las columnas (usando un ordenamiento por inserción). Repita este
proceso, cada vez con un número menor de columnas más largas. Al final, la tabla tiene
sólo una columna. Mientras que transformar la lista en una tabla hace más fácil
visualizarlo, el algoritmo propiamente hace su ordenamiento en contexto
(incrementando el índice por el tamaño de paso, esto es usando i += tamaño_de_paso
en vez de i++).
Por ejemplo, considere una lista de números como [ 13 14 94 33 82 25 59 94 65
23 45 27 73 25 39 10 ]. Si comenzamos con un tamaño de paso de 5, podríamos
visualizar esto dividiendo la lista de números en una tabla con 5 columnas. Esto
quedaría así:
13 14 94 33 82
25 59 94 65 23
45 27 73 25 39
10
Entonces ordenamos cada columna, lo que nos da
10 14 73 25 23
13 27 94 33 39
25 59 94 65 82
45
Cuando lo leemos de nuevo como una única lista de números, obtenemos [ 10 14 73
25 23 13 27 94 33 39 25 59 94 65 82 45 ]. Aquí, el 10 que estaba en el extremo
final, se ha movido hasta el extremo inicial. Esta lista es entonces de nuevo ordenada
usando un ordenamiento con un espacio de 3 posiciones, y después un ordenamiento
con un espacio de 1 posición (ordenamiento por inserción simple).
El Shell sort lleva este nombre en honor a su inventor, Donald Shell, que lo publicó en
1959. Algunos libros de texto y referencias antiguas le llaman ordenación "Shell-
Metzner" por Marlene Metzner Norton, pero según Metzner, "No tengo nada que ver
con el algoritmo de ordenamiento, y mi nombre nunca debe adjuntarse a éste." [1]
[editar] Secuencia de espacios
La secuencia de espacios es una parte integral del algoritmo Shell sort. Cualquier
secuencia incremental funcionaría siempre que el último elemento sea 1. El algoritmo
comienza realizando un ordenamiento por inserción con espacio, siendo el espacio el
primer número en la secuencia de espacios. Continua para realizar un ordenamiento por
inserción con espacio para cada número en la secuencia, hasta que termina con un
espacio de 1. Cuando el espacio es 1, el ordenamiento por inserción con espacio es
simplemente un ordenamiento por inserción ordinario, garantizando que la lista final
estará ordenada.
La secuencia de espacios que fue originalmente sugerida por Donald Shell debía
comenzar con N / 2 y dividir por la mitad el número hasta alcanzar 1. Aunque esta
secuencia proporciona mejoras de rendimiento significativas sobre los algoritmos
cuadráticos como el ordenamiento por inserción, se puede cambiar ligeramente para
disminuir más el tiempo necesario medio y el del peor caso. El libro de texto de Weiss
demuestra que esta secuencia permite un ordenamiento O(n2
) del peor caso, si los datos
están inicialmente en el vector como (pequeño_1, grande_1, pequeño_2, grande_2, ...) -
es decir, la mitad alta de los números están situados, de forma ordenada, en las
posiciones con índice par y la mitad baja de los números están situados de la misma
manera en las posiciones con índice impar.
Quizás la propiedad más crucial del Shell sort es que los elementos permanecen k-
ordenados incluso mientras el espacio disminuye. Se dice que un vector dividido en k
subvectores esta k-ordenado si cada uno de esos subvectores esta ordenado en caso de
considerarlo aislado. Por ejemplo, si una lista fue 5-ordenada y después 3-ordenada, la
lista está ahora no sólo 3-ordenada, sino tanto 5-ordenada como 3-ordenada. Si esto no
fuera cierto, el algoritmo desharía el trabajo que había hecho en iteraciones previas, y no
conseguiría un tiempo de ejecución tan bajo.
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), O(n3 / 2
) (usando los incrementos
de Hibbard de 2k
− 1), O(n4 / 3
) (usando los incrementos de Sedgewick de 9(4i
) − 9(2i
) +
1, o 4i + 1
+ 3(2i
) + 1), o O(nlog2
n), y posiblemente mejores tiempos de ejecución no
comprobados. La existencia de una implementación O(nlogn) en el peor caso del Shell
sort permanece como una pregunta por resolver.
[editar] Implementaciones
El Shell sort se usa comúnmente en lenguajes de programación; esto es una
implementación del algoritmo en C/C++ para ordenar un vector de enteros. La
secuencia de incrementos usada en este ejemplo de código da un tiempo de ejecución
O(n2
) en el peor caso.
[editar] ActionScript
var arrayOriginal:Array = new
Array(2,5,6,8,10,2,3,64,23,76,43,27,75,33,23,45,67,89);
trace("Array desordenado: "+arrayOriginal);
ordenamiento_shell(arrayOriginal,arrayOriginal.length);
function ordenamiento_shell(arrayDesordenado:Array, tamano:uint)
{
var i:uint;
var j:uint;
var incremento:uint;
var temp:uint;
incremento = tamano / 2;
while (incremento>0)
{
for (i=incremento; i<tamano; i++)
{
j = i;
temp = arrayDesordenado[i];
while ((j >= incremento) &&
(arrayDesordenado[j-incremento] > temp))
{
arrayDesordenado[j] = arrayDesordenado[j
- incremento];
j = j - incremento;
}
arrayDesordenado[j] = temp;
}
incremento = incremento/2;
}
trace("Array ordenado: "+arrayDesordenado);
}
[editar] C
void shell_sort(int A[], int size)
{
int i, j, incrmnt, temp;
incrmnt = size/2;
while (incrmnt > 0)
{
for (i=incrmnt; i < size; i++)
{
j = i;
temp = A[i];
while ((j >= incrmnt) && (A[j-incrmnt] > temp))
{
A[j] = A[j - incrmnt];
j = j - incrmnt;
}
A[j] = temp;
}
incrmnt /= 2;
}
}
[editar] C#
using System;
public class ShellSorter
{
public void Sort(int [] list)
{
int j,inc;
inc=list.length/2;
while(inc>0)
{
for(int i=inc+1;i<list.length;i++)
{
j=i-inc;
while(j>0)
{
if(list[j] > list[j+inc])
{
Swap(list[j],list[j+inc]);
j=j-inc;
}
else
{
j=0;
}
}
}
inc=inc/2;
}
}
}
public class MainClass
{
public static void Main()
{
int[] iArrary=new int[]{1,5,3,6,10,55,9,2,87,12,34,75,33,47};
ShellSorter sh=new ShellSorter();
sh.Sort(iArrary);
for(int m=0;m<=13;m++)
Console.WriteLine("{0}",iArrary[m]);
}
}
[editar] Java
public static void shellSort(int[] a) {
for ( int increment = a.length / 2;
increment > 0;
increment = (increment == 2 ? 1 : (int) Math.round(increment
/ 2.2))) {
for (int i = increment; i < a.length; i++) {
for (int j = i; j >= increment && a[j - increment] > a[j];
j -= increment) {
int temp = a[j];
a[j] = a[j - increment];
a[j - increment] = temp;
}
}
}
}
[editar] Perl
sub shellsort {
my $array = shift; # Recibimos una referencia a un array
my $i; # Índice del elemento a comparar
my $j; # Índice del elemento actual a comparar
my $shell; # Tamaño del incremento
# Calculamos el valor del incremento
for ( $shell = 1; $shell < @$array; $shell = 2 * $shell + 1 ) {
;
}
do {
$shell = int( ( $shell - 1 ) / 2 );
# Para todos los elementos, elegidos con un incremento
for ( $i = $shell; $i < @$array; $i++ ) {
for ( $j = $i - $shell;
$j >= 0 && $array->[ $j ] > $array->[ $j + $shell ];
$j -= $shell ) {
# Intercambiamos valores
@$array[ $j, $j + $shell ] = @$array[ $j + $shell, $j
];
}
}
} while $shell > 1;
}
[editar] Python
def shellsort(a):
def new_increment(a):
i = int(len(a) / 2)
yield i
while i<>1:
if i==2:
i = 1
else:
i = int(round(i/2.2))
yield i
for increment in new_increment(a):
for i in range(increment, len(a)):
for j in range(i, increment-1, -increment):
if a[j-increment] < a[j]:
break
a[j],a[j-increment] = a[j - increment],a[j]
return a
[editar] Visual Basic
Sub Shell_Sort(ByRef V) 'debemos pasarle el arreglo(de enteros) desde
el programa principal()
Dim I, Medio, J, Temp As Integer
Dim Ordenado As Boolean
Medio = UBound(V)
While (Medio > 0)
Medio = Medio  2
Do
Ordenado = True
For J = 0 To UBound(V) - Medio ' se asume que el arreglo va de
0 a UBound(V) elementos
I = J + Medio
If V(J) > V(I) Then ' Se intercambian los elementos
Temp = V(J)
V(J) = V(I)
V(I) = Temp
Ordenado = False
End If
Next
Loop Until Ordenado
Wend
End Sub
Sub principal()
Dim Arr(99) As Integer
Dim I As Integer
For I = 0 To 99
Arr(I) = Int(Rnd() % 1000) ' Se llena el arreglo con números
menores que 1000
Next I
Call Shell_Sort(Arr)
End Sub
Quicksort
De Wikipedia, la enciclopedia libre
(Redirigido desde Ordenamiento rápido)
Saltar a navegación, búsqueda
Quicksort en acción sobre una lista de números aleatorios. Las líneas horizontales son
valores pivote.
El ordenamiento rápido (quicksort en inglés) es un algoritmo basado en la técnica de
divide y vencerás, que permite, en promedio, ordenar n elementos en un tiempo
proporcional a n log n.
Contenido
[ocultar]
1 Descripción del algoritmo
o 1.1 Demostración
2 Optimización del algoritmo
o 2.1 Técnicas de elección del pivote
o 2.2 Técnicas de reposicionamiento
o 2.3 Transición a otro algoritmo
3 Ejemplo
4 Implementaciones
5 Véase también
6 Referencias
[editar] Descripción del algoritmo
El algoritmo fundamental es el siguiente:
Elegir un elemento de la lista de elementos a ordenar, al que llamaremos pivote.
Resituar los demás elementos de la lista a cada lado del pivote, de manera que a
un lado queden todos los menores que él, y al otro los mayores. Los elementos
iguales al pivote pueden ser colocados tanto a su derecha como a su izquierda,
dependiendo de la implementación deseada. En este momento, el pivote ocupa
exactamente el lugar que le corresponderá en la lista ordenada.
La lista queda separada en dos sublistas, una formada por los elementos a la
izquierda del pivote, y otra por los elementos a su derecha.
Repetir este proceso de forma recursiva para cada sublista mientras éstas
contengan más de un elemento. Una vez terminado este proceso todos los
elementos estarán ordenados.
Como se puede suponer, la eficiencia del algoritmo depende de la posición en la que
termine el pivote elegido.
En el mejor caso, el pivote termina en el centro de la lista, dividiéndola en dos
sublistas de igual tamaño. En este caso, el orden de complejidad del algoritmo es
O(n·log n).
En el peor caso, el pivote termina en un extremo de la lista. El orden de
complejidad del algoritmo es entonces de O(n²). El peor caso dependerá de la
implementación del algoritmo, aunque habitualmente ocurre en listas que se
encuentran ordenadas, o casi ordenadas. 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.
En el caso promedio, el orden es O(n·log n).
No es extraño, pues, que la mayoría de optimizaciones que se aplican al algoritmo se
centren en la elección del pivote.
[editar] Demostración
Podríamos probar el orden de ejecución en el mejor caso de la siguiente manera:
Vamos a suponer que el número total de elementos a ordenar es potencia de dos, es
decir, n = 2k
. de aquí podemos ver que k = log2(n), donde k es el número de divisiones
que realizará el algoritmo.
En la primera fase del algoritmo habrán n comparaciones, en la segunda fase el
algoritmo creará dos sublistas aproximadamente de tamaño n/2. El número total de
comparaciones de estas dos sublistas es: 2(n/2) = n. En la tercera fase el algoritmo
procesará 4 sublistas más, por tanto el número total de comparaciones en esta fase es
4(n/4) = n.
En conclusión, el número total de comparaciones que hace el algoritmo es:
n + n + n + ..... + n = kn, donde k = log2(n), por tanto el tiempo de ejecución del
algoritmo en el mejor caso es O(n.log2n)
[editar] Optimización del algoritmo
Cabe destacar que de usarse en su versión recursiva las siguientes optimizaciones y sus
desventajas no se ven vistas en el tiempo de ejecución del mismo manteniéndose, así el
tiempo de ejecución planteado en un principio.
[editar] Técnicas de elección del pivote
El algoritmo básico del metodo Quicksort consiste en tomar cualquier elemento de la
lista al cual denominaremos como pivote, dependiendo de la partición en 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.
Otra opción puede ser recorrer la lista para saber de antemano qué elemento
ocupará la posición central de la lista, para elegirlo como pivote. Esto puede
hacerse en O(n) y asegura que hasta en el peor de los casos, el algoritmo sea
O(n·log n). No obstante, el cálculo adicional rebaja bastante la eficiencia del
algoritmo en el caso promedio.
La opción a medio camino es tomar tres elementos de la lista - por ejemplo, el
primero, el segundo, y el último - y compararlos, eligiendo el valor del medio
como pivote.
[editar] Técnicas de reposicionamiento
Una idea preliminar para ubicar el pivote en su posición final sería contar la cantidad de
elementos menores que él, y colocarlo un lugar más arriba, moviendo luego todos esos
elementos menores que él a su izquierda, para que pueda aplicarse la recursividad.
Existe, no obstante, un procedimiento mucho más efectivo. Se utilizan dos índices: i, al
que llamaremos índice izquierdo, y j, al que llamaremos índice derecho. El algoritmo es
el siguiente:
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).
Cuando lista[i] sea mayor que el pivote y lista[j] sea menor, se intercambian los
elementos en esas posiciones.
Repetir esto hasta que se crucen los índices.
El punto en que se cruzan los índices es la posición adecuada para colocar el
pivote, porque sabemos que a un lado los elementos son todos menores y al otro
son todos mayores (o habrían sido intercambiados).
[editar] Transición a otro algoritmo
Como se comentó antes, el algoritmo quicksort ofrece un orden de ejecución O(n²) para
ciertas permutaciones "críticas" de los elementos de la lista, que siempre surgen cuando
se elige el pivote «a ciegas». La permutación concreta depende del pivote elegido, pero
suele corresponder a secuencias ordenadas. Se tiene que la probabilidad de encontrarse
con una de estas secuencias es inversamente proporcional a su tamaño.
Los últimos pases de quicksort son numerosos y ordenan cantidades pequeña de
elementos. Un porcentaje medianamente alto de ellos estarán dispuestos de una
manera similar al peor caso del algoritmo, volviendo a éste ineficiente. Una
solución a este problema consiste en ordenar las secuencias pequeñas usando
otro algoritmo. Habitualmente se aplica el algoritmo de inserción para
secuencias de tamaño menores de 8-15 elementos.
Pese a que en secuencias largas de elementos la probabilidad de hallarse con una
configuración de elementos "crítica" es muy baja, esto no evita que sigan
apareciendo (a veces, de manera intencionada). El algoritmo introsort es una
extensión del algoritmo quicksort que resuelve este problema utilizando heapsort
en vez de quicksort cuando el número de recursiones excede al esperado.
Parámetros:
o Se debe llamar a la función Quicksort desde donde quiera ejecutarse
o Ésta llamará a colocar pivote para encontrar el valor del mismo
o Se ejecutará el algoritmo Quicksort de forma recursiva a ambos lados del
pivote
int colocar(int *v, int b, int t)
{
int i;
int pivote, valor_pivote;
int temp;
pivote = b;
valor_pivote = v[pivote];
for (i=b+1; i<=t; i++){
if (v[i] < valor_pivote){
pivote++;
temp=v[i];
v[i]=v[pivote];
v[pivote]=temp;
}
}
temp=v[b];
v[b]=v[pivote];
v[pivote]=temp;
return pivote;
}
void Quicksort(int* v, int b, int t)
{
int pivote;
if(b < t){
pivote=colocar(v, b, t);
Quicksort(v, b, pivote-1);
Quicksort(v, pivote+1, t);
}
}
Nota: Los tres parámetros de la llamada inicial a Quicksort serán array[0], 0,
numero_elementos -1, es decir, si es un array de 6 elementos array[0], 0, 5
[editar] Ejemplo
En el siguiente ejemplo se marcan el pivote y los índices i y j con las letras p, i y j
respectivamente.
Comenzamos con la lista completa. El elemento pivote será el 4:
5 - 3 - 7 - 6 - 2 - 1 - 4
p
Comparamos con el 5 por la izquierda y el 1 por la derecha.
5 - 3 - 7 - 6 - 2 - 1 - 4
i j p
5 es mayor que 4 y 1 es menor. Intercambiamos:
1 - 3 - 7 - 6 - 2 - 5 - 4
i j p
Avanzamos por la izquierda y la derecha:
1 - 3 - 7 - 6 - 2 - 5 - 4
i j p
3 es menor que 4: avanzamos por la izquierda. 2 es menor que 4: nos mantenemos ahí.
1 - 3 - 7 - 6 - 2 - 5 - 4
i j p
7 es mayor que 4 y 2 es menor: intercambiamos.
1 - 3 - 2 - 6 - 7 - 5 - 4
i j p
Avanzamos por ambos lados:
1 - 3 - 2 - 6 - 7 - 5 - 4
iyj p
En este momento termina el ciclo principal, porque los índices se cruzaron. Ahora
intercambiamos lista[i] con lista[sup] (pasos 16-18):
1 - 3 - 2 - 4 - 7 - 5 - 6
p
Aplicamos recursivamente a la sublista de la izquierda (índices 0 - 2). Tenemos lo
siguiente:
1 - 3 - 2
1 es menor que 2: avanzamos por la izquierda. 3 es mayor: avanzamos por la derecha.
Como se intercambiaron los índices termina el ciclo. Se intercambia lista[i] con
lista[sup]:
1 - 2 - 3
El mismo procedimiento se aplicará a la otra sublista. Al finalizar y unir todas las
sublistas queda la lista inicial ordenada en forma ascendente.
1 - 2 - 3 - 4 - 5 - 6 - 7
[editar] Implementaciones
El algoritmo de ordenamiento rápido (Quicksort) en:
Pseudocódigo
function quicksort(array)
var list, less, greater
if length(array) ≤ 1
return array
seleccionar y eliminar un valor pivote pivot en el array
for each x in array
if x < pivot then añadir x a less
else añadir x a greater
return concadenar(quicksort(less), pivot, quicksort(greater))
C
int pivotar (int v[], int izq, int der)
{
int posicionPivote = (izq + der) / 2;
int valorPivote = v[posicionPivote];
int indiceAlmacenamiento;
swap (v, posicionPivote, der);//Se situal pivote al final del
vector
indiceAlmacenamiento = izq;
for (int indiceLectura = izq; indiceLectura < der;
indiceLectura++){
if (v[indiceLectura] <= valorPivote){
swap (v, indiceLectura, indiceAlmacenamiento);
indiceAlmacenamiento++;
}
}
swap (v, indiceAlmacenamiento, der); //Se coloca el pivote en su
lugar.
return indiceAlmacenamiento;
}
void quicksort (int v[], int izq, int der)
{
int pivote;
if(izq < der){
pivote = pivotar (v, izq, der); //Esta operación coloca el
pivote en su lugar.
quicksort(v, izq, pivote-1);
quicksort(v, pivote+1, der);
}
}
Otra en C. Trabaja sólo con punteros (no índices). Ordena enteros de menor a mayor.
Pivot: El primero del vector.
void quicksort(int* izq, int* der) /*Se llama con:
quicksort(&vector[0],&vector[n-1]);*/
{
if(der<izq) return;
int pivot=*izq;
int* ult=der;
int* pri=izq;
while(izq<der)
{
while(*izq<=pivot && izq<der+1) izq++;
while(*der>pivot && der>izq-1) der--;
if(izq<der) swap(izq,der);
}
swap(pri,der);
quicksort(pri,der-1);
quicksort(der+1,ult);
}
void swap(int* a, int* b)
{
int temp=*a;
*a=*b;
*b=temp;
}
Java
//Recibe un vector de enteros y el índice del primer y último elemento
válido del mismo
void ordenarQuicksort(int[] vector, int primero, int ultimo){
int i=primero, j=ultimo;
int pivote=vector[(primero + ultimo) / 2];
int auxiliar;
do{
while(vector[i]<pivote) i++;
while(vector[j]>pivote) j--;
if (i<=j){
auxiliar=vector[j];
vector[j]=vector[i];
vector[i]=auxiliar;
i++;
j--;
}
} while (i<=j);
if(primero<j) ordenarQuicksort(vector,primero, j);
if(ultimo>i) ordenarQuicksort(vector,i, ultimo);
}
C#
void Quicksort(int[] v, int prim, int ult)
{
if (prim < ult)
{
/* Selecciona un elemento del vector y coloca los
menores
que él a su izquierda y los mayores a su derecha */
int p = Pivote(v, prim, ult, ult);
/* Repite el proceso para cada una de las
particiones generadas en el paso anterior */
Quicksort(v, prim, p - 1);
Quicksort(v, p + 1, ult);
}
}
/* Implementación no clásica de la función Pivote. En lugar de
recorrer el vector simultáneamente desde ambos extremos hasta el
cruce de índices, se recorre desde el comienzo hasta el final */
int Pivote(int[] v, int prim, int ult, int piv)
{
int p = v[piv];
int j = prim;
// Mueve el pivote a la última posición del vector
Intercambia(v, piv, ult);
/* Recorre el vector moviendo los elementos menores
o iguales que el pivote al comienzo del mismo */
for (int i = prim; i < ult; i++)
{
if (v[i] <= p)
{
Intercambia(v, i, j);
j++;
}
}
// Mueve el pivote a la posición que le corresponde
Intercambia(v, j, ult);
return j;
}
void Intercambia(int[] v, int a, int b)
{
if (a != b)
{
int tmp = v[a];
v[a] = v[b];
v[b] = tmp;
}
}
Python
def quicksort(datos, primero, ultimo):
i = primero
j = ultimo
pivote = (datos[primero] + datos[ultimo]) / 2
while i < j:
while datos[i] < pivote:
i+=1
while datos[j] > pivote:
j-=1
if i <= j:
aux = datos[i]
datos[i] = datos[j]
datos[j] = aux
i+=1
j-=1
if primero < j:
datos = quicksort(datos, primero, j)
if ultimo > i:
datos = quicksort(datos, i, ultimo)
return datos
Otra en Python
def qsort(list):
try:
x=list.pop()
except:
return []
return qsort(filter((lambda y: y<x), list)) + [x] +
qsort(filter((lambda y: y>=x), list))
Haskell
qsort :: Ord a => [a] -> [a]
qsort [] = []
qsort (x:xs) = qsort (filter (< x) xs) ++ [x] ++ qsort (filter (>= x)
xs)
Otra en Haskell
qsort :: Ord a => [a] -> [a]
qsort [] = []
qsort (x:xs) = qsort elmts_lt_x ++ [x] ++ qsort elmts_greq_x
where
elmts_lt_x = [y | y <- xs, y < x]
elmts_greq_x = [y | y <- xs, y >= x]
Asm
quicksort:
push ebp
mov ebp,esp
push esi
push ebx
push ecx
push edx
mov ebx,dword[ebp + 12]
mov ecx,dword[ebp + 16]
cdq
mov eax, ebx
add eax, ecx
push ecx
mov ecx,2
div ecx
pop ecx
xchg edx,eax
mov esi, [ebp + 8]
mov edx,dword[esi + edx * 4]
qs@L1:
qs@L1@L1:
cmp dword[esi + ebx * 4],edx
jge qs@L1@L1@out
inc ebx
jmp qs@L1@L1
qs@L1@L1@out:
qs@L1@L2:
cmp dword[esi + ecx * 4],edx
jle qs@L1@L2@out
dec ecx
jmp qs@L1@L2
qs@L1@L2@out:
qs@L1@IF1:
cmp ebx, ecx
jg qs@L1@IF1@out
mov eax, dword[esi + ebx * 4]
xchg eax, dword[esi + ecx * 4]
mov dword[esi + ebx * 4], eax
inc ebx
dec ecx
qs@L1@IF1@out:
cmp ebx,ecx
jle qs@L1
qs@L1@out:
qs@IF1:
cmp dword[ebp + 12],ecx
jge qs@IF1@out
push ecx
push dword[ebp + 12]
push esi
call quicksort
qs@IF1@out:
qs@IF2:
cmp ebx, dword[ebp + 16]
jge qs@IF2@out
push dword[ebp + 16]
push ebx
push esi
call quicksort
qs@IF2@out:
pop edx
pop ecx
pop ebx
pop esi
pop ebp
retn 12
Prolog
quicksort([], []).
quicksort([CABEZA | COLA], ORDENADO) :- partir(CABEZA, COLA, IZDA,
DCHA),
quicksort(IZDA, ORDENADO_IZDA),
quicksort(DCHA, ORDENADO_DCHA),
concatenar(ORDENADO_IZDA, [CABEZA
| ORDENADO_DCHA], ORDENADO).
partir(PIVOTE, [], [], []).
partir(PIVOTE, [CABEZA | COLA], [CABEZA | IZDA], DCHA) :- CABEZA @=<
PIVOTE,
partir(PIVOTE, COLA, IZDA, DCHA).
partir(PIVOTE, [CABEZA | COLA], IZDA, [CABEZA | DCHA]) :- CABEZA @>
PIVOTE,
partir(PIVOTE, COLA, IZDA, DCHA).
concatenar([], LISTA, LISTA).
concatenar([CABEZA | LISTA_1], LISTA_2, [CABEZA | LISTA_3]) :-
concatenar(LISTA_1, LISTA_2, LISTA_3).

Contenu connexe

Tendances

Insercion directa
Insercion directaInsercion directa
Insercion directa
abelpit2
 
Estructura de datos: lista, pilas y colas
Estructura de datos: lista, pilas y colasEstructura de datos: lista, pilas y colas
Estructura de datos: lista, pilas y colas
Huascar Génere
 
Busqueda Binaria
Busqueda BinariaBusqueda Binaria
Busqueda Binaria
ITCV
 

Tendances (20)

Insercion directa
Insercion directaInsercion directa
Insercion directa
 
Arboles M-Way, 2-3 y 2-3-4
Arboles M-Way, 2-3 y 2-3-4Arboles M-Way, 2-3 y 2-3-4
Arboles M-Way, 2-3 y 2-3-4
 
Estructura de Datos Unidad - V: Métodos de Ordenamiento
Estructura de Datos Unidad - V: Métodos de OrdenamientoEstructura de Datos Unidad - V: Métodos de Ordenamiento
Estructura de Datos Unidad - V: Métodos de Ordenamiento
 
Unidad 5
Unidad 5Unidad 5
Unidad 5
 
Estructura de Datos - Unidad 5 metodos de ordenamiento
Estructura de Datos - Unidad 5 metodos de ordenamientoEstructura de Datos - Unidad 5 metodos de ordenamiento
Estructura de Datos - Unidad 5 metodos de ordenamiento
 
METODOLOGIA DE sistemas blandos
METODOLOGIA DE sistemas blandosMETODOLOGIA DE sistemas blandos
METODOLOGIA DE sistemas blandos
 
Metodos de ordenamiento
Metodos de ordenamientoMetodos de ordenamiento
Metodos de ordenamiento
 
4. algoritmo de ordenamiento externo
4. algoritmo de ordenamiento externo4. algoritmo de ordenamiento externo
4. algoritmo de ordenamiento externo
 
Programación 3: árboles de búsqueda equilibrados
Programación 3: árboles de búsqueda equilibradosProgramación 3: árboles de búsqueda equilibrados
Programación 3: árboles de búsqueda equilibrados
 
Reporte metodos de busqueda y ordenamiento
Reporte metodos de busqueda y ordenamientoReporte metodos de busqueda y ordenamiento
Reporte metodos de busqueda y ordenamiento
 
Pilas y colas
Pilas y colasPilas y colas
Pilas y colas
 
Informe ordenamiento
Informe ordenamientoInforme ordenamiento
Informe ordenamiento
 
Arboles binarios
Arboles binariosArboles binarios
Arboles binarios
 
Estructura de datos: lista, pilas y colas
Estructura de datos: lista, pilas y colasEstructura de datos: lista, pilas y colas
Estructura de datos: lista, pilas y colas
 
Método de ordenamiento shell
Método de ordenamiento shellMétodo de ordenamiento shell
Método de ordenamiento shell
 
Ordenamiento ppt
Ordenamiento pptOrdenamiento ppt
Ordenamiento ppt
 
Heap sort (Monticulos)
Heap sort (Monticulos)Heap sort (Monticulos)
Heap sort (Monticulos)
 
Busqueda Binaria
Busqueda BinariaBusqueda Binaria
Busqueda Binaria
 
Tipos de listas en estructura de datos
Tipos de listas en estructura de datosTipos de listas en estructura de datos
Tipos de listas en estructura de datos
 
Quicksort
QuicksortQuicksort
Quicksort
 

En vedette

array
arrayarray
array
mario
 
Ordenamiento x insercion espo
Ordenamiento x insercion espoOrdenamiento x insercion espo
Ordenamiento x insercion espo
Ana Maria
 
Matematicas discretas para la computacion
Matematicas discretas para la computacionMatematicas discretas para la computacion
Matematicas discretas para la computacion
William DS
 
Ordenamiento por inserción.
Ordenamiento por inserción.Ordenamiento por inserción.
Ordenamiento por inserción.
AnGela PeRez
 
Tipos de plantas
Tipos de plantasTipos de plantas
Tipos de plantas
michellezea
 
Ordenamiento por insercion binaria
Ordenamiento por insercion binariaOrdenamiento por insercion binaria
Ordenamiento por insercion binaria
Edwin Pasindo
 
Metodos de ordenacion radix sort
Metodos de ordenacion radix sortMetodos de ordenacion radix sort
Metodos de ordenacion radix sort
tephyfree
 
METODOS DE ORDENACION ORDENAMIENTO Y BUSQUEDA (ALGORITMOS)
METODOS DE ORDENACION ORDENAMIENTO Y BUSQUEDA (ALGORITMOS)METODOS DE ORDENACION ORDENAMIENTO Y BUSQUEDA (ALGORITMOS)
METODOS DE ORDENACION ORDENAMIENTO Y BUSQUEDA (ALGORITMOS)
Fuerza Auriazul
 

En vedette (19)

array
arrayarray
array
 
Ordenamiento x insercion espo
Ordenamiento x insercion espoOrdenamiento x insercion espo
Ordenamiento x insercion espo
 
Grafos
GrafosGrafos
Grafos
 
Matematicas discretas para la computacion
Matematicas discretas para la computacionMatematicas discretas para la computacion
Matematicas discretas para la computacion
 
Algoritmos de Ordenamiento
Algoritmos de OrdenamientoAlgoritmos de Ordenamiento
Algoritmos de Ordenamiento
 
Método de ordenamiento inserción
Método de ordenamiento inserciónMétodo de ordenamiento inserción
Método de ordenamiento inserción
 
E7 ensayo-ordenacion
E7 ensayo-ordenacionE7 ensayo-ordenacion
E7 ensayo-ordenacion
 
Capítulo IV
Capítulo IVCapítulo IV
Capítulo IV
 
Ordenamiento por inserción.
Ordenamiento por inserción.Ordenamiento por inserción.
Ordenamiento por inserción.
 
diagrama inserción
diagrama insercióndiagrama inserción
diagrama inserción
 
Tipos de plantas
Tipos de plantasTipos de plantas
Tipos de plantas
 
Insertion sort
Insertion sortInsertion sort
Insertion sort
 
Ordenamiento por insercion binaria
Ordenamiento por insercion binariaOrdenamiento por insercion binaria
Ordenamiento por insercion binaria
 
Métodos de ordenamiento
Métodos de ordenamiento Métodos de ordenamiento
Métodos de ordenamiento
 
Metodos de ordenacion radix sort
Metodos de ordenacion radix sortMetodos de ordenacion radix sort
Metodos de ordenacion radix sort
 
Método de ordenación por inserción directa
Método de ordenación por inserción directaMétodo de ordenación por inserción directa
Método de ordenación por inserción directa
 
Algoritmo por seleccion
Algoritmo por seleccionAlgoritmo por seleccion
Algoritmo por seleccion
 
Algortimos De Ordenamiento
Algortimos De OrdenamientoAlgortimos De Ordenamiento
Algortimos De Ordenamiento
 
METODOS DE ORDENACION ORDENAMIENTO Y BUSQUEDA (ALGORITMOS)
METODOS DE ORDENACION ORDENAMIENTO Y BUSQUEDA (ALGORITMOS)METODOS DE ORDENACION ORDENAMIENTO Y BUSQUEDA (ALGORITMOS)
METODOS DE ORDENACION ORDENAMIENTO Y BUSQUEDA (ALGORITMOS)
 

Similaire à Algoritmos de ordenamiento

Metodo de la burbuja en algoritmo
Metodo de la burbuja en algoritmo Metodo de la burbuja en algoritmo
Metodo de la burbuja en algoritmo
ikky2345
 
Ordenamientos de vectores
Ordenamientos de vectoresOrdenamientos de vectores
Ordenamientos de vectores
sirekarol
 
Metodos de odenamiento de vctores
Metodos de odenamiento de vctoresMetodos de odenamiento de vctores
Metodos de odenamiento de vctores
mishuhot
 
Unidad 1 1
Unidad 1   1Unidad 1   1
Unidad 1 1
VivianaG
 
Algoritmos Ordenamiento
Algoritmos OrdenamientoAlgoritmos Ordenamiento
Algoritmos Ordenamiento
Daniel Guaycha
 

Similaire à Algoritmos de ordenamiento (20)

Ordenamiento en C++
Ordenamiento en C++Ordenamiento en C++
Ordenamiento en C++
 
Informe ordenamiento
Informe ordenamientoInforme ordenamiento
Informe ordenamiento
 
Metodo de la burbuja en algoritmo
Metodo de la burbuja en algoritmo Metodo de la burbuja en algoritmo
Metodo de la burbuja en algoritmo
 
1_Metodos.doc
1_Metodos.doc1_Metodos.doc
1_Metodos.doc
 
Arrays metodos deordenamiento01
Arrays metodos deordenamiento01Arrays metodos deordenamiento01
Arrays metodos deordenamiento01
 
Ordenamientos de vectores
Ordenamientos de vectoresOrdenamientos de vectores
Ordenamientos de vectores
 
Presentacion
PresentacionPresentacion
Presentacion
 
Metodos de odenamiento de vctores
Metodos de odenamiento de vctoresMetodos de odenamiento de vctores
Metodos de odenamiento de vctores
 
Ordenacion y busqueda
Ordenacion y busquedaOrdenacion y busqueda
Ordenacion y busqueda
 
metodos-de-ordenamiento.pdf
metodos-de-ordenamiento.pdfmetodos-de-ordenamiento.pdf
metodos-de-ordenamiento.pdf
 
Burbuja Bidireccional
Burbuja BidireccionalBurbuja Bidireccional
Burbuja Bidireccional
 
Informe insercion
Informe insercionInforme insercion
Informe insercion
 
datos de ordenamiento
datos de ordenamientodatos de ordenamiento
datos de ordenamiento
 
Bus99
Bus99Bus99
Bus99
 
Ordenamiento
OrdenamientoOrdenamiento
Ordenamiento
 
Unidad 1 1
Unidad 1   1Unidad 1   1
Unidad 1 1
 
Algoritmos Ordenamiento
Algoritmos OrdenamientoAlgoritmos Ordenamiento
Algoritmos Ordenamiento
 
Algoritmos ordenación.pptx
Algoritmos ordenación.pptxAlgoritmos ordenación.pptx
Algoritmos ordenación.pptx
 
expo de metodos de busqueda.pptx
expo de metodos de busqueda.pptxexpo de metodos de busqueda.pptx
expo de metodos de busqueda.pptx
 
Unidad 5
Unidad 5Unidad 5
Unidad 5
 

Algoritmos de ordenamiento

  • 1. Ordenamiento de burbuja De Wikipedia, la enciclopedia libre Saltar a navegación, búsqueda El Ordenamiento de burbuja (Bubble Sort en inglés) es un sencillo algoritmo de ordenamiento. Funciona revisando cada elemento de la lista que va a ser ordenada con el siguiente, intercambiándolos de posición si están en el orden equivocado. 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. Contenido [ocultar] 1 Descripción 2 Análisis o 2.1 Rendimiento en casos óptimos o 2.2 Conejos y Tortugas (Yo-yos) (?) 3 En la práctica 4 Implementación 5 Véase también 6 Enlaces externos [editar] Descripción Una manera simple de expresar el ordenamiento de burbuja en pseudocódigo es la siguient e: En este algorit mo se trata de ordenar una lista de valores: a, de n término s numera dos del termino 0 al n-1, consta de dos bucles anidados uno con el índice i, que acota el
  • 2. recorrido de la burbuja en sentido inverso de 2 a n, y un segundo bucle con el índice j, con un recorrido desde 0 hasta n-i, para cada iteración del primer bucle, que indica el lugar de la burbuja. La burbuja son dos términos de la lista seguidos, j y j+1, que se comparan, si el primero es menor que el segundo sus valores se intercambian. Esta comparación se repite en el centro de los dos bucles, dando lugar a la postre a una lista ordenada, puede verse que el número de repeticiones sola depende de n, y no del orden de los términos, esto es si pasamos al algoritmo una lista ya ordenada, realizara todas las comparaciones exactamente igual que para una lista no ordenada, esta es una característica de este algoritmo, luego veremos una variante que evita este problema. Para comprender el funcionamiento, veamos un ejemplo sencillo: Partimos de una lista de números que hay que ordenar: Podemos ver que la lista tiene cinco términos, luego: El índice i hará un recorrido de 2 hasta n: Que en este caso será de 2 a 5. Para cada uno de los valores de i, j tomara sucesivamente los valores de 0 hasta n-i: Para cada valor de j, obtenido en ese orden, se compara el valor del índice j con el siguiente: Si el termino j es menor, en su caso podría se mayor, que el termino j+1, los valores se permutan, en caso contrario se continúa con la iteración. Para el caso del ejemplo, tenemos que: Para la primera iteración del primer bucle:
  • 3. y j tomara los valores de 0 hasta 3: Cuando j vale 0, se comparan , el 55 y el 86, dado que 55 < 86 no se permutan el orden. Ahora j vale 1 y se comparan el 86 y el 48 Como 86 > 48, se permutan, dando lugar a una nueva lista. Se repite el proceso hasta que j valga 3, dando lugar a una lista parcialmente ordenada, podemos ver que el termino de mayor valor esta en el lugar más alto. Ahora i vale 3, y j hará un recorrido de 0 a 2. Primero j vale 0, se comparan , el 55 y el 48, como 55 > 48 se permutan dando lugar a la nueva lista. Para j = 1 se compara el 55 con el 16 y se cambian de orden. Para j = 2 se compara el 55 y el 82 y se dejan como están, finalizando el bucle con una lista mejor ordenada, puede verse que los dos valores más altos ya ocupan su lugar. No se ha realizado ninguna comparación con el termino cuarto, dado que ya se sabe que después del primer ciclo es el mayor de la lista. El algoritmo consiste en comparaciones sucesivas de dos términos consecutivos, ascendiendo de abajo a arriba en cada iteración, como la ascensión de las burbujas de aire en el agua, de ahí el nombre del procedimiento, en la primera iteración el recorrido ha sido completo, en el segundo se ha dejado él ultimo termino, al tener ya el mayor de los valores, en los sucesivos sé ira dejando re realizar las ultimas comparaciones, como se puede ver. Ahora ya i vale 4 y j recorrerá los valores de 0 a 1. Cuando j vale 0, se comparan esto es el 48 y el 16 dado que 48 es mayor que 16 se permutan los valores, dando lugar a una lista algo más ordenada que la anterior, desde esta nueva ordenación, j pasa a valer 1, con lo que se comparan los términos el 48 y el 55 que quedan en el mismo orden. En este caso la burbuja ha ascendido menos que en los casos anteriores, y la lista esta ya ordenada, pero el algoritmo tendrá que completarse, realizando una ultima iteración.
  • 4. Hay que tener en cuenta que el bucle para realiza un número fijo de repeticiones y para finalizar tendrán que completarse, aun en el caso extremo, de que la lista estaría previamente ordenada. Por ultimo i vale 5 y j solo puede vale 0, con lo que solo se realizara una comparación de el 16 y el 48, que ya están ordenados y se dejan igual. Los bucles finalizan y también el procedimiento, dejando la lista ordenada. Una variante que finaliza en caso de que la lista este ordenada, puede ser la siguiente, empleando un centinela ordenado, que detecta que no se ha modificado la lista en un recorrido de la burbuja, y que por tanto la lista ya esta ordenada, finalizando.
  • 5. [editar] Análisis Ejemplo del ordenamiento de burbuja ordenando una lista de números aleatorios. [editar] Rendimiento en casos óptimos El ordenamiento de burbuja tiene una complejidadΩ(n²). Cuando una lista ya está ordenada, a diferencia del ordenamiento por inserción que pasará por la lista una vez, y encontrará que no hay necesidad de intercambiar las posiciones de los elementos, el método de ordenación por burbuja está forzado a pasar por dichas comparaciones, lo que hace que su complejidad sea cuadrática en el mejor de los casos, esto lo cataloga como el algoritmo mas ineficiente que existe aunque para muchos programadores sea el más sencillo de implementar. [editar] Conejos y Tortugas (Yo-yos) (?) La posición de los elementos en el ordenamiento de burbuja juegan un papel muy importante en la determinación del rendimiento. Los elementos mayores al principio de la lista son rápidamente movidos hacia abajo. En cambio, elementos menores en el fondo de la lista, se mueven a la parte superior muy lentamente. Esto llevó a nombrar estos elementos conejos y tortugas, respectivamente. Varios esfuerzos se han realizado para eliminar las tortugas véase Exterminación y mejorar la velocidad del ordenamiento de burbuja, la cual será más redonda que nunca. El Ordenamiento por sacudida es un buen ejemplo, aunque aún mantiene, en el peor de los casos, una complejidad O (n2 ). El ordenamiento por combinación compara los elementos primero en pedazos grandes de la lista, moviendo tortugas extremadamente rápido, antes de proceder a pedazos cada vez más pequeños para alisar la lista. Su velocidad promedio es comparable a algoritmos rápidos (y complejos) como el ordenamiento rápido. [editar] En la práctica
  • 6. A pesar de que el ordenamiento de burbuja es uno de los algoritmos más sencillos de implementar, su orden O (n2 ) lo hace muy ineficiente para usar en listas que tengan más que un número reducido de elementos. Incluso entre los algoritmos de ordenamiento de orden O (n2 ), otros procedimientos como el Ordenamiento por inserción son considerados más eficientes. Dada su simplicidad, el ordenamiento de burbuja es utilizado para introducir el concepto de algoritmo, o de algoritmo de ordenamiento para estudiantes de ciencias de la computación. Aunque algunos investigadores como Owen Astrachan han criticado al ordenamiento de burbuja y su popularidad en la educación de la computación, recomendando que ya no debe ser enseñado. El ordenamiento de burbuja es asintóticamente equivalente, en tiempos de ejecución con el Ordenamiento por inserción en el peor de los casos, pero ambos algoritmos difieren principalmente en la cantidad de intercambios que son necesarios. Resultados experimentales, como los descubiertos por Astrachan han demostrado que el ordenamiento por inserción funcionan considerablemente mejor incluso con listas aleatorias. Por esta razón, muchos libros de algoritmos modernos evitan usar el ordenamiento de burbuja, utilizando en cambio el ordenamiento por inserción. El ordenamiento de burbuja interactúa vagamente con el hardware de las CPU modernas. Requiere al menos el doble de escrituras que el ordenamiento por inserción, el doble de pérdidas de cache, y asintóticamente más predicción de saltos. Varios experimentos, hechos por Astrachan, de ordenamiento de cadenas en Java, muestran que el ordenamiento de burbuja es 5 veces más lento que el ordenamiento por inserción y 40% más lento que el ordenamiento por selección. [editar] Implementación A continuación se muestra el Ordenamiento de burbuja en distintos lenguajes de programación: LUA function burbuja_ordenar(t) for i=1, #t do for j=i+1, #t do if (t[i] > t[j]) then temp = t[i] t[i] = t[j] t[j] = temp end end end end QBASIC CLS RANDOMIZE TIMER n = 10
  • 7. DIM a(n) REM Generar e imprimir de a(0) a a(n) números aleatorios FOR i = 0 TO n a(i) = INT(RND * 1000) PRINT USING "a(##)=#####"; i; a(i) NEXT PRINT REM algoritmo de la burbuja FOR j = n TO 1 STEP -1 FOR i = 1 TO j IF a(i - 1) > a(i) THEN aux = a(i) a(i) = a(i - 1) a(i - 1) = aux END IF NEXT NEXT REM imprimir datos ordenados FOR i = 0 TO n PRINT USING "a(##)=#####"; i; a(i) NEXT C //Ordenamiento por metodo de Burbujeo // Por Leandro D Ferro void ordenamientoBurbuja(int v[], int util_v) { int temp, i, j; for (i = 0; i < util_v ; i++) { for (j = i + 1; j < util_v - 1; j++) { if (v[i] > v[j]) { temp = v[i]; v[i] = v[j]; v[j] = temp; } } } } C++ template<typename _Ty> void bubble_sort(vector<_Ty> & v){ for (size_t i = 0; i < v.size() - 1; ++i){ for (size_t j = i + 1; j < v.size(); ++j){ if (v[i] > v[j]) swap(v[i], v[j]); } } } C#
  • 8. Public int[] OrdenarBurbuja(int[]x) { int t= x.Length, temp; for(int i=1 ; i< t ; i++) for(int j = t-1 ; j >= i; j--) { if(x[j] < x[j-1]) { temp= x[j]; x[j]= x[j-1]; x[j-1]= temp; } } } Java //Ordenamiento por Burbuja // by ramses2999 public static int[] OrdenarBurbuja(int[] n){ int temp; int t = n.length; for (int i = 1; i < t; i++) { for (int k = t- 1; k >= i; k--) { if(n[k] < n[k-1]){ temp = n[k]; n[k] = n[k-1]; n[k-1]= temp; }//fin if }// fin 2 for }//fin 1 for return n; }//fin Visual Basic Private Sub OrdenarBurbuja(ByRef VectorOriginal() As Integer) Dim Temp, Longitud As Integer Longitud = VectorOriginal.Length - 2 For b = 0 To Longitud For a = 0 To Longitud If VectorOriginal(a) > VectorOriginal(a + 1) Then Temp = VectorOriginal(a + 1) VectorOriginal(a + 1) = VectorOriginal(a) VectorOriginal(a) = Temp End If Next Next End Sub PHP <?php //Ordenamiento por burbuja $numeros = array(9, 4, -1, 7, 8, 11, 6, 12, 10, 5); $n = count($numeros);
  • 9. for ($i = 1; $i<$n; $i++) { for ($j = $n-1; $j >= $i; $j--) { echo "i: $i, j: $jn"; echo "Comparando " . $numeros[$j-1] . " y " . $numeros[$j] . "n"; if ($numeros[$j-1] > $numeros[$j]) { $aux = $numeros[$j]; $numeros[$j] = $numeros[$j-1]; $numeros[$j-1] = $aux; } } } print_r($numeros); Ordenamiento por inserción De Wikipedia, la enciclopedia libre Saltar a navegación, búsqueda Ejemplo de ordenamiento por inserción ordenando una lista de números aleatorios. El ordenamiento por inserción (insertion sort en inglés) es una manera muy natural de ordenar para un ser humano, y puede usarse fácilmente para ordenar un mazo de cartas numeradas en forma arbitraria. Requiere O(n²) operaciones para ordenar una lista de n elementos. Inicialmente se tiene un solo elemento, que obviamente es un conjunto ordenado. Después, cuando hay k elementos ordenados de menor a mayor, se toma el elemento k+1 y se compara con todos los elementos ya ordenados, deteniéndose cuando se encuentra un elemento menor (todos los elementos mayores han sido desplazados una posición a la derecha). En este punto se inserta el elemento k+1 debiendo desplazarse los demás elementos. Contenido [ocultar]
  • 10. 1 Ejemplo de funcionamiento 2 Implementación o 2.1 C o 2.2 C++ o 2.3 Java o 2.4 JavaScript o 2.5 Perl o 2.6 PHP o 2.7 Pascal o 2.8 Python o 2.9 Visual Basic .NET 3 Véase también 4 Enlaces externos [editar] Ejemplo de funcionamiento En el siguiente ejemplo, 32 debe ser insertado entre 26 y 47, y por lo tanto 47, 59 y 96 deben ser desplazados. k+1 11 26 47 59 96 32 11 26 47 59 96 11 26 32 47 59 96 En la implementación computacional, el elemento k+1 va comparándose de atrás para adelante, deteniéndose con el primer elemento menor. Simultáneamente se van haciendo los desplazamientos. 11 26 47 59 96 32 11 26 47 59 96 11 26 47 59 96 11 26 47 59 96 11 26 32 47 59 96 El algoritmo en pseudocódigo (con listas que empiezan por 0) debería ser como el siguiente: algoritmo insertSort( A : lista de elementos ordenables ) para i=1 hasta longitud(A) hacer index=A[i] j=i-1 mientras j>=0 y A[j]>index hacer A[j+1] = A[j] j = j - 1 fin mientras A[j+1] = index fin para fin algoritmo
  • 11. Aunque este algoritmo tiene un mejor orden de complejidad que el de burbuja, es muy ineficiente al compararlo con otros algoritmos como quicksort. Sin embargo, para listas relativamente pequeñas el orden por inserción es una buena elección, no sólo porque puede ser más rápido para cantidades pequeñas de elementos sino particularmente debido a su facilidad de programación. [editar] Implementación A continuación se muestra el Ordenamiento por inserción en distintos lenguajes de programación: [editar] C void insertionSort(int numbers[], int array_size) { int i, a, index; for (i=1; i < array_size; i++) { index = numbers[i]; a = i-1; while (a >= 0 && numbers[a] > index) { numbers[a + 1] = numbers[a]; a--; } numbers[a+1] = index; } } [editar] C++ template <class T> void insertionSort(std::vector<T>& v, int fin) { int i, j, index; for (i=1; i <fin; i++) { index = v.at(i); j = i-1; while (j >= 0 && v.at(j)>index) { v.at(j+1)=v.at(j); j--; } v.erase(v.begin()+j+1); v.insert(v.begin()+j+1,index); } } [editar] Java public static void insertSort (int[] v) { for (int i=1; i<v.length; i++) { int aux = v[i]; int j; for (j=i-1; j>=0 && v[j]>aux; j--) v[j+1] = v[j]; v[j+1] = aux; } }
  • 12. [editar] JavaScript for (var i=1; i < vector.length; i++) { var temp = vector[i]; var j = i-1; while (j >= 0 && vector[j] > temp) { vector[j + 1] = vector[j]; j--; } vector[j+1] = temp; } [editar] Perl sub insercion { my $array = shift; # Recibimos una referencia a un array my $i; # Índice del elemento a comparar my $j; # Índice del valor mínimo a encontrar for ( $i = 1; $i < @$array; $i++ ) { my $x = $array->[$i]; # Elemento $i-ésimo # Comparamos este elemento con todos los anteriores, # hasta que lleguemos al principio de la lista o encontremos # un elemento que sea menor o igual que él. for ( $j = $i; $j > 0 and $array->[$j-1] > $x; $j-- ) { ; } # Hacemos la inserción del elemento a comparar (posición $i) en la # nueva posición encontrada (posición $j), pero sólo si son distintas # posiciones. # El uso de splice (extraer/insertar) permite que la solución sea mucho # más rápida que el movimiento de los elementos uno a uno. splice(@$array, $j, 0, splice(@$array, $i, 1)) if $i != $j; } } [editar] PHP function insert_sort($arr){ $count = count($arr); for($i=1; $i<$count; $i++){ $tmp = $arr[$i]; for ($j=$i-1; $j>=0 && $arr[$j] > $tmp; $j--) $arr[$j+1] = $arr[$j]; $arr[$j] = $tmp; } return $arr; } [editar] Pascal
  • 13. Procedure InsertionSort(var insertion:Array_integer; array_size: Integer); Var i, j, index : Integer; Begin For i := 1 to array_size do Begin index := insertion[i]; j := i-1; While ((j >= 0) AND (insertion[j] > index)) do Begin insertion[j+1] := insertion[j]; j := j - 1; End; insertion[j+1] := index; End; End; [editar] Python def insertionSort(numeros): #numeros es una lista tama = len(numeros) #creamos una variable igual al tamaño de la lista i=0 for i in range(tama): indice = numeros[i] a = i-1 while (a >= 0 and numeros[a] > indice): numeros[a+1] = numeros[a] a = a-1 numeros[a+1] = indice print numeros #imprime la lista ordenada [editar] Visual Basic .NET Private Sub insertionSort(ByVal numbers() As Integer) ' Es una función, 'debemos pasarle el array de números desde el Sub Main() Dim i, j, index As Integer i = 1 Do index = numbers(i) j = i - 1 While ((j >= 0) And (numbers(j) > index)) numbers(j + 1) = numbers(j) j = j - 1 End While numbers(j + 1) = index i = i + 1 Loop Until i > (UBound(v)) End Sub Ordenamiento Shell
  • 14. De Wikipedia, la enciclopedia libre Saltar a navegación, búsqueda El ordenamiento Shell (Shell sort en inglés) es un algoritmo de ordenamiento. El método se denomina Shell en honor de su inventor Donald Shell. Su implementación original, requiere O(n2 ) comparaciones e intercambios en el peor caso. Un cambio menor presentado en el libro de V. Pratt produce una implementación con un rendimiento de O(nlog2 n) en el peor caso. Esto es mejor que las O(n2 ) comparaciones requeridas por algoritmos simples pero peor que el óptimo O(n log n). Aunque es fácil desarrollar un sentido intuitivo de cómo funciona este algoritmo, es muy difícil analizar su tiempo de ejecución. El Shell sort es una generalización del ordenamiento por inserción, teniendo en cuenta dos observaciones: 1. El ordenamiento por inserción es eficiente si la entrada está "casi ordenada". 2. El ordenamiento por inserción es ineficiente, en general, porque mueve los valores sólo una posición cada vez. El algoritmo Shell sort mejora el ordenamiento por inserción comparando elementos separados por un espacio de varias posiciones. Esto permite que un elemento haga "pasos más grandes" 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. El último paso del Shell sort es un simple ordenamiento por inserción, pero para entonces, ya está garantizado que los datos del vector están casi ordenados. Contenido [ocultar] 1 Ejemplo 2 Secuencia de espacios 3 Implementaciones o 3.1 ActionScript o 3.2 C o 3.3 C# o 3.4 Java o 3.5 Perl o 3.6 Python o 3.7 Visual Basic 4 Referencias 5 Enlaces externos [editar] Ejemplo Considere un pequeño valor que está inicialmente almacenado en el final del vector. Usando un ordenamiento O(n2 ) como el ordenamiento de burbuja o el ordenamiento por inserción, tomará aproximadamente n comparaciones e intercambios para mover este
  • 15. valor hacia el otro extremo del vector. El Shell sort primero mueve los valores usando tamaños de espacio gigantes, de manera que un valor pequeño se moverá bastantes posiciones hacia su posición final, con sólo unas pocas comparaciones e intercambios. Uno puede visualizar el algoritmo Shell sort de la siguiente manera: coloque la lista en una tabla y ordene las columnas (usando un ordenamiento por inserción). Repita este proceso, cada vez con un número menor de columnas más largas. Al final, la tabla tiene sólo una columna. Mientras que transformar la lista en una tabla hace más fácil visualizarlo, el algoritmo propiamente hace su ordenamiento en contexto (incrementando el índice por el tamaño de paso, esto es usando i += tamaño_de_paso en vez de i++). Por ejemplo, considere una lista de números como [ 13 14 94 33 82 25 59 94 65 23 45 27 73 25 39 10 ]. Si comenzamos con un tamaño de paso de 5, podríamos visualizar esto dividiendo la lista de números en una tabla con 5 columnas. Esto quedaría así: 13 14 94 33 82 25 59 94 65 23 45 27 73 25 39 10 Entonces ordenamos cada columna, lo que nos da 10 14 73 25 23 13 27 94 33 39 25 59 94 65 82 45 Cuando lo leemos de nuevo como una única lista de números, obtenemos [ 10 14 73 25 23 13 27 94 33 39 25 59 94 65 82 45 ]. Aquí, el 10 que estaba en el extremo final, se ha movido hasta el extremo inicial. Esta lista es entonces de nuevo ordenada usando un ordenamiento con un espacio de 3 posiciones, y después un ordenamiento con un espacio de 1 posición (ordenamiento por inserción simple). El Shell sort lleva este nombre en honor a su inventor, Donald Shell, que lo publicó en 1959. Algunos libros de texto y referencias antiguas le llaman ordenación "Shell- Metzner" por Marlene Metzner Norton, pero según Metzner, "No tengo nada que ver con el algoritmo de ordenamiento, y mi nombre nunca debe adjuntarse a éste." [1] [editar] Secuencia de espacios La secuencia de espacios es una parte integral del algoritmo Shell sort. Cualquier secuencia incremental funcionaría siempre que el último elemento sea 1. El algoritmo comienza realizando un ordenamiento por inserción con espacio, siendo el espacio el primer número en la secuencia de espacios. Continua para realizar un ordenamiento por inserción con espacio para cada número en la secuencia, hasta que termina con un espacio de 1. Cuando el espacio es 1, el ordenamiento por inserción con espacio es simplemente un ordenamiento por inserción ordinario, garantizando que la lista final estará ordenada.
  • 16. La secuencia de espacios que fue originalmente sugerida por Donald Shell debía comenzar con N / 2 y dividir por la mitad el número hasta alcanzar 1. Aunque esta secuencia proporciona mejoras de rendimiento significativas sobre los algoritmos cuadráticos como el ordenamiento por inserción, se puede cambiar ligeramente para disminuir más el tiempo necesario medio y el del peor caso. El libro de texto de Weiss demuestra que esta secuencia permite un ordenamiento O(n2 ) del peor caso, si los datos están inicialmente en el vector como (pequeño_1, grande_1, pequeño_2, grande_2, ...) - es decir, la mitad alta de los números están situados, de forma ordenada, en las posiciones con índice par y la mitad baja de los números están situados de la misma manera en las posiciones con índice impar. Quizás la propiedad más crucial del Shell sort es que los elementos permanecen k- ordenados incluso mientras el espacio disminuye. Se dice que un vector dividido en k subvectores esta k-ordenado si cada uno de esos subvectores esta ordenado en caso de considerarlo aislado. Por ejemplo, si una lista fue 5-ordenada y después 3-ordenada, la lista está ahora no sólo 3-ordenada, sino tanto 5-ordenada como 3-ordenada. Si esto no fuera cierto, el algoritmo desharía el trabajo que había hecho en iteraciones previas, y no conseguiría un tiempo de ejecución tan bajo. 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), O(n3 / 2 ) (usando los incrementos de Hibbard de 2k − 1), O(n4 / 3 ) (usando los incrementos de Sedgewick de 9(4i ) − 9(2i ) + 1, o 4i + 1 + 3(2i ) + 1), o O(nlog2 n), y posiblemente mejores tiempos de ejecución no comprobados. La existencia de una implementación O(nlogn) en el peor caso del Shell sort permanece como una pregunta por resolver. [editar] Implementaciones El Shell sort se usa comúnmente en lenguajes de programación; esto es una implementación del algoritmo en C/C++ para ordenar un vector de enteros. La secuencia de incrementos usada en este ejemplo de código da un tiempo de ejecución O(n2 ) en el peor caso. [editar] ActionScript var arrayOriginal:Array = new Array(2,5,6,8,10,2,3,64,23,76,43,27,75,33,23,45,67,89); trace("Array desordenado: "+arrayOriginal); ordenamiento_shell(arrayOriginal,arrayOriginal.length); function ordenamiento_shell(arrayDesordenado:Array, tamano:uint) { var i:uint; var j:uint; var incremento:uint; var temp:uint; incremento = tamano / 2; while (incremento>0) { for (i=incremento; i<tamano; i++) {
  • 17. j = i; temp = arrayDesordenado[i]; while ((j >= incremento) && (arrayDesordenado[j-incremento] > temp)) { arrayDesordenado[j] = arrayDesordenado[j - incremento]; j = j - incremento; } arrayDesordenado[j] = temp; } incremento = incremento/2; } trace("Array ordenado: "+arrayDesordenado); } [editar] C void shell_sort(int A[], int size) { int i, j, incrmnt, temp; incrmnt = size/2; while (incrmnt > 0) { for (i=incrmnt; i < size; i++) { j = i; temp = A[i]; while ((j >= incrmnt) && (A[j-incrmnt] > temp)) { A[j] = A[j - incrmnt]; j = j - incrmnt; } A[j] = temp; } incrmnt /= 2; } } [editar] C# using System; public class ShellSorter { public void Sort(int [] list) { int j,inc; inc=list.length/2; while(inc>0) { for(int i=inc+1;i<list.length;i++) { j=i-inc; while(j>0) { if(list[j] > list[j+inc]) { Swap(list[j],list[j+inc]); j=j-inc;
  • 18. } else { j=0; } } } inc=inc/2; } } } public class MainClass { public static void Main() { int[] iArrary=new int[]{1,5,3,6,10,55,9,2,87,12,34,75,33,47}; ShellSorter sh=new ShellSorter(); sh.Sort(iArrary); for(int m=0;m<=13;m++) Console.WriteLine("{0}",iArrary[m]); } } [editar] Java public static void shellSort(int[] a) { for ( int increment = a.length / 2; increment > 0; increment = (increment == 2 ? 1 : (int) Math.round(increment / 2.2))) { for (int i = increment; i < a.length; i++) { for (int j = i; j >= increment && a[j - increment] > a[j]; j -= increment) { int temp = a[j]; a[j] = a[j - increment]; a[j - increment] = temp; } } } } [editar] Perl sub shellsort { my $array = shift; # Recibimos una referencia a un array my $i; # Índice del elemento a comparar my $j; # Índice del elemento actual a comparar my $shell; # Tamaño del incremento # Calculamos el valor del incremento for ( $shell = 1; $shell < @$array; $shell = 2 * $shell + 1 ) { ; } do { $shell = int( ( $shell - 1 ) / 2 ); # Para todos los elementos, elegidos con un incremento
  • 19. for ( $i = $shell; $i < @$array; $i++ ) { for ( $j = $i - $shell; $j >= 0 && $array->[ $j ] > $array->[ $j + $shell ]; $j -= $shell ) { # Intercambiamos valores @$array[ $j, $j + $shell ] = @$array[ $j + $shell, $j ]; } } } while $shell > 1; } [editar] Python def shellsort(a): def new_increment(a): i = int(len(a) / 2) yield i while i<>1: if i==2: i = 1 else: i = int(round(i/2.2)) yield i for increment in new_increment(a): for i in range(increment, len(a)): for j in range(i, increment-1, -increment): if a[j-increment] < a[j]: break a[j],a[j-increment] = a[j - increment],a[j] return a [editar] Visual Basic Sub Shell_Sort(ByRef V) 'debemos pasarle el arreglo(de enteros) desde el programa principal() Dim I, Medio, J, Temp As Integer Dim Ordenado As Boolean Medio = UBound(V) While (Medio > 0) Medio = Medio 2 Do Ordenado = True For J = 0 To UBound(V) - Medio ' se asume que el arreglo va de 0 a UBound(V) elementos I = J + Medio If V(J) > V(I) Then ' Se intercambian los elementos Temp = V(J) V(J) = V(I) V(I) = Temp Ordenado = False End If Next Loop Until Ordenado Wend End Sub
  • 20. Sub principal() Dim Arr(99) As Integer Dim I As Integer For I = 0 To 99 Arr(I) = Int(Rnd() % 1000) ' Se llena el arreglo con números menores que 1000 Next I Call Shell_Sort(Arr) End Sub Quicksort De Wikipedia, la enciclopedia libre (Redirigido desde Ordenamiento rápido) Saltar a navegación, búsqueda Quicksort en acción sobre una lista de números aleatorios. Las líneas horizontales son valores pivote. El ordenamiento rápido (quicksort en inglés) es un algoritmo basado en la técnica de divide y vencerás, que permite, en promedio, ordenar n elementos en un tiempo proporcional a n log n. Contenido [ocultar] 1 Descripción del algoritmo o 1.1 Demostración 2 Optimización del algoritmo o 2.1 Técnicas de elección del pivote o 2.2 Técnicas de reposicionamiento o 2.3 Transición a otro algoritmo 3 Ejemplo 4 Implementaciones 5 Véase también 6 Referencias
  • 21. [editar] Descripción del algoritmo El algoritmo fundamental es el siguiente: Elegir un elemento de la lista de elementos a ordenar, al que llamaremos pivote. Resituar los demás elementos de la lista a cada lado del pivote, de manera que a un lado queden todos los menores que él, y al otro los mayores. Los elementos iguales al pivote pueden ser colocados tanto a su derecha como a su izquierda, dependiendo de la implementación deseada. En este momento, el pivote ocupa exactamente el lugar que le corresponderá en la lista ordenada. La lista queda separada en dos sublistas, una formada por los elementos a la izquierda del pivote, y otra por los elementos a su derecha. Repetir este proceso de forma recursiva para cada sublista mientras éstas contengan más de un elemento. Una vez terminado este proceso todos los elementos estarán ordenados. Como se puede suponer, la eficiencia del algoritmo depende de la posición en la que termine el pivote elegido. En el mejor caso, el pivote termina en el centro de la lista, dividiéndola en dos sublistas de igual tamaño. En este caso, el orden de complejidad del algoritmo es O(n·log n). En el peor caso, el pivote termina en un extremo de la lista. El orden de complejidad del algoritmo es entonces de O(n²). El peor caso dependerá de la implementación del algoritmo, aunque habitualmente ocurre en listas que se encuentran ordenadas, o casi ordenadas. 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. En el caso promedio, el orden es O(n·log n). No es extraño, pues, que la mayoría de optimizaciones que se aplican al algoritmo se centren en la elección del pivote. [editar] Demostración Podríamos probar el orden de ejecución en el mejor caso de la siguiente manera: Vamos a suponer que el número total de elementos a ordenar es potencia de dos, es decir, n = 2k . de aquí podemos ver que k = log2(n), donde k es el número de divisiones que realizará el algoritmo. En la primera fase del algoritmo habrán n comparaciones, en la segunda fase el algoritmo creará dos sublistas aproximadamente de tamaño n/2. El número total de comparaciones de estas dos sublistas es: 2(n/2) = n. En la tercera fase el algoritmo
  • 22. procesará 4 sublistas más, por tanto el número total de comparaciones en esta fase es 4(n/4) = n. En conclusión, el número total de comparaciones que hace el algoritmo es: n + n + n + ..... + n = kn, donde k = log2(n), por tanto el tiempo de ejecución del algoritmo en el mejor caso es O(n.log2n) [editar] Optimización del algoritmo Cabe destacar que de usarse en su versión recursiva las siguientes optimizaciones y sus desventajas no se ven vistas en el tiempo de ejecución del mismo manteniéndose, así el tiempo de ejecución planteado en un principio. [editar] Técnicas de elección del pivote El algoritmo básico del metodo Quicksort consiste en tomar cualquier elemento de la lista al cual denominaremos como pivote, dependiendo de la partición en 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. Otra opción puede ser recorrer la lista para saber de antemano qué elemento ocupará la posición central de la lista, para elegirlo como pivote. Esto puede hacerse en O(n) y asegura que hasta en el peor de los casos, el algoritmo sea O(n·log n). No obstante, el cálculo adicional rebaja bastante la eficiencia del algoritmo en el caso promedio. La opción a medio camino es tomar tres elementos de la lista - por ejemplo, el primero, el segundo, y el último - y compararlos, eligiendo el valor del medio como pivote. [editar] Técnicas de reposicionamiento Una idea preliminar para ubicar el pivote en su posición final sería contar la cantidad de elementos menores que él, y colocarlo un lugar más arriba, moviendo luego todos esos elementos menores que él a su izquierda, para que pueda aplicarse la recursividad. Existe, no obstante, un procedimiento mucho más efectivo. Se utilizan dos índices: i, al que llamaremos índice izquierdo, y j, al que llamaremos índice derecho. El algoritmo es el siguiente: 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). Cuando lista[i] sea mayor que el pivote y lista[j] sea menor, se intercambian los elementos en esas posiciones. Repetir esto hasta que se crucen los índices.
  • 23. El punto en que se cruzan los índices es la posición adecuada para colocar el pivote, porque sabemos que a un lado los elementos son todos menores y al otro son todos mayores (o habrían sido intercambiados). [editar] Transición a otro algoritmo Como se comentó antes, el algoritmo quicksort ofrece un orden de ejecución O(n²) para ciertas permutaciones "críticas" de los elementos de la lista, que siempre surgen cuando se elige el pivote «a ciegas». La permutación concreta depende del pivote elegido, pero suele corresponder a secuencias ordenadas. Se tiene que la probabilidad de encontrarse con una de estas secuencias es inversamente proporcional a su tamaño. Los últimos pases de quicksort son numerosos y ordenan cantidades pequeña de elementos. Un porcentaje medianamente alto de ellos estarán dispuestos de una manera similar al peor caso del algoritmo, volviendo a éste ineficiente. Una solución a este problema consiste en ordenar las secuencias pequeñas usando otro algoritmo. Habitualmente se aplica el algoritmo de inserción para secuencias de tamaño menores de 8-15 elementos. Pese a que en secuencias largas de elementos la probabilidad de hallarse con una configuración de elementos "crítica" es muy baja, esto no evita que sigan apareciendo (a veces, de manera intencionada). El algoritmo introsort es una extensión del algoritmo quicksort que resuelve este problema utilizando heapsort en vez de quicksort cuando el número de recursiones excede al esperado. Parámetros: o Se debe llamar a la función Quicksort desde donde quiera ejecutarse o Ésta llamará a colocar pivote para encontrar el valor del mismo o Se ejecutará el algoritmo Quicksort de forma recursiva a ambos lados del pivote int colocar(int *v, int b, int t) { int i; int pivote, valor_pivote; int temp; pivote = b; valor_pivote = v[pivote]; for (i=b+1; i<=t; i++){ if (v[i] < valor_pivote){ pivote++; temp=v[i]; v[i]=v[pivote]; v[pivote]=temp; } } temp=v[b]; v[b]=v[pivote]; v[pivote]=temp; return pivote; }
  • 24. void Quicksort(int* v, int b, int t) { int pivote; if(b < t){ pivote=colocar(v, b, t); Quicksort(v, b, pivote-1); Quicksort(v, pivote+1, t); } } Nota: Los tres parámetros de la llamada inicial a Quicksort serán array[0], 0, numero_elementos -1, es decir, si es un array de 6 elementos array[0], 0, 5 [editar] Ejemplo En el siguiente ejemplo se marcan el pivote y los índices i y j con las letras p, i y j respectivamente. Comenzamos con la lista completa. El elemento pivote será el 4: 5 - 3 - 7 - 6 - 2 - 1 - 4 p Comparamos con el 5 por la izquierda y el 1 por la derecha. 5 - 3 - 7 - 6 - 2 - 1 - 4 i j p 5 es mayor que 4 y 1 es menor. Intercambiamos: 1 - 3 - 7 - 6 - 2 - 5 - 4 i j p Avanzamos por la izquierda y la derecha: 1 - 3 - 7 - 6 - 2 - 5 - 4 i j p 3 es menor que 4: avanzamos por la izquierda. 2 es menor que 4: nos mantenemos ahí. 1 - 3 - 7 - 6 - 2 - 5 - 4 i j p 7 es mayor que 4 y 2 es menor: intercambiamos.
  • 25. 1 - 3 - 2 - 6 - 7 - 5 - 4 i j p Avanzamos por ambos lados: 1 - 3 - 2 - 6 - 7 - 5 - 4 iyj p En este momento termina el ciclo principal, porque los índices se cruzaron. Ahora intercambiamos lista[i] con lista[sup] (pasos 16-18): 1 - 3 - 2 - 4 - 7 - 5 - 6 p Aplicamos recursivamente a la sublista de la izquierda (índices 0 - 2). Tenemos lo siguiente: 1 - 3 - 2 1 es menor que 2: avanzamos por la izquierda. 3 es mayor: avanzamos por la derecha. Como se intercambiaron los índices termina el ciclo. Se intercambia lista[i] con lista[sup]: 1 - 2 - 3 El mismo procedimiento se aplicará a la otra sublista. Al finalizar y unir todas las sublistas queda la lista inicial ordenada en forma ascendente. 1 - 2 - 3 - 4 - 5 - 6 - 7 [editar] Implementaciones El algoritmo de ordenamiento rápido (Quicksort) en: Pseudocódigo function quicksort(array) var list, less, greater if length(array) ≤ 1 return array seleccionar y eliminar un valor pivote pivot en el array for each x in array if x < pivot then añadir x a less else añadir x a greater return concadenar(quicksort(less), pivot, quicksort(greater)) C
  • 26. int pivotar (int v[], int izq, int der) { int posicionPivote = (izq + der) / 2; int valorPivote = v[posicionPivote]; int indiceAlmacenamiento; swap (v, posicionPivote, der);//Se situal pivote al final del vector indiceAlmacenamiento = izq; for (int indiceLectura = izq; indiceLectura < der; indiceLectura++){ if (v[indiceLectura] <= valorPivote){ swap (v, indiceLectura, indiceAlmacenamiento); indiceAlmacenamiento++; } } swap (v, indiceAlmacenamiento, der); //Se coloca el pivote en su lugar. return indiceAlmacenamiento; } void quicksort (int v[], int izq, int der) { int pivote; if(izq < der){ pivote = pivotar (v, izq, der); //Esta operación coloca el pivote en su lugar. quicksort(v, izq, pivote-1); quicksort(v, pivote+1, der); } } Otra en C. Trabaja sólo con punteros (no índices). Ordena enteros de menor a mayor. Pivot: El primero del vector. void quicksort(int* izq, int* der) /*Se llama con: quicksort(&vector[0],&vector[n-1]);*/ { if(der<izq) return; int pivot=*izq; int* ult=der; int* pri=izq; while(izq<der) { while(*izq<=pivot && izq<der+1) izq++; while(*der>pivot && der>izq-1) der--; if(izq<der) swap(izq,der); } swap(pri,der); quicksort(pri,der-1); quicksort(der+1,ult); } void swap(int* a, int* b) { int temp=*a; *a=*b;
  • 27. *b=temp; } Java //Recibe un vector de enteros y el índice del primer y último elemento válido del mismo void ordenarQuicksort(int[] vector, int primero, int ultimo){ int i=primero, j=ultimo; int pivote=vector[(primero + ultimo) / 2]; int auxiliar; do{ while(vector[i]<pivote) i++; while(vector[j]>pivote) j--; if (i<=j){ auxiliar=vector[j]; vector[j]=vector[i]; vector[i]=auxiliar; i++; j--; } } while (i<=j); if(primero<j) ordenarQuicksort(vector,primero, j); if(ultimo>i) ordenarQuicksort(vector,i, ultimo); } C# void Quicksort(int[] v, int prim, int ult) { if (prim < ult) { /* Selecciona un elemento del vector y coloca los menores que él a su izquierda y los mayores a su derecha */ int p = Pivote(v, prim, ult, ult); /* Repite el proceso para cada una de las particiones generadas en el paso anterior */ Quicksort(v, prim, p - 1); Quicksort(v, p + 1, ult); } } /* Implementación no clásica de la función Pivote. En lugar de recorrer el vector simultáneamente desde ambos extremos hasta el cruce de índices, se recorre desde el comienzo hasta el final */ int Pivote(int[] v, int prim, int ult, int piv) { int p = v[piv]; int j = prim; // Mueve el pivote a la última posición del vector Intercambia(v, piv, ult);
  • 28. /* Recorre el vector moviendo los elementos menores o iguales que el pivote al comienzo del mismo */ for (int i = prim; i < ult; i++) { if (v[i] <= p) { Intercambia(v, i, j); j++; } } // Mueve el pivote a la posición que le corresponde Intercambia(v, j, ult); return j; } void Intercambia(int[] v, int a, int b) { if (a != b) { int tmp = v[a]; v[a] = v[b]; v[b] = tmp; } } Python def quicksort(datos, primero, ultimo): i = primero j = ultimo pivote = (datos[primero] + datos[ultimo]) / 2 while i < j: while datos[i] < pivote: i+=1 while datos[j] > pivote: j-=1 if i <= j: aux = datos[i] datos[i] = datos[j] datos[j] = aux i+=1 j-=1 if primero < j: datos = quicksort(datos, primero, j) if ultimo > i: datos = quicksort(datos, i, ultimo) return datos Otra en Python def qsort(list): try: x=list.pop() except: return []
  • 29. return qsort(filter((lambda y: y<x), list)) + [x] + qsort(filter((lambda y: y>=x), list)) Haskell qsort :: Ord a => [a] -> [a] qsort [] = [] qsort (x:xs) = qsort (filter (< x) xs) ++ [x] ++ qsort (filter (>= x) xs) Otra en Haskell qsort :: Ord a => [a] -> [a] qsort [] = [] qsort (x:xs) = qsort elmts_lt_x ++ [x] ++ qsort elmts_greq_x where elmts_lt_x = [y | y <- xs, y < x] elmts_greq_x = [y | y <- xs, y >= x] Asm quicksort: push ebp mov ebp,esp push esi push ebx push ecx push edx mov ebx,dword[ebp + 12] mov ecx,dword[ebp + 16] cdq mov eax, ebx add eax, ecx push ecx mov ecx,2 div ecx pop ecx xchg edx,eax mov esi, [ebp + 8] mov edx,dword[esi + edx * 4] qs@L1: qs@L1@L1: cmp dword[esi + ebx * 4],edx jge qs@L1@L1@out inc ebx jmp qs@L1@L1 qs@L1@L1@out: qs@L1@L2: cmp dword[esi + ecx * 4],edx jle qs@L1@L2@out dec ecx jmp qs@L1@L2 qs@L1@L2@out: qs@L1@IF1: cmp ebx, ecx jg qs@L1@IF1@out mov eax, dword[esi + ebx * 4] xchg eax, dword[esi + ecx * 4] mov dword[esi + ebx * 4], eax
  • 30. inc ebx dec ecx qs@L1@IF1@out: cmp ebx,ecx jle qs@L1 qs@L1@out: qs@IF1: cmp dword[ebp + 12],ecx jge qs@IF1@out push ecx push dword[ebp + 12] push esi call quicksort qs@IF1@out: qs@IF2: cmp ebx, dword[ebp + 16] jge qs@IF2@out push dword[ebp + 16] push ebx push esi call quicksort qs@IF2@out: pop edx pop ecx pop ebx pop esi pop ebp retn 12 Prolog quicksort([], []). quicksort([CABEZA | COLA], ORDENADO) :- partir(CABEZA, COLA, IZDA, DCHA), quicksort(IZDA, ORDENADO_IZDA), quicksort(DCHA, ORDENADO_DCHA), concatenar(ORDENADO_IZDA, [CABEZA | ORDENADO_DCHA], ORDENADO). partir(PIVOTE, [], [], []). partir(PIVOTE, [CABEZA | COLA], [CABEZA | IZDA], DCHA) :- CABEZA @=< PIVOTE, partir(PIVOTE, COLA, IZDA, DCHA). partir(PIVOTE, [CABEZA | COLA], IZDA, [CABEZA | DCHA]) :- CABEZA @> PIVOTE, partir(PIVOTE, COLA, IZDA, DCHA). concatenar([], LISTA, LISTA). concatenar([CABEZA | LISTA_1], LISTA_2, [CABEZA | LISTA_3]) :- concatenar(LISTA_1, LISTA_2, LISTA_3).