Documentos de Académico
Documentos de Profesional
Documentos de Cultura
Clase 3: Ordenamiento IV
Instructor: Diego Villamizar
3.1. Costo
Correctitud
Como es bien sabido un algoritmo son una serie de pasos conectados entre sí, que dada
una entrada producen una salida acorde a la solución de algún problema particular. Si
el algoritmo no resuelve el problema, simplemente no es considerado como tal.
Eciencia
Hay ciertos requerimientos que un algoritmo debe cumplir dado el problema que quiere
resolver. Si, por ejemplo, usted crea un algoritmo que resuelve un problema, pero el
algoritmo requiere mucha más memoria de la cual usted dispone, no podrá correr el
algoritmo y eso hará que no tenga sentido el mismo. Así mismo, si un algoritmo es
correcto pero demora mucho más tiempo del que se dispone, no tiene sentido correrlo.
Eso lleva a que sea útil entender y clasicar, en términos de requerimientos, lo que
cuesta un algoritmo.
En esta clase tendremos más en cuenta el tiempo que el espacio y cualquier otro requer-
imiento de eciencia, para eso supondremos que las operaciones elementales dentro de un
código cuestan una constante de tiempo cualquiera y será representada como comentario en
cada linea que se necesite en el código.
Veamos el siguiente código.
1 for i in range (0,n): # c_1
2 for j in range (0,n): #c_2
3 print " * ", #c_3
4 print "" #c_4
o su correspondiente en Java (sin la construcción usual de main y clase)
1 for(int i = 0;i<n;i++, System .out. println (""))//#c_1 c_2
2 for(int j = 0;j<n;j++) System .out. print (" * ");//#c_3 c_4
1
2 Clase 3: Ordenamiento IV
Luego si quisiera ver cuánto se tarda el algoritmo en términos de los tiempos constantes y
la entrada n, tendría que resolver lo siguiente
n−1
X n−1
X
(c1 + (c2 + c3 ) + c4 ).
i=0 j=0
Lo que dice que ese algoritmo corre proporcional a un tiempo cuadrático(n2 ) sobre la variable
n que le entre.
Consideremos ahora el siguiente código:
1 for i in range (0,n): # c_1
2 for j in range (0,i): #c_2
3 print " * ", #c_3
4 print "" #c_4
o su correspondiente en Java (sin la construcción usual de main y clase)
1 for(int i = 0;i<n;i++, System .out. println (""))//#c_1 c_2
2 for(int j = 0;j<i;j++) System .out. print (" * ");//#c_3 c_4
Si se hace el mismo análisis, se llegaría a una expresión como
n−1
X i−1
X
(c1 + (c2 + c3 ) + c4 ),
i=0 j=0
4 4
2 2
3 3
5 5
3 3
Figura 3.1: La echa negra es el apuntador a la primera carta en la mano roja, de desorde-
nadas. La linea roja y la verde representan las cartas en su respectivas manos. Se ven los dos
primeros pasos en las dos primeras cartas, ya ordenadas
4 4
2 2
3 5
5 3
3 3
4 4
2 5
5 3
3 3
3 2
4 5
5 4
3 3
3 3
2 2
De esa forma, es fácil notar que tenermos que llevar un apuntador para la echa negra,
que sea la carta a poner en la mano verde. Ese puntero, como va secuencial, lo podemos
llevar con la estructura de control for. Además de eso, necesitamos una estructura de control
que nos permita hacer el movimiento de las cartas, que se hace mientras que el apuntador
sea menor que la carta en otro apuntador en la mano verde.
1 X = [34 ,2 ,4 ,3 ,6 ,3 ,56 ,6 ,7 ,4 ,5 ,7 ,4]
2 print X
3 for i in range (1, len(X)): #apuntador negro
4 k = X[i]
5 j = i−1;
6 while j>−1 and k<X[j]: #i r corriendo l a s cartas en la mano verde .
7 X[j+1]=X[j]
8 j−=1
9 X[j+1]=k #poner la carta apuntada
10 print X
Ahora que se tiene el algoritmo, es interesante ver qué costo en tiempo tiene. Para eso
Algoritmo de Inserción 5
Inv(312) = {(1, 2), (1, 3)}, Inv(321) = {(1, 2), (1, 3), (2, 3)}.
Dada esa estadística, podemos preguntarnos cuál es el valor esperado de las veces que
el algoritmo entrará en el while dado un arreglo de longitud n.
que es lo mismo que denir una distribución en el conjunto de permutaciones (i.e., Sn ),
para
P eso denimos Ai,n = |{σ ∈ Sn : |Inv(σ)| = i}|,luego por el principio de la suma
i∈[(n)] Ai,n = 1. Luego el valor esperado sería
1
n! 2
(n2 )
X
Ai,n ∗ i.
i=0
6 Clase 3: Ordenamiento IV