Está en la página 1de 41

TEMA 2

LA EFICIENCIA DE
LOS ALGORITMOS

Departamento de Lenguajes y Sistemas Informáticos

UNIVERSIDAD DE ALICANTE

La eficiencia de los algoritmos


OBJETIVOS

„ Proporcionar la capacidad para analizar con rigor la eficiencia


de los algoritmos
… Distinguir los conceptos de eficiencia en tiempo y en espacio
… Introducir las bases matemáticas para poder aplicar el criterio
asintótico a los conceptos de eficiencia
… Calcular la complejidad temporal o espacial de un algoritmo
recursivo o iterativo
… Comparar, respecto a eficiencia, distintas soluciones algorítmicas
a un mismo problema

1
La eficiencia de los algoritmos
CONTENIDO

1. Noción de complejidad
2. Cotas de complejidad
3. Análisis asintótico
4. Cálculo de complejidades
… Algoritmos Iterativos
… Algoritmos Recursivos. Ecuaciones de recurrencia
5. Anexo

1. Noción de complejidad
¿QUÉ ES UN ALGORITMO?

„ Un algoritmo es una serie finita de pasos que expresa una forma


o estrategia de resolución de un problema.
„ Importante:
… El número de pasos debe ser finito. El algoritmo debe terminar en
un tiempo finito.
… El algoritmo debe ser capaz de determinar la solución del
problema. Se trata de un método sistemático, susceptible de ser
realizado mecánicamente, para resolver un problema dado.

2
1. Noción de complejidad
DEFINICIÓN

„ Complejidad de un algoritmo
… Medida de los recursos que un algoritmo necesita para su
ejecución
… Complejidad temporal: Tiempo que un algoritmo necesita para su
ejecución
… Complejidad espacial: Recursos espaciales (de almacén) que un
algoritmo consume o necesita para su ejecución
„ Posibilidad de hacer
… Valoraciones: el algoritmo A es “bueno”, “el mejor”, “prohibitivo”
… Comparaciones: el algoritmo A es mejor que el B
„ Nos centraremos en el estudio de la complejidad temporal

1. Noción de complejidad
COMPLEJIDAD TEMPORAL

„ El tiempo de ejecución de un algoritmo depende de:


… Factores externos
„ La máquina en la que se va a ejecutar
„ El compilador
„ La experiencia del programador
„ Los datos de entrada suministrados en cada ejecución
… Internos
„ El número de instrucciones asociadas al algoritmo
„ ¿Cómo estudiamos el tiempo de ejecución de un algoritmo?

3
1. Noción de complejidad
¿CÓMO ESTUDIAMOS EL TIEMPO DE EJECUCIÓN?

„ Análisis empírico (a posteriori):


… Generando ejecuciones del algoritmo para distintos valores de entrada y
cronometrando el tiempo de ejecución
J Se obtiene una medida real del comportamiento del algoritmo en el entorno de
aplicación
L El resultado depende de los factores externos e internos
„ Análisis analítico (a priori):
… Obtener una función que represente el tiempo de ejecución del algoritmo
para cualquier valor de entrada
J El resultado depende sólo de los factores internos
J Estima el comportamiento del algoritmo de forma independiente de los
factores externos
J No es necesario implementar y ejecutar los algoritmos
L No obtiene una medida real del comportamiento del algoritmo en el entorno de
aplicación
„ Ambas medidas son importantes
7

1. Noción de complejidad
¿CÓMO ESTUDIAMOS EL TIEMPO DE EJECUCIÓN?

„ Se expresa mediante funciones de coste.


… Permiten determinar el comportamiento de un algoritmo para cualquier
entrada posible.
… Las entradas se expresan mediante lo que denominamos talla, tamaño
de la entrada o tamaño del problema.
„ Talla o tamaño de un problema:
… Valor o conjunto de valores asociados a la entrada del problema que
representa una medida de su tamaño respecto de otras entradas
posibles
„ Denotaremos T(n) al tiempo de ejecución de un algoritmo para una
entrada de tamaño n.

4
1. Noción de complejidad
¿CÓMO ESTUDIAMOS EL TIEMPO DE EJECUCIÓN?

„ ¿Qué unidad de medida empleamos para T(n)?


… ¿segundos? No existe unidad concreta
… No existe ordenador de referencia para estas medidas
„ El principio de Invarianza
… Dado un algoritmo y dos implementaciones I1 e I2 (máquinas o códigos
distintos) que tardan en ejecutarse T1(n) y T2(n) , entonces

∃c ∈ \ + , ∃n0 ∈ ` / ∀n ≥ n0 T1 ( n) ≤ c·T2 ( n)

… Es decir, el tiempo de ejecución de dos implementaciones distintas de un


algoritmo dado va a diferir como mucho en una constante multiplicativa
… Por tanto podemos decir que un algoritmo tarda un tiempo del orden de
T(n) si ∃c ∈ \ + y una implementación I del algoritmo que tarda menos
que c ·T(n) para cualquier entrada de tamaño n

1. Noción de complejidad
¿CÓMO ESTUDIAMOS EL TIEMPO DE EJECUCIÓN?

„ ¿Unidad en función del tipo de análisis?


… Análisis empírico (a posteriori):
„ Emplearemos los segundos siempre que se particularice el estudio a la
ejecución de una implementación concreta de un algoritmo en una máquina
determinada
… Análisis analítico (a priori):
„ Necesitamos definir una unidad de medida teórica, independiente de factores
externos
„ Se define una unidad de medida (operación elemental o paso de programa)
„ El tiempo de un algoritmo se puede así medir como el número de pasos de
programa que realiza para una entrada dada.

10

5
1. Noción de complejidad
CONSIDERACIONES

„ ¿Porqué es importante conocer el coste de ejecución de los


algoritmos?
„ ¿Porqué se emplean funciones de coste para expresar el coste de
un algoritmo?
„ ¿Cómo definimos un paso de programa u operación elemental?
¿Cómo lo identificamos en un algoritmo?

11

1. Noción de complejidad
CONSIDERACIONES

„ ¿Porqué es importante conocer el coste de ejecución de los


algoritmos?
„ Ejemplo: El cuadrado de un número concreto (1000)

1 Paso de programa = 1operación simple


funcion Cuad1():entero;
devuelve(1000*1000); // 2 //
fin /* 2 */
funcion Cuad2():entero;
m=0; // 1 //
para i=1 hasta 1000 // 1001+1001 // Número total
m=m+1000; // 1000+1000 // de operaciones
fpara
devuelve(m); // 1 //
fin /* 4004 */

• Diferente coste según algoritmo


• Todos coste constante
12

6
1. Noción de complejidad
CONSIDERACIONES

„ ¿Porqué se emplean funciones de coste para expresar el coste de un


algoritmo?
… Necesitamos que la expresión del coste del algoritmo sea válida para
cualquier entrada al mismo (se expresa en función de su talla)
„ Ejemplo: El cuadrado de un número cualquiera (n)
funcion Cuad3(n:ent):entero;
devuelve(n*n); // 2 //
Fin /* 2 */ f ( n) = 2
funcion Cuad4(n:ent):entero;
m=0; // 1 //
para i=1 hasta n // n+1+n+1 //
m=m+n; // n+n //
fpara

f (n) = 4n + 4
devuelve(m); // 1 //
fin /* 4n+4 */

• Diferente coste según algoritmo


• Primero: coste constante (No depende de n)
• Segundo: coste variable en función de n (talla del problema)
13

1. Noción de complejidad
CONSIDERACIONES

„ Talla o tamaño de un problema:


… Valor o conjunto de valores asociados a la entrada del problema que
representa una medida de su tamaño respecto de otras entradas
posibles
… Cuad3: f ( n ) = 2 - Cuad4: f (n) = 4n + 4

70
60 f(n)=2
50 f(n)=4n+4
tiempo

40
30
20
10
0
1 5 10 15
tamaño problema 14

7
1. Noción de complejidad
CONSIDERACIONES

„ ¿Cómo definimos un paso de programa u operación elemental?


¿Cómo lo identificamos en un algoritmo?
„ Paso de programa:
… Secuencia de operaciones con contenido semántico cuyo coste es
independiente de la talla del problema.
… Ejemplo:
„ Opción A: 1 Paso = operación simple
„ Opción B: 1 Paso = secuencia máxima de operaciones cuyo coste es
independiente de la talla del problema
func SUMAR(A:vector[1..n]:ent):ent; Línea Opcion-A Opcion-B
(1) s=0 (1) 1 1
(2) para i=1 hasta n hacer (2) (n+1)(1+1)
(3) s=s+A[i]; Imprime(A[i]); (3) (n+1)(1+1+1) n (1)
fpara
(4) devuelve(s); (4) 1 1
fin Suma 5n+7 n+2

¿Cuál es la diferencia?
15

1. Noción de complejidad
CÁLCULO DEL NÚMERO DE PASOS DE PROGRAMA

„ Una operación elemental corresponde a un paso de programa.


„ La complejidad de una secuencia consecutiva de instrucciones se calcula
sumando los pasos de cada una de las instrucciones
„ Estructuras de selección. El tiempo de ejecución de la sentencia
“SI C ENTONCES S1 SINO S2 FINSI” es:

T = T (C ) + max{T ( S1), T ( S 2)}


„ Estructuras repetitivas. El tiempo de ejecución de un bucle “MIENTRAS C
HACER S FIN” es:

T = T (C ) + ( n º iteraciones ) * (T ( S ) + T (C ))
donde T(C) y T(S) pueden variar en cada iteración, y por tanto habrá que
tenerlo en cuenta para su cálculo.
„ El resto de sentencias iterativas se asemeja al bucle MIENTRAS

16

8
1. Noción de complejidad
CÁLCULO DEL NÚMERO DE PASOS DE PROGRAMA

„ Funciones: El tiempo de ejecución de una llamada a un procedimiento o


función F(P1, P2,..., Pn) es 1 (por la llamada), más el tiempo de evaluación
de los parámetros P1, P2,..., Pn, más el tiempo que tarde en ejecutarse F,
esto es:

T = 1 + T ( P1 ) + T ( P2 ) + ... + T ( Pn ) + T ( F )
„ El paso de parámetros por referencia, por tratarse simplemente de punteros,
no contabiliza
„ El tiempo de ejecución de las llamadas a procedimientos recursivos va a dar
lugar a ecuaciones en recurrencia, que veremos posteriormente.

17

1. Noción de complejidad
EJERCICIOS

funcion ejemplo1 (n:entero):entero;

n=n+1;
devuelve(n);
fin

funcion ejemplo2 (n:entero):entero;


i=0;
mientras (i ≤ 2000)
n=n+1;
i=i+1;
fmientras;
devuelve(n);
fin

18

9
1. Noción de complejidad
EJERCICIOS

funcion ejemplo3 (n:entero):entero;

j = 2;
para i = 1 hasta 2000
j=j*j;
fpara;
i = 0;
mientras (i ≤ n)
j = j + j;
j = j - 2;
i = i + 1;
fmientras;
devuelve(j);
fin

19

1. Noción de complejidad
EJERCICIOS

funcion ejemplo4 (n:entero):entero;


k = 1;
para i=0 hasta n
para j=1 hasta n
k = k + k;
finpara
finpara
devuelve(k);
fin

funcion ejemplo5 (n:entero):entero;


k = 1;
para i=0 hasta n
para j=i hasta n
k = k + k;
finpara
finpara
devuelve(k);
fin
20

10
1. Noción de complejidad
EJERCICIOS

„ Cálculo de la traspuesta de una matriz

función TRASPUESTA (var A:matriz)


var i,j,filas: entero fvar
filas=numfilas (A);
para i=1 hasta filas-1 hacer
para j=i+1 hasta filas hacer
b=A[j,i];
A[j,i]=A[i,j];
A[i,j]=b;
fpara
fpara
fin

21

1. Noción de complejidad
EJERCICIOS

„ Producto de dos matrices


función PRODUCTO (var A,B:matriz; n,m:entero):matriz
var C:matriz; i,j,k,suma:entero fvar

para i=1 hasta n hacer


para j=1 hasta n hacer
suma=0;
para k=1 hasta m hacer
suma= suma + Ai,k * Bk,j;
fpara
Ci,j=suma;
fpara
fpara
devuelve C;
fin

22

11
2. Cotas de complejidad
INTRODUCCION

„ Dado un vector X de n números naturales y dado un número natural z


… Encontrar el índice i tal que Xi = z
… Calcular el número de pasos que realiza

función BUSCAR (var X:vector[N]; z:N):devuelve N;


var i:natural fvar;
i=1;
mientras (i≤⏐X⏐) ∧ (Xi≠z) hacer
i=i+1;
fmientras
si (i=⏐X⏐+1) entonces devuelve(0) (*No encontrado*)
si_no devuelve(i)
fin

23

2. Cotas de complejidad
EL PROBLEMA

„ No podemos contar el número de pasos porque para diferentes


entradas de un mismo tamaño de problema se obtienen diferentes
complejidades
„ Ejemplo:
X z Nº PASOS
( 1, 0, 2, 4 ) 3 1+5+1=7
( 1, 0, 2, 4 ) 0 1+2+1=4
( 1, 0, 2, 4 ) 1 1+1+1=3
„ ¿Qué podemos hacer?
… Acotar el coste mediante dos funciones que expresen respectivamente,
el máximo y el mínimo coste del algoritmo (cotas de complejidad)

24

12
2. Cotas de complejidad
LA SOLUCIÓN: Cotas de complejidad

„ Cuando aparecen diferentes casos para una misma talla genérica n,


se introducen las cotas de complejidad
… Caso peor: cota superior del algoritmo → Cs(n)
… Caso mejor: cota inferior del algoritmo → Ci(n)
… Caso promedio: cota promedio → Cm(n)
„ Todas son funciones del tamaño del problema
„ La cota promedio es difícil de evaluar a priori
… Es necesario conocer la distribución de probabilidad de la entrada
… No es la media de la inferior y de la superior

25

2. Cotas de complejidad
EJEMPLO: Cotas superior e inferior

función BUSCAR (var X:vector[N]; z:N):devuelve N


var i: natural fvar;
(1) i=1;
(2) mientras (i≤⏐X⏐) ∧ (Xi≠z) hacer
(3) i=i+1;
fmientras
(4) si i= ⏐X⏐+1 entonces devuelve 0 si_no devuelve i
fin

Tamaño del problema (n)= Número de elementos del vector X (⏐X⏐)

Línea Mejor Caso Peor Caso


(1) 1 1
(2,3) 1 n
(4) 1 1 Cs(n)=n+2
Suma 3 n+2
Ci (n)=3

26

13
2. Cotas de complejidad
EJEMPLO: Cotas superior e inferior

„ Complejidad función Buscar


Cota Superior
18
16 Ci(n)=3
14 Cs(n)=n+2
¿Cota promedio?
12
10
8
6
4
2
0 Cota Inferior
1 5 10 15
27

3. Análisis asintótico
INTRODUCCION

„ El estudio de la complejidad resulta realmente interesante para


tamaños grandes de problema por varios motivos:
… Las diferencias “reales” en tiempo de ejecución de algoritmos con
diferente coste para tamaños pequeños de problema no suelen ser muy
significativas
… Es lógico invertir tiempo en el desarrollo de un buen algoritmo sólo si se
prevé que éste realizará un gran volumen de operaciones
„ Al estudio de la complejidad para tamaños grandes de problema se
le denomina análisis asintótico
… Permite clasificar las funciones de complejidad de forma que podamos
compararlas entre si fácilmente
… Para ello, se definen clases de equivalencia que engloban a las
funciones que “crecen de la misma forma” (ver principio de invarianza).
… Se emplea la notación asintótica

28

14
3. Análisis asintótico
NOTACION ASINTÓTICA

„ Notación matemática utilizada para representar la complejidad


cuando el tamaño de problema (n) es muy grande (n → ∞)
„ Se definen tres tipos de notación
… Notación O (big-omicron) ⇒ Cota superior
… Notación Ω (omega) ⇒ Cota inferior
… Notación Θ (big-theta) ⇒ Cota promedio

29

3. Análisis asintótico
COTA SUPERIOR. NOTACION O
≥0
„ Sea f : ` → \ se define el conjunto O(f) como el conjunto de
funciones acotadas superiormente por un múltiplo de f :
Ο( f ) = {g : ` → \ ≥0 | ∃c > 0, ∃n0 ∈ ` / ∀n ≥ n0 g( n ) ≤ c· f ( n )}

„ Dada una función t : ` → \ ≥0 se dice que t ∈ Ο( f ) si existe un


múltiplo de f que es cota superior de t

30

15
3. Análisis asintótico
COTA SUPERIOR. NOTACION O
≥0
„ Sea f : ` → \ se define el conjunto O(f) como el conjunto de
funciones acotadas superiormente por un múltiplo de f :
Ο( f ) = {g : ` → \ ≥0 | ∃c > 0, ∃n0 ∈ ` / ∀n ≥ n0 g( n ) ≤ c· f ( n )}

„ Dada una función t : ` → \ ≥0 se dice que t ∈ Ο( f ) si existe un


múltiplo de f que es cota superior de t

c· f (n)

t (n) Ejemplos:

ƒ 3n + 1 ¿pertenece a O(n) ?
ƒ 3n2 + 1 ¿pertenece a O(n) ?
ƒ 3n2 + 1 ¿pertenece a O(n2)?

31

3. Análisis asintótico
NOTACION O : PROPIEDADES

„ Veamos algunas propiedades de esta notación:


1. Dada una función f, entonces f ∈ Ο( f )
2. f ∈ Ο( g ) ⇒ Ο( f ) ⊂ Ο( g )
3. Ο( f ) = Ο( g ) ⇔ f ∈ Ο ( g ) ∧ g ∈ Ο ( f )
„ ¿Para qué sirven?
… Nos permiten agrupar en clases aquellas funciones con el mismo crecimiento
… Ejemplo:
„ ¿ O(3n) = O(15n) ?

„ ¿ O(349n2) = O(2n2) ?

… Las clases resultantes se representan con la función más simple que


contienen
… Ejemplo:
„ O(3n) = O(15n) - Representante : O(n)
„ O(349n2) = O(2n2) - Representante : O(n2)

32

16
3. Análisis asintótico
NOTACION O : PROPIEDADES

„ Veamos algunas propiedades de esta notación:


1. Dada una función f, entonces f ∈ Ο( f )
2. f ∈ Ο( g ) ⇒ Ο( f ) ⊂ Ο( g )
3. Ο( f ) = Ο( g ) ⇔ f ∈ Ο ( g ) ∧ g ∈ Ο ( f )
„ ¿Para qué sirven?
… Nos permiten agrupar en clases aquellas funciones con el mismo crecimiento

33

3. Análisis asintótico
NOTACION O : MAS PROPIEDADES

„ Veamos más propiedades interesantes de esta notación:

4. f ∈ Ο ( g ) ∧ g ∈ Ο( h ) ⇒ f ∈ Ο ( h )
5. f ∈ Ο( g ) ∧ g ∈ Ο(h) ⇒ f ∈ Ο(min( g , h))
6. Regla de la suma: Si f1 ∈ Ο( g1 ) ∧ f 2 ∈ Ο( g 2 ) ⇒ f1 + f 2 ∈ Ο(max( g1 , g 2 ))
7. Regla del producto: Si f1 ∈ Ο ( g1 ) ∧ f 2 ∈ Ο( g 2 ) ⇒ f1 · f 2 ∈ Ο( g1 · g 2 )

f ( n)
8. lim = 0 ⇒ f ∈ Ο( g )
n →∞ g ( n)
9. f (n) = am ·n m + am-1 ·n m-1 + ... + a1 ·n + a0 ∈ Ο(n m )

10. Ο( f ) ⊂ Ο( g ) ⇔ f ∈ Ο( g ) ∧ g ∉ Ο( f )

34

17
3. Análisis asintótico
COTA INFERIOR. NOTACION Ω
≥0
„ Sea f : ` → \ se define el conjunto Ω(f) como el conjunto de
funciones acotadas inferiormente por un múltiplo de f :
Ω( f ) = { g : ` → \ ≥0 | ∃c > 0, ∃n0 ∈ ` / ∀n ≥ n0 g(n) ≥ c· f (n)}

„ Dada una función t : ` → \ ≥0 se dice que t ∈ Ω( f ) si existe un


múltiplo de f que es cota inferior de t

35

3. Análisis asintótico
COTA INFERIOR. NOTACION Ω
≥0
„ Sea f : ` → \ se define el conjunto Ω(f) como el conjunto de
funciones acotadas inferiormente por un múltiplo de f :
Ω( f ) = { g : ` → \ ≥0 | ∃c > 0, ∃n0 ∈ ` / ∀n ≥ n0 g(n) ≥ c· f (n)}

„ Dada una función t : ` → \ ≥0 se dice que t ∈ Ω( f ) si existe un


múltiplo de f que es cota inferior de t

t (n)
Ejemplos:

c· f (n) ƒ 3n + 1 ¿pertenece a Ω(n) ?


ƒ 3n2 + 1 ¿pertenece a Ω(n) ?
ƒ 3n2 + 1 ¿pertenece a Ω(n2)?

36

18
3. Análisis asintótico
NOTACION Ω : PROPIEDADES

„ Veamos algunas propiedades de esta notación:


1. Dada una función f, entonces f ∈ Ω( f )
2. f ∈ Ω( g ) ⇒ Ω( f ) ⊂ Ω ( g )
3. Ω( f ) = Ω ( g ) ⇔ f ∈ Ω( g ) ∧ g ∈ Ω ( f )
4. f ∈ Ω ( g ) ∧ g ∈ Ω( h) ⇒ f ∈ Ω( h)
5. f ∈ Ω( g ) ∧ g ∈ Ω(h) ⇒ f ∈ Ω(max( g , h))
6. Regla de la suma: Si f1 ∈ Ω( g1 ) ∧ f 2 ∈ Ω( g 2 ) ⇒ f1 + f 2 ∈ Ω( g1 + g 2 )
7. Regla del producto: Si f1 ∈ Ω( g1 ) ∧ f 2 ∈ Ω( g2 ) ⇒ f1· f 2 ∈ Ω( g1·g2 )
f ( n)
8. lim = 0 ⇒ g ∈ Ω( f )
n →∞ g ( n)
9. f (n) = am ·n m + am-1 ·n m-1 + ... + a1 ·n + a0 ∈ Ω(n m ) si am > 0

37

3. Análisis asintótico
COTA PROMEDIO. NOTACION Θ
≥0
„ Sea f : ` → \ se define el conjunto Θ(f) como el conjunto de
funciones acotadas superior e inferiormente por un múltiplo de f :

Θ( f ) = { g : ` → \ ≥0 | ∃c, d > 0, ∃n0 ∈ ` / ∀n ≥ n0 c· f ( n) ≤ g( n) ≤ d · f ( n)}

„ O lo que es lo mismo: Θ( f ) = Ο( f ) ∩ Ω( f )
„ Dada una función t : ` → \ ≥0 se dice que t ∈ Θ( f ) si existen
múltiplos de f que son cota superior y cota inferior de t

38

19
3. Análisis asintótico
COTA PROMEDIO. NOTACION Θ
≥0
„ Sea f : ` → \ se define el conjunto Θ(f) como el conjunto de
funciones acotadas superior e inferiormente por un múltiplo de f :

Θ( f ) = { g : ` → \ ≥0 | ∃c, d > 0, ∃n0 ∈ ` / ∀n ≥ n0 c· f ( n) ≤ g( n) ≤ d · f ( n)}

„ O lo que es lo mismo: Θ( f ) = Ο( f ) ∩ Ω( f )
„ Dada una función t : ` → \ ≥0 se dice que t ∈ Θ( f ) si existen
múltiplos de f que son cota superior y cota inferior de t

d · f ( n)
t (n) Ejemplos:

c· f (n) ƒ 3n + 1 ¿pertenece a Θ(n) ?


ƒ 3n2 + 1 ¿pertenece a Θ(n) ?
ƒ 3n2 + 1 ¿pertenece a Θ(n2)?

39

3. Análisis asintótico
NOTACION Θ : PROPIEDADES

„ Veamos algunas propiedades de esta notación:


1. Dada una función f, entonces f ∈ Θ( f )
2. f ∈ Θ( g ) ⇒ Θ( f ) = Θ( g )
3. Θ ( f ) = Θ ( g ) ⇔ f ∈ Θ ( g ) ∧ g ∈ Θ( f )
4. f ∈ Θ ( g ) ∧ g ∈ Θ ( h) ⇒ f ∈ Θ ( h )
5. Regla de la suma: Si f1 ∈ Θ( g1 ) ∧ f 2 ∈ Θ( g 2 ) ⇒ f1 + f 2 ∈ Θ(max( g1 , g 2 ))
6. Regla del producto: Si f ∈ Θ( g ) ∧ f ∈ Θ( g ) ⇒ f · f ∈ Θ( g · g )
1 1 2 2 1 2 1 2
7.
f ( n)
lim = k /(k ≠ 0 ∧ k ≠ ∞ ) ⇒ Θ( f ) = Θ ( g )
n →∞ g ( n )

8. f (n) = am ·n m + am -1 ·n m-1 + ... + a1 ·n + a0 ∈ Θ(n m ) si am > 0

40

20
3. Análisis asintótico
JERARQUIA DE FUNCIONES

„ Los conjuntos de funciones están incluidos unos en otros


generando una ordenación de las diferentes funciones

Ο( f1 (n)) Ο( f 2 (n)) Ο( f 3 ( n))

„ Las clases más utilizadas en la expresión de complejidades son:


Ο(1) ⊂ Ο(lg lg n) ⊂ Ο(lg n) ⊂ Ο(lga>1 n) ⊂
constantes sublogarítmicas logarítmicas
⊂ Ο( n ) ⊂ O(n) ⊂ Ο(n lg n) ⊂
sublineales lineales lineal-logarítmicas
a >2
⊂ Ο(n ) ⊂ " ⊂ Ο(n
2
) ⊂ Ο(2n ) ⊂ Ο(n!) ⊂ Ο(nn )
polinómicas exponenciales
41

3. Análisis asintótico
JERARQUIA DE FUNCIONES

„ ¿Cuál es la diferencia real entre complejidades?


„ Ejemplo: Máximo tamaño, por hora, que pueden resolver algoritmos
cuyo tiempo de ejecución está acotado superiormente por algunas de
las funciones anteriores.
Complejidad 1 paso=1 ms. 1 paso=0’1 ms.
„ La complejidad logarítmica es mucho mejor
que la lineal. No requiere mucho esfuerzo
106 107 plantear soluciones logarítmicas a
log n 10 10
problemas aparentemente lineales (p.e. la
n 3’6 ⋅ 10 6
3’6 ⋅ 107 búsqueda de un elemento en un vector
ordenado).
n log n 2 ⋅ 105 2 ⋅ 106
„ Ante una complejidad elevada no tiene
n2 1.897 6000 sentido invertir en hardware para acelerar el
tiempo de proceso.
n3 153 330
n
2 21 25

42

21
3. Análisis asintótico
EJERCICIOS

1. f (n) ∈ O( g (n)) ∧ g ( n) ∈ O( h(n)) ⇔ f (n) ∈ O(h( n))

2. Ο( f ( n)) = O( g ( n)) ⇔ f (n) ∈ O( g (n)) ∧ g ( n) ∈ O( f ( n))


k
⎛ k ⎞
3. fi (n) ∈ O( gi (n))1..k ⇒ ∏ fi (n) ∈ O ⎜ ∏ gi ( n) ⎟
i =1 ⎝ i =1 ⎠

⎛ k ⎞
k
4. fi ( n) ∈ O( gi ( n))1..k ⇒ ∑ f i (n) ∈ O ⎜ max gi ( n) ⎟
i =1 ⎝ i =1 ⎠
k
⎛ k ⎞
5. fi (n) ∈ O( gi (n))1..k ⇒ ∑ fi ( n) ∈ O ⎜ ∑ gi (n) ⎟
i =1 ⎝ i =1 ⎠
6. O(lg a n) = O(lg b n) ∀a, b > 1
n
7. ∑i
i =1
k
∈ O(n k +1 )
43

4. Calculo de Complejidades
INTRODUCCION

„ Cálculo de la complejidad espacial y temporal


„ Nos centraremos en la complejidad temporal
„ Etapas para obtener las cotas de complejidad
1. Determinar la talla o tamaño del problema
2. Determinar el caso mejor y peor: instancias para las que el algoritmo
tarda más o menos
„ No siempre existe mejor y peor caso ya que existen algoritmos que se
comportan de igual forma para cualquier instancia del mismo tamaño
3. Obtención de las cotas para cada caso
„ Algoritmos iterativos
„ Algoritmos recursivos

44

22
4. Calculo de Complejidades
ALGORITMOS ITERATIVOS

función SUMAR (A:vector[1..n]:entero):entero;


(1) s=0;
(2) para i=1 hasta n hacer
(3) s=s+A[i]; Imprime(A[i]);
fpara
(4) devuelve(s);
„ La talla es n y no existe caso mejor ni peor.
fin

Línea Pasos C. Asintótica


(1) 1 Θ(1)
(2,3) n(1) Θ(n)
(4) 1 Θ(1)
Suma n+2 Θ(n)

Correlación entre ambas


expresiones

45

4. Calculo de Complejidades
ALGORITMOS ITERATIVOS

función BUSCAR (var X:vector[N]; z:N):N


var i:natural fvar;
(1) i=1;
(2) mientras (i≤⏐X⏐) ∧ (Xi≠z) hacer
(3) i=i+1;
fmientras
(4) si i= ⏐X⏐+1 entonces devuelve 0 si_no devuelve i
fin

• La talla es el número de elementos del vector (n)


• Existe mejor y peor caso ¿cuándo se produce cada uno de ellos?

Línea Cuenta Pasos C.Asintótica


Mejor Peor Mejor Peor Cs(n)=n+2
Caso Caso Caso Caso
(1) 1 1 Ω(1) Ο(1) Ci (n)=3
(2,3) 1 n Ω(1) Ο(n)
(4) 1 1 Ω(1) Ο(1)
Suma 3 n+2 Ω(1) Ο(n) Cs(n)=Ο(n)
Ci (n)=Ω(1)

46

23
4. Calculo de Complejidades
ALGORITMOS ITERATIVOS. EJERCICIOS

„ Cálculo del máximo de un vector

función MÁXIMO (var v:vector[n]):entero


var i,n,max: entero fvar
n=|v|;
max=v[1];
para i=2 hasta n hacer
si v[i]>max entonces max=v[i] fsi
fpara
devuelve max;
fin

47

4. Calculo de Complejidades
ALGORITMOS ITERATIVOS. EJERCICIOS

„ Búsqueda de un elemento en un vector ordenado

función BUSCA (var v:vector[N]; x,pri,ult:natural):natural


var m:natural fvar

repetir
m= (pri+ult)/2;
si v[m]>x entonces ult= m-1
si_no pri= m+1
fsi
hasta (pri>ult) ∨ v[m]=x;
si v[m]=x entonces devuelve m
si_no devuelve 0
fsi
fin

48

24
4. Calculo de Complejidades
ALGORITMOS ITERATIVOS. EJERCICIOS
función F1 (a,n:entero)
var i,j:natural fvar
para i=1 hasta n hacer
para j=i hasta 2 hacer (*decreciente*)
F2(a);
fpara F2 ∈ Θ(a2)
fpara
fin

función SEP (x,y:entero):entero


var i,j,r:natural fvar
para i=0 hasta (x+y) hacer
j=i;
mientras (j≠0) hacer
j=j div 2;
r=r+j;
fmientras
fpara
devuelve r;
fin
49

4. Calculo de Complejidades
ALGORITMOS ITERATIVOS. EJERCICIOS

función EJEMPLO (var X:vector[carácter]);


var i,j,n:natural fvar
n=|X|;
i=2;
mientras (n>1) ∧ (i≤n) hacer
j=i;
mientras X[j] ≠ X[1] hacer
j=j div 2;
fmientras
i=i+1;
fmientras
fin

50

25
4. Calculo de Complejidades
ALGORITMOS ITERATIVOS. EJERCICIOS

función CALC (var v:vector[natural);


var i,j,n,x:natural fvar
n=|v|;
si n>0 entonces
j=n; x=0;
mientras x<100 hacer
j=j div 2; x=0; i=j;
repetir
i=i+1;
x=x+v[i];
hasta i=n;
si j=0 entonces x=100 fsi
fmientras
Imprimir(j);
fsi
fin

51

4. Calculo de Complejidades
ALGORITMOS ITERATIVOS. EJERCICIOS

funcion PICO (n,m:N):N


var i,j,x:N;
x=0;
si (n<=m) entonces
i=n;
repetir
para j=1 hasta m*m hacer
x=x+1
fpara;
i=i+2;
hasta (i>m);
finsi;
devuelve x;
fin

52

26
4. Calculo de Complejidades
ALGORITMOS ITERATIVOS. EJERCICIOS

función ECTO(a: vector[N]; n:N): entero


var i,j:N; permuta:bool;
permuta=CIERTO;
i=1;
mientras (permuta) hacer
i=i+1;
permuta=FALSO;
para j=n hasta i hacer
si (a[j]<a[j-1]) entonces
x=a[j];
permuta=CIERTO;
a[j]=a[j-1];
a[j-1]=x;
fsi
fpara
fmientras
fin
53

4. Calculo de Complejidades
ALGORITMOS RECURSIVOS

„ Dado un algoritmo recursivo:


función factorial (n:entero):entero

si n=1 entonces devuelve(1)


si_no devuelve(n*factorial(n-1))
fsi
fin

„ Podemos obtener el coste de la mayoría de las instrucciones pero,


¿cuál es la contribución al coste total del algoritmo de cada una de
las llamadas recursivas?
„ Sólo se puede asegurar que el coste será una función del tamaño del
problema f(n) cuyo valor dependerá del coste de las sucesivas
llamadas recursivas.

⎧Θ(1) n ≤1
f ( n) = ⎨
⎩Θ(1) + f (n − 1) n > 1
54

27
4. Calculo de Complejidades
ALGORITMOS RECURSIVOS

„ Una relación de recurrencia es una expresión que relaciona el valor


de una función f definida para un entero n con uno o más valores de
la misma función para valores menores que n.

⎧a· f ( F (n)) + P(n) n > n0


f ( n) = ⎨
⎩ P '(n) n ≤ n0

• a∈` constante
• P(n), P '(n) Funciones de n. No tienen por que ser polinomios
⎧n - b
• F (n ) < n Función estrictamente decreciente con n. Normalmente ⎨ b∈`
⎩n / b

55

4. Calculo de Complejidades
ALGORITMOS RECURSIVOS

„ Las ecuaciones de recurrencia se usan para expresar la complejidad de


un algoritmo recursivo aunque también son aplicables a los iterativos
„ Si el algoritmo dispone de mejor y peor caso, habrá una función para
cada caso
„ La complejidad de un algoritmo se obtiene en tres pasos:
1. Determinar la talla del algoritmo
2. Obtención de las ecuaciones de recurrencia del algoritmo
3. Resolución de las ecuaciones
„ Para resolverlas, usaremos el método de sustitución:
… Es el método más sencillo
… Sólo para funciones lineales (sólo una vez en función de sí mismas)
… Consiste en sustituir cada f(n) por su valor al aplicarle de nuevo la función
hasta obtener un término general

56

28
4. Calculo de Complejidades
ALGORITMOS RECURSIVOS

„ Ejemplo: Calcular la complejidad del siguiente algoritmo


función máximo (a:vector[enteros];i:entero):entero
si i=1 entonces devuelve(a[1])
si_no
para j=1 hasta i ESCRIBIR(a[i]) fpara
devuelve(MAYOR(máximo(a,i-1),a[i]))
fsi ESCRIBIR ∈ Θ(1)
fin MAYOR ∈ Θ(1)

1. Obtener talla (n) del algoritmo (n=i – Num. de elementos del vector)
2. Obtener ecuación de recurrencia a partir del algoritmo

⎧Θ(1) n =1 Coste base de recurrencia


f ( n) = ⎨ (NO hay recursión)
⎩Θ(n) + f (n − 1) n > 1 Coste caso general de
recurrencia (hay recursión)
Coste instrucciones no Coste llamada
recursivas recursiva
57

4. Calculo de Complejidades
ALGORITMOS RECURSIVOS

„ Ejemplo: Calcular la complejidad del siguiente algoritmo


1. Obtener talla (n) del algoritmo (n=i – Num. de elementos del vector)
2. Obtener ecuación de recurrencia a partir del algoritmo
3. Resolver la recurrencia por sustitución
f (n) = n + f ( n − 1) = (1ª rec)

= n + ( n − 1) + f (n − 2) = (2ª rec)

= n + ( n − 1) + ( n − 2) + f (n − 3) = ... (3ª rec)


i −1
= ∑ (n − j ) + f (n − i) (i-esima rec)
j =0

„ La recursión termina cuando (n-i)=1


„ Por tanto, habrá i=n-1 llamadas recursivas
i −1 n −2
f (n) = ∑ ( n − j ) + f (n − i) = ∑ (n − j ) + f (1)
j =0 j =0

n −2 n −2
(n − 2)(n − 1)
⇒ f ( n) ∈ Θ( n 2 )
= ∑ (n) − ∑ ( j ) + f (1) = n( n − 1) − +1
j =0 j =0 2
58

29
4. Calculo de Complejidades
ALGORITMOS RECURSIVOS

„ QUICKSORT
… Elemento pivote: Nos sirve para dividir en dos partes el vector
„ Al azar
„ Primer elemento → Quicksort primer elemento
„ Elemento central → Quicksort central
„ Elemento mediana → Quicksort mediana
… Pasos:
„ Elección del pivote
„ Se hacen dos recorridos del vector: ascendente (i) y descendente (j)
„ El vector queda dividido en dos partes:
… parte izquierda del pivote → elementos menores
… parte derecha del pivote → elementos mayores
„ Se hacen dos llamadas recursivas. Una con cada parte del vector.

59

4. Calculo de Complejidades
ALGORITMOS RECURSIVOS

„ QUICKSORT primer elemento

funcion QUICKSORT_CENTINELA (var a:vector; pi,pf:indice)


var i,j: indice; x: elemento fvar

si pi<pf entonces
x=a[pi]; i=pi+1; j=pf;
repetir
mientras a[i]<x hacer i=i+1 fmientras
mientras a[j]>x hacer j=j-1 fmientras
si i≤j entonces
SWAP(a[i],a[j]); i=i+1; j=j-1;
fsi
hasta i>j;
SWAP(a[pi],a[j]);
QUICKSORT_CENTINELA (a,pi,j-1);
QUICKSORT_CENTINELA (a,j+1,pf);
fsi
fin

60

30
4. Calculo de Complejidades
ALGORITMOS RECURSIVOS

„ QUICKSORT
… Tamaño del problema: n
… Mejor caso: subproblemas (n/2, n /2)

⎧ Θ(1) n ≤1

f (n ) = ⎨ ⎛n⎞ ⎛n⎞
⎪ Θ( n ) + f ⎜⎝ 2 ⎟⎠ + f ⎜⎝ 2 ⎟⎠ n > 1

… Peor caso: subproblemas (0, n -1),(n -1,0)

⎧ Θ(1) n ≤1
f (n) = ⎨
⎩ Θ( n ) + f ( 0 ) + f ( n − 1) n > 1

61

4. Calculo de Complejidades
ALGORITMOS RECURSIVOS

„ QUICKSORT
… Resolución recurrencia mejor caso
f ( n) = n + 2 f ( n ) = (1ª rec)
2

(2 4 )
= n + 2 n + 2 f ( n ) = 2n + 4 f ( n ) =
4
(2ª rec)

4 ( 8 )
= 2n + 4 n + 2 f ( n ) = 3n + 8 f ( n ) = ... (3ª rec)
8

= in + 2i f ( n i ) (i-esima rec)
2
„ La recursión termina cuando (n/2 i)=1
„ Por tanto, habrá i=log2 n llamadas recursivas

f (n ) = in + 2i f ( n i ) =
2
= n log 2 n + nf (1) = n log 2 n + n ⇒ f (n ) ∈ Ω(n log 2 n )
62

31
4. Calculo de Complejidades
ALGORITMOS RECURSIVOS

„ QUICKSORT
… Resolución recurrencia peor caso
f (n ) = n + f (n − 1) = (1ª rec)
= n + ( n − 1) + f (n − 2) = (2ª rec)
= n + ( n − 1) + (n − 2) + f (n − 3) = ... (3ª rec)
i −1
= ∑ (n − j ) + f (n − i ) (i-esima rec)
j =0

„ La recursión termina cuando (n-i)=1


„ Por tanto, habrá i=n-1 llamadas recursivas
i −1 n−2
f ( n ) = ∑ ( n − j ) + f ( n − i ) = ∑ ( n − j ) + f (1)
j =0 j =0

n −2 n −2
( n − 2)( n − 1) ⇒ f ( n ) ∈ Ο( n 2 )
= ∑ ( n ) − ∑ ( j ) + f (1) = n (n − 1) − +1
j =0 j =0 2 63

4. Calculo de Complejidades
ALGORITMOS RECURSIVOS

„ Coste QUICKSORT
8

7 1
8
6 1
4 4

2 2 2 2
5 1 Caso peor

1 1 1 1 1 1 1 1
4 1 Ο(n2)
Caso mejor 3 1

Ω(n lg2n) 2 1

1 1

64

32
4. Calculo de Complejidades
ALGORITMOS RECURSIVOS

„ QUICKSORT mediana (el pivote es la mediana)

… En la versión anterior se cumple que el caso mejor es cuando el


elemento seleccionado es la mediana.
… En este algoritmo estamos forzando el caso mejor.
… Obtener la mediana
„ Coste menor que Ο(nlgn)
„ Se aprovecha el recorrido para reorganizar elementos y para encontrar la
mediana en la siguiente subllamada.
„ Su complejidad es por tanto de Θ(nlgn).

65

4. Calculo de Complejidades
ALGORITMOS RECURSIVOS: EJERCICIOS

función DESPERDICIO (n:natural)

para i=1 hasta n hacer


para j=1 hasta i hacer
ESCRIBIR i,j,n ;
fpara ESCRIBIR ∈ Θ(1)
fpara
si n>0 entonces
para i=1 hasta 4 hacer
DESPERDICIO(n/2);
fpara
fsi
fin

66

33
4. Calculo de Complejidades
ALGORITMOS RECURSIVOS: EJERCICIOS

función EJEMPLO (n, a:entero):entero;


var r:entero fvar;

si a2 > n entonces devuelve 0;


si_no
r=EJEMPLO(n,2a);
opción
n<(r+a)2 devuelve r;
n≥(r+a)2 devuelve r+a;
fopción
fsi
fin

67

4. Calculo de Complejidades
ALGORITMOS RECURSIVOS: EJERCICIOS

funcion ORD(n: N ; v:vector[N]);


si (n>0) entonces
ORD(n div 2,v);
QuickSortMediana(v,1,n);
fsi;
fin

68

34
4. Calculo de Complejidades
ALGORITMOS RECURSIVOS: EJERCICIOS

función PAL (A:vector[N]; iz,de:N):bool


var n,i:N;
n=de-iz+1;
opcion
(n <=1): devuelve (CIERTO) ;
(n > 1): para i=1 hasta n hacer
Imprimir("A")
fpara;
si (A[iz]=A[de]) entonces
devuelve(PAL(A,iz+1,de-1));
sino
devuelve(FALSO) ;
finsi;
fopcion
fin

69

5. Anexo
EXPRESIONES FRECUENTES

1. c ∈ Θ(1), ∀c ∈ \ ≥0 n
1
n
n
7. ∑ i ∈ Θ(lg n)
2. ∑ i = 2 (n + 1) ∈ Θ(n
i =1
2
) i =1

n
1
n
n 1
8. ∑r i
∈ Θ(1) si r > 1
3. ∑ i 2 = (n + 1)( n + ) ∈ Θ(n3 ) i =1

i =1 3 2 n

n
9. ∑ lg i ∈ Θ(n lg n)
4. ∑i
i =1
k
∈ Θ(n k +1
), ∀k ∈ ` i =1

n
10. ∑ i2 i −1
= n 2 n − 2 n + 1 ∈ Θ( n 2 n )
5. ∑ (n − i )
i =1
k
∈ Θ( n k +1 ), ∀k ∈ ` i =1

n
−1 r n +1
11. ∑ i2 −i
∈ Θ(1)
6. ∑ r i =
i =0
∈ Θ( r n ), r ≠ 1
i =0 r −1
70

35
5. Anexo
EXPRESIONES FRECUENTES

n
12. ∑ iri =1
i −1
∈ Θ(nr n ), ∀r > 1

n
13. ∑ iri =1
−i
∈ Θ(1), ∀r > 1

n
1
14. ∑ i ! ∈ Θ(1)
i =1

n
⎛n⎞
15. ∑ ⎜⎝ i ⎟⎠ = 2
i =1
n
∈ Θ(2n )

n
⎛n⎞
16. n !∈ Θ( n ⎜ ⎟ )
⎝e⎠
71

5. Anexo
SUMA DE SERIES

Donde:
progresión aritmética
a0 = Primer elemento de la serie
a + an
S n = n· 0 an = n-esimo elemento de la serie
2 S n = Suma de los n primeros elementos de la serie

r = Razon de la serie geometrica


progresión geométrica
r n −1
S n = a0 · r >1
r −1
a0
Sn = r < 1, n → ∞
1− r

72

36
5. Anexo
SUMA DE SERIES

progresión aritmético-geométrica
S n = 1r + 2r 2 + " + nr n

rS n = 1r 2 + 2r 3 " + ( n − 1)r n + nr n+1

S n − rS n = r + r 2 + r 3 " + r n − nr n +1

(1 − r ) S n = r + r 2 + r 3 " + r n − nr n+1
n

r + r 2 + r 3 " + r n − nr n+1 nr n+1 i =1 ∑r i


n·r n +1
Sn = − = −
1− r 1− r 1− r 1− r

73

5. Anexo
RECURRENCIAS FRECUENTES

REDUCCIÓN DEL PROBLEMA POR RESTAS (c>0)

a < 1 → Θ(1)
⎧b ' n ≤ n0
f ( n) ⎨ Solución: a = 1 → Θ(n)
⎩ a· f (n − c) + b n > n0 a > 1 → Θ( a n / c )
a < 1 → Θ( n )
⎧b ' n ≤ n0
f ( n) ⎨ Solución: a = 1 → Θ( n 2 )
⎩ a· f (n − c) + b·n n > n0 a > 1 → Θ( a n / c )

a < 1 → Θ( n k )
⎧b ' n ≤ n0
f ( n) ⎨ Solución: a = 1 → Θ(n k +1 )
⎩ a· f (n − c) + b·n n > n0
k

a > 1 → Θ( a n / c )
74

37
5. Anexo
RECURRENCIAS FRECUENTES

REDUCCIÓN DEL PROBLEMA POR DIVISIONES (c>1)

a < 1 → Θ(1)
⎧b ' n ≤ n0
f ( n) ⎨ Solución: a = 1 → Θ(lg n)
⎩a· f (n / c) + b n > n0 a > 1 → Θ(nlg a )
a < 1 → Θ ( n)
⎧b ' n ≤ n0
f ( n) ⎨ Solución: a = 1 → Θ(n lg n)
⎩a· f (n / c) + bn n > n0 a > 1 → Θ(nlg a )

a < c k → Θ( n k )
⎧b ' n ≤ n0
f ( n) ⎨ Solución: a = c k → Θ(n k lg n)
⎩ a· f (n / c ) + b·n n > n0
k

a > c k → Θ(n lg a )
75

5. Anexo
ALGORITMOS DE ORDENACION

„ Directos
… Inserción directa
… Inserción binaria
… Selección directa
… Intercambio directo (burbuja)

„ Avanzados
… Mergesort
… Quicksort
… Heapsort
… Shell

76

38
5. Anexo
ALGORITMOS DE ORDENACION

„ INSERCIÓN DIRECTA

función INSERCION_DIRECTA (var a:vector[natural]; n: natural)


var i,j: entero; x:natural fvar

para i=2 hasta n hacer


x=a[i]; j=i-1;
mientras (j>0) ∧ (a[j]>x) hacer
a[j+1]=a[j];
j=j-1;
fmientras
a[j+1]=x;
fpara
fin

77

5. Anexo
ALGORITMOS DE ORDENACION

„ INSERCIÓN BINARIA

función INSERCION_BINARIA (var a:vector[natural]; n: natural)


var i, j, iz, de, m: entero; x:natural fvar

para i=2 hasta n hacer


x=a[i]; iz=1; de=i-1;
mientras (iz≤de) hacer
m= (iz+de)/2;
si a[m]>x entonces de= m-1
si_no iz=m+1
fsi
fmientras
para j=i-1 hasta iz hacer (*decreciente*)
a[j+1]=a[j];
fpara
a[iz]=x;
fpara
fin

78

39
5. Anexo
ALGORITMOS DE ORDENACION

„ SELECCIÓN DIRECTA

función SELECCION_DIRECTA (var a:vector[natural]; n:natural)


var i, j, posmin: entero; min:natural fvar

para i=1 hasta n-1 hacer


min=a[i]; posmin=i;
para j=i+1 hasta n hacer
si a[j]<min entonces
min=a[j]; posmin=j;
fsi
fpara
a[posmin]=a[i]; a[i]=min;
fpara
fin

79

5. Anexo
ALGORITMOS DE ORDENACION

„ INTERCAMBIO DIRECTO (Burbuja)

función INTERCAMBIO_DIRECTO (var a:vector[natural]; n:natural )


var i,j:entero fvar

para i=2 hasta n hacer


para j=n hasta i hacer
si a[j]<a[j-1] entonces
SWAP(a[j],a[j-1]);
fsi
fpara
fpara
fin

80

40
5. Anexo
ALGORITMOS DE ORDENACION

„ QUICKSORT central

función QUICKSORT_SIN_CENTINELA (var a:vector; pi,pf:indice)


var i,j: indice; x: elemento fvar
comienzo
si pi<pf entonces
x=a[(pi+pf)/2]; i=pi; j=pf;
repetir
mientras a[i]<x hacer i=i+1 fmientras
mientras a[j]>x hacer j=j-1 fmientras
si i≤j entonces
SWAP(a[i],a[j]); i=i+1; j=j-1;
fsi
hasta i>j;
QUICKSORT_SIN_CENTINELA (a,pi,j);
QUICKSORT_SIN_CENTINELA (a,i,pf);
fsi
fin

81

41