Preliminares Del Analisis Del Problema de Sorting v1.0
Preliminares Del Analisis Del Problema de Sorting v1.0
Preliminares Del Analisis Del Problema de Sorting v1.0
Apuntes de Teórico
PROGRAMACIÓN 3
Complejidad
Versión 1.0
Apuntes de Teórico de Programación 3 – Complejidad
Apuntes de Teórico de Programación 3 – Complejidad
Índice
Reformulando:
Sea el problema P del que se quiere estudiar la complejidad. Existe un conjunto
A = {A1, A2, …, An} de algoritmos que brindan una solución al problema P. Sea
T el conjunto de tiempos (en el peor caso) para cada algoritmo, T = {T1, T2, …,
Tn} (siendo Twi el peor caso para el algoritmo Ai) .
Al buscar la función F, se debe procurar además que sea lo mayor posible (entre
todas las posibles cotas inferiores).
Tiempos de ejecución
35
30
25
20
T(n)
15
10
0
1 2 3 4 5
n
FA(n) = n-1
Apuntes de Teórico de Programación 3 – Complejidad
La especificación queda:
Entrada: Secuencia S a ordenar
Salida: Secuencia R ordenada
Proceso
R = Crear()
Mientras NOT Vacia(S) hacer
R = InsBack(R, Minimo(S))
S = DeleteMin(S)
Fin Mientras
Devolver R
Una implementación
Se utilizará la opción de implementar la secuencia y el resultado ordenado sobre
un único arreglo A de n elementos. El arreglo se considerará dividido en dos
partes, la izquierda contendrá la parte ordenada, la derecha contendrá la parte
desordenada. En cada paso se buscará el menor elemento de la desordenada y se
intercambiará con el primer elemento de ésta, creciendo así la parte ordenada y
decreciendo la desordenada (en tamaño).
Apuntes de Teórico de Programación 3 – Complejidad
j =n−1 i =n−2
i =n−2 i =n−2 i =n−2
T ( n) = ∑ ∑ ∑
(1) = (n − i − 1 ) = ∑ ( n − 1) − ∑ (i )
i =0 j =i +1 i =0 i =0 i =0
(n − 1).(n − 2) 2n 2 − 4n + 2 − n 2 + 3n − 2 n 2 − n
= (n − 1) − = =
2
2 2 2
n(n − 1)
⇒ T ( n) = ⇒ T ( n) ∈ Ο( n 2 )
2
Introducción
La idea es modelar todas las posibles ejecuciones del algoritmo cualquiera sea la
secuencia de entrada. Su construcción será como una ejecución “a mano” del
algoritmo dibujando un árbol binario.
Cada nodo del árbol corresponderá a una comparación de elementos A[j] <
A[posmin]; esto se hará desde el comienzo de la ejecución del algoritmo, con
los valores iniciales de j y posmin. Se tendrán dos resultados posibles según la
respuesta a la comparación, en cada caso se adecuará el arreglo según lo que
indica el algoritmo y se volverá a realizar lo anterior con los nuevos valores de j
y posmin, agregando los nodos correspondientes a las comparaciones. Al
terminar con las comparaciones se colocarán como hojas del árbol (nodos
externos) rectángulos con los elementos ordenados.
Construcción
A continuación se verá el árbol de decisión para este algoritmo en un ejemplo
para n=3.
Inicialmente se tiene que en el arreglo vienen dados 3 elementos con valores a, b
y c en las posiciones A0, A1 y A2 respectivamente.
En el árbol los óvalos representan las comparaciones, los rectángulos coloreados
son las diferentes variaciones de A, agregándose además los valores de i,
posmin y j en los distintos pasos.
Apuntes de Teórico de Programación 3 – Complejidad
Esta primer figura muestra el árbol parcial con su rama de más a la derecha:
inicialmente se tiene que el primer nodo (raiz) realiza la comparación A[1] <
A[0], esto se debe a que j = 1 y posmin = i = 0. Notar que ésta comparación
equivale a comparar los elementos de la secuencia a y b: ¿ a < b ? ya que el
arreglo inicial es [abc].
Si esta comparación da verdadero, se toma a la derecha en el árbol, el valor de
posmin cambia a 1 y el de j a 2 (ver algoritmo). En estas condiciones continúa
el ciclo (2), la comparación es entre los elementos 2 y 1 de A (¿c < b? ). Si la
respuesta es afirmativa, se cambia posmin al valor de j que es 2, termina el
ciclo (2) y se realiza el intercambio, ya se encontró el mínimo que está en la
posición 2, o sea que c es el menor elemento y se cambia al primer lugar (i = 0).
Notar que c no se accederá más, es el primer elemento de la parte ordenada del
arreglo.
Comienza un nuevo ciclo (1) con i=1, entonces posmin=1 y j=2. La
siguiente comparación es entre los elementos 2 y 1 del arreglo (ya modificado) o
sea ¿a < b?. Si la comparación da verdadero, entonces posmin = 2, termina el
ciclo (2), se hace el intercambio quedando [cab] y el algoritmo termina, [cab]
será la ordenación final. Si la respuesta es falso, el intercambio mantiene el
elemento en su lugar y la secuencia final ordenada será [cba].
Apuntes de Teórico de Programación 3 – Complejidad
Esta cuarta figura muestra la rama de más a la izquierda del árbol que
corresponde a todas respuestas negativas. Con respecto al caso anterior implica
volver un paso atrás y considerar el caso en que la segunda comparación dio
negativo. En ese caso no cambia posmin (como siempre que la respuesta a la
comparación sea negativa). El mínimo entonces es a, que se cambiará al primer
lugar (en realidad el intercambio lo deja en el mismo lugar). El arreglo queda
como el inicial [abc]. Comienza otra iteración de (1) posmin=i=1, j=2 y se
comparará el elemento 2 con el 1. Si la respuesta es afirmativa, posmin=2, se
intercambia, termina el algoritmo resultando la secuencia ordenada [acb]. Si la
respuesta es negativa, posmin no cambia, el intercambio deja el elemento en el
mismo lugar quedando la secuencia ordenada [abc], la cual corresponde al caso
en que la secuencia inicial ya venía ordenada.
Apuntes de Teórico de Programación 3 – Complejidad
Nota:
El nodo 8 no puede darse nunca. La primer comparación (¿b < a?) resulta
afirmativa, entonces no puede resultar afirmativa la última comparación que
lleva a que a sea menor que b.
Los nodos externos 3 y 7 representan [cba] en ambos casos, pero en el nodo 7 se
representan los casos donde b<a y el caso del nodo 3 sólo puede representar los
casos donde a=b (por construcción). Si no se admiten repetidos, el caso del nodo
3 no puede darse nunca (por las comparaciones anteriores como en el caso del
nodo 8).
Apuntes de Teórico de Programación 3 – Complejidad
Proceso
R = Crear()
Mientras NOT Vacia(S) hacer
R = InsEnOrden(R, Primero(S))
S = Resto(S)
Fin Mientras
Devolver R
Una implementación
Como en el caso de Selection Sort, se utilizará un algoritmo que reciba la
secuencia en un arreglo de n elementos y proceda a ordenar con esta estrategia
sobre el mismo arreglo. Para ello se considerará el arreglo dividido
conceptualmente en dos partes, una, la de más a la izquierda (o de menores
índices) ya ordenada y el resto será la secuencia desordenada. La idea consiste
en tomar el primer elemento de la parte desordenada e irlo desplazando a la
izquierda hasta insertarlo en su lugar. Para ello se deberá al mismo tiempo
desplazar a la derecha los elementos mayores a él que forman la parte ordenada
de manera de hacer lugar en el arreglo para ese elemento a insertar.
En el algoritmo siguiente se recibe el arreglo A, se usan las variables: First para
ubicar transitoriamente el primer elemento de la parte desordenada, o sea el
elemento a insertar en la parte ordenada, i para indicar la posición de comienzo
de la parte desordenada y j para buscar la ubicación de First en la parte ya
ordenada (desde i-1 a la izquierda).
Apuntes de Teórico de Programación 3 – Complejidad
En este caso no se verá en la forma detallada del caso del Selection Sort, en la
figura se muestra el árbol final que ilustra o modela todas las ejecuciones
posibles del Insertion Sort.
Se seguirá paso a paso sólo la rama derecha del árbol:
Apuntes de Teórico de Programación 3 – Complejidad