Está en la página 1de 51

Departamento de

Métodos
Cuantitativos

Tema 2.1. Análisis de Complejidad


Antonio Manuel Durán Rosal (amduran@uloyola.es)
Programación Avanzada
2º de Grado en Ingeniería Informática y Tecnologías Virtuales
Curso 2020-2021
Octubre 2020
Índice de contenidos

1. Algoritmos

2. Complejidad de un Algoritmo

3. Notación Asintótica

4. Cálculo de la Complejidad

A.M. Durán-Rosal 2/51


1. Algoritmos

Índice de contenidos

1. Algoritmos
Definición
Características de un Algoritmo

2. Complejidad de un Algoritmo

3. Notación Asintótica

4. Cálculo de la Complejidad

A.M. Durán-Rosal 3/51


1. Algoritmos→ Definición

¿Qué entendemos por algoritmo?

Conjunto de reglas y pasos seguidos para realizar un determinado


cálculo, ya sea de tipo manual o en una máquina. Ejemplos: méto-
dos que aprendimos para sumar, restar, multiplicar y dividir.
Un algoritmo muy famoso es el propuesto por Euclides para calcular
el mcd entre dos enteros:

Sean a y b dos números Algoritmo mcd(a,b)


inicio
enteros, tal que a > b, si b = 0 entonces
devolver a
entonces el mcd(a, b) = sino
mcd(b, r ) siendo r el resto r <- a mod b
devolver mcd(b,r)
de dividir a entre b. finsi
fi

A.M. Durán-Rosal 4/51


1. Algoritmos→ Características de un Algoritmo

Características de un algoritmo

• Precisión: las reglas de los algoritmos han de ser precisas y


no dar lugar a la ambigüedad. Por ejemplo, un algoritmo no
puede tener una regla del tipo sume una cantidad de dinero
a su gusto. No obstante, los algoritmos probabilísticos pueden
violar en parte esta rigidez.
• Determinismo: ante unas mismas condiciones, el algoritmo
debe comportarse exactamente igual.
• General: capaz de resolver una clase de problemas lo más am-
plia posible.
• Eficiente: debe consumir poca cantidad de recursos (tiempo,
memoria, procesador). Nos centraremos en el tiempo.

A.M. Durán-Rosal 5/51


1. Algoritmos→ Características de un Algoritmo

Algorítmica: ¿Qué algoritmo escoger?

A.M. Durán-Rosal 6/51


2. Complejidad de un Algoritmo

Índice de contenidos

1. Algoritmos

2. Complejidad de un Algoritmo
Complejidad
Factores
Enfoques

3. Notación Asintótica

4. Cálculo de la Complejidad

A.M. Durán-Rosal 7/51


2. Complejidad de un Algoritmo→ Complejidad

Definición
El cálculo de la eficiencia o complejidad de un algoritmo consiste
en la evaluación de los recursos necesarios para su ejecución, de
forma que para un determinado problema podamos elegir el mejor
algoritmo.

A.M. Durán-Rosal 8/51


2. Complejidad de un Algoritmo→ Complejidad

¿Es necesario su cálculo?

Ordenación de vector de 100.000 Cálculo de determinante de


enteros 25x25

Método Burbuja Quicksort Recursivo Gauss-Jordan


varios minutos segundos años fracción seg

A.M. Durán-Rosal 9/51


2. Complejidad de un Algoritmo→ Factores

Factores que influyen en el cálculo

• El tamaño de los datos de entrada o tamaño del ejemplar.


• El contenido de los datos de entrada.
• El computador y el código generado por el compilador.
Definimos T (n) como el tiempo empleado para ejecutar el algoritmo
con una entrada de tamaño n.

A.M. Durán-Rosal 10/51


2. Complejidad de un Algoritmo→ Factores

Tamaño de los datos de entrada

Aunque el tamaño de un ejemplar se corresponde formalmente con


el número de dígitos necesarios para representarlo en un ordenador,
se suele identificar como el número de elementos lógicos contenidos
en el ejemplar. Por ejemplo:
• Ordenar n número enteros → tamaño n.
• Factorial de un número → tamaño en función del valor.
• Matrices cuadradas → tamaño en función de su orden.

A.M. Durán-Rosal 11/51


2. Complejidad de un Algoritmo→ Factores

Contenido de los datos de entrada

Se distinguen tres estrategias:


• Estudio de la eficiencia en el caso peor Tmax (n): se fija un
tamaño del problema y se estudia la eficiencia en situaciones
que emplean más tiempo para dar una cota superior.
• Estudio en el caso medio Tmed (n): se debe conocer el tiempo
de ejecución de todas las situaciones y su frecuencia de ocu-
rrencia → es muy complejo y casi no se usa.
• Estudio en el mejor caso Tmin (n): se estudia la eficiencia en
situaciones en las que se emplea menor tiempo posible para
dar una cota inferior. No es recomendable su uso ya que es
demasiado optimista.

A.M. Durán-Rosal 12/51


2. Complejidad de un Algoritmo→ Factores

Computador y código generado por compilador

No se suele tener en cuenta debido a:


• Se pretende analizar la eficiencia de modo totalmente indepen-
diente a las máquinas y lenguajes existentes.
• Principio de invarianza: dos implementaciones de un mismo
algoritmo no diferirán más que en una constante multiplicativa.

A.M. Durán-Rosal 13/51


2. Complejidad de un Algoritmo→ Enfoques

Enfoques en la evaluación

Enfoques

Empírico o a
Teórico o a priori Híbrido
posteriori

A.M. Durán-Rosal 14/51


3. Notación Asintótica

Índice de contenidos
1. Algoritmos

2. Complejidad de un Algoritmo

3. Notación Asintótica
Definición
Notación Orden de f (n) (O())
Notación Omega de f (n) (Ω())
Notación Orden Exacto de f (n) (Θ())
Propiedades de la Notación Orden O()
Jerarquía de los Órdenes de Complejidad

4. Cálculo de la Complejidad

A.M. Durán-Rosal 15/51


3. Notación Asintótica→ Definición

Definición

Estudia el comportamiento del algoritmo cuando el tamaño de las


entradas es lo suficientemente grande (n → ∞), sin tener en cuenta
lo que ocurre para entradas pequeñas y obviando factores constan-
tes.
En otras palabras, si f es la función que indica cuanto tarda en
ejecutarse un algoritmo, entonces f (n) es el tiempo que requiere
cuando el tamaño del problema es n. La eficiencia se estudia por
medio de f (n) cuando n es lo suficientemente grande, por eso se
denomina análisis asintótico.

A.M. Durán-Rosal 16/51


3. Notación Asintótica→ Notación Orden de f (n) (O())

Notación orden de f (n) (O())

Sea f : N → R+ ∪ {0}. El conjunto de las funciones de orden de


f (n), denotado por O(f (n)), se define como:

O(f (n)) = T : N → R+ ∪ {0}|∃c ∈ R+ , n0 ∈ N, ∀n ≥ n0 , T (n) ≤ cf (n) .




O expresado de otra forma: decimos que una función T (n) es O(f (n))
si existen constantes n0 y c tales que T (n) ≤ cf (n) para todo
n ≥ n0 .

T (n) es O(f (n)) ↔ ∃c ∈ R+ , ∃n0 ∈ N, tal que ∀n ≥ n0 , T (n) ≤ cf (n).

A.M. Durán-Rosal 17/51


3. Notación Asintótica→ Notación Orden de f (n) (O())

Notación orden de f (n) (O())

Resumiendo, se dice que T (n) es del orden de f (n) cuando está aco-
tada superiormente por f (n) para valores suficientemente grandes
de n y haciendo abstracción de posibles constantes multiplicativas.

A.M. Durán-Rosal 18/51


3. Notación Asintótica→ Notación Omega de f (n) (Ω())

Notación omega de f (n) (Ω())

Sea f : N → R+ ∪ {0}. El conjunto de las funciones de orden de


f (n), denotado por Ω(f (n)), se define como:

Ω(f (n)) = T : N → R+ ∪ {0}|∃c ∈ R+ , n0 ∈ N, ∀n ≥ n0 , T (n) ≥ cf (n) .




O expresado de otra forma: decimos que una función T (n) es Ω(f (n))
si existen constantes n0 y c tales que T (n) ≥ cf (n) para todo
n ≥ n0 .

T (n) es Ω(f (n)) ↔ ∃c ∈ R+ , ∃n0 ∈ N, tal que ∀n ≥ n0 , T (n) ≥ cf (n).

A.M. Durán-Rosal 19/51


3. Notación Asintótica→ Notación Omega de f (n) (Ω())

Notación omega de f (n) (Ω())

Resumiendo, se dice que T (n) está en omega de f (n) cuando es-


tá acotada inferiormente por f (n) para valores suficientemente
grandes de n y haciendo abstracción de posibles constantes multi-
plicativas.
Las notaciones orden y omega son independientes de que el
análisis sea en el mejor caso, peor caso o caso medio. Si T (n)
representa el tiempo de ejecución de un algoritmo y T (n) ∈
Ω(f (n)), entonces la medida Ω(f (n)) no se refiere al mejor
tiempo del mismo, sino a una cota inferior de T (n).

A.M. Durán-Rosal 20/51


3. Notación Asintótica→ Notación Orden Exacto de f (n) (Θ())

Notación orden exacto de f (n) (Θ())

Sea f : N → R+ ∪ {0}. El conjunto de las funciones de orden exacto


de f (n), denotado por Θ(f (n)), se define como:

Θ(f (n)) = O(f (n)) ∩ Ω(f (n)).

Es decir, T (n) es Θ(f (n)) cuando T (n) es O(f (n)) y T (n) es


Ω(f (n)).

NOS CENTRAREMOS EN LA NOTACIÓN ORDEN O()

A.M. Durán-Rosal 21/51


3. Notación Asintótica→ Propiedades de la Notación Orden O()

Propiedades de O()
Nº Expresión
1 Reflexiva: f (n) ∈ O(f (n)).
2 Transitiva: Si f (n) ∈ O(g(n)) y g(n) ∈ O(h(n)) → f (n) ∈ O(h(n)).
3 Si g(n) ∈ O(f (n)) y f (n) ∈ O(g(n)) → O(f (n)) ∈ O(g(n)).
4 ∀c ∈ R+ O(cf (n)) = O(f (n)).
5 Si a, b > 1 → O(loga n) = O(logb n) = O(log n).
6 Regla del máximo o suma: O(f (n) + g(n)) = O(máx(f (n), g(n))).
Regla del límite:
f (n)
1. Si lı́m ∈ R+ → f (n) ∈ O(g(n)) y g(n) ∈ O(f (n))
n→∞ g(n)
7 f (n)
2. Si lı́m = 0 → f (n) ∈ O(g(n)) y g(n) ∈
/ O(f (n))
n→∞ g(n)
f (n)
3. Si lı́m = ∞ → f (n) ∈
/ O(g(n)) y g(n) ∈ O(f (n))
n→∞ g(n)

A.M. Durán-Rosal 22/51


3. Notación Asintótica→ Jerarquía de los Órdenes de Complejidad

Jerarquía de los órdenes


Como se ha comentado, elegiremos como representante del orden
de complejidad a la función f (n) más sencilla perteneciente a esta
familia. Así:
Orden Nombre
O(1) Complejidad constante
O(log n) Complejidad logarítmica
O(n) Complejidad lineal
O(n log n) Complejidad cuasilineal
O(n2 ) Complejidad cuadrática
O(n3 ) Complejidad cúbica
O(nk ) Complejidad polinómica
O(2n ) Complejidad exponencial
O(n!) Complejidad factorial

O(1) ⊂ O(log n) ⊂ O(n) ⊂ O(n log n) ⊂ O(n2 ) ⊂ O(n3 ) ⊂ O(nk ) ⊂ O(2n ) ⊂ O(n!)

A.M. Durán-Rosal 23/51


3. Notación Asintótica→ Jerarquía de los Órdenes de Complejidad

Jerarquía de los órdenes

1. Complejidad constante: no depende del tamaño de los datos


de entrada.
2. Complejidad algorítmica: aparece en determinados algoritmos
con iteración o recursión no estructural (búsqueda binaria).
3. Complejidad lineal: buena y usual. Bucles simples.
4. Complejidad cuasilineal: algoritmos del tipo divide y vencerás.
5. Complejidad cuadrática: bucles doblemente anidados.
6. Complejidad cúbica: bucles con triple anidación. Al crecer n,
el tiempo crece drásticamente.
7. Complejidad polinómica: bastante mala si n crece.
8. Complejidad exponencial: debe evitarse.
9. Complejidad factorial: el tiempo de ejecución crece de manera
inviable.

A.M. Durán-Rosal 24/51


3. Notación Asintótica→ Jerarquía de los Órdenes de Complejidad

Comparativa gráfica

A.M. Durán-Rosal 25/51


3. Notación Asintótica→ Jerarquía de los Órdenes de Complejidad

Comparativa analítica

Duplicar el tamaño del problema Duplicar el tiempo disponible


T (n) n = 100 n = 200 T (n) t = 1s t = 2s
log n 1s 1,15s log n n=100 n=100000
n 1s 2s n n=100 n=200
n log n 1s 2,3s n log n n=100 n=178
n2 1s 4s n2 n=100 n=141
n3 1s 8s n3 n=100 n=126
2 n 1s 1,27 · 1030 s 2n n=100 n=101

A.M. Durán-Rosal 26/51


3. Notación Asintótica→ Jerarquía de los Órdenes de Complejidad

Consideraciones importantes

• Un algoritmo eficientemente bueno en términos generales no


implica que no exista otro algoritmo que resuelva el mismo
problema de una forma más eficiente.
• En la notación asintótica estamos obviando las constantes ya
que estamos ante valores de n suficientemente grandes.
I Con valores de n pequeños no tiene porque ocurrir lo mismo.
I Habrá que determinar cuando es mejor usar un algoritmo u otro
en función de este tamaño si fuera necesario.

A.M. Durán-Rosal 27/51


3. Notación Asintótica→ Jerarquía de los Órdenes de Complejidad

Ejercicio 1

En Moodle tenéis disponible una carpeta con los algoritmos de or-


denación Burbuja y Quicksort.
a) Probaremos el problema de aumentar el tamaño de entrada de
los datos.
b) Comprobaremos cuando afecta más en términos de tiempo se-
gún su orden de complejidad.

A.M. Durán-Rosal 28/51


4. Cálculo de la Complejidad

Índice de contenidos

1. Algoritmos

2. Complejidad de un Algoritmo

3. Notación Asintótica

4. Cálculo de la Complejidad
Introducción
Algoritmos No Recursivos
Algoritmos Recursivos

A.M. Durán-Rosal 29/51


4. Cálculo de la Complejidad→ Introducción

Cálculo de la complejidad

• Como se ha comentado, un algoritmo puede tener tres tiem-


pos de ejecución Tmin (n) (mejor caso), Tmax (n) (peor caso), y
Tmed (n) muy difícil de determinar.
• Utilizaremos el peor caso ya que el tiempo mínimo es dema-
siado optimista y refleja en pocas ocasiones la realidad en la
ejecución de los programas.
• Hablaremos de tiempo total de ejecución y orden de eficiencia
(Notación O(n)).
• Distinguimos entre algoritmos no recursivos y algoritmos recur-
sivos.

A.M. Durán-Rosal 30/51


4. Cálculo de la Complejidad→ Algoritmos No Recursivos

Sentencias simples

El tiempo de ejecución necesario para la evaluación de una cons-


tante, una expresión formada por términos simples, lectura y escri-
tura o una asignación simple es constante.
Su orden de eficiencia es O(1).

A.M. Durán-Rosal 31/51


4. Cálculo de la Complejidad→ Algoritmos No Recursivos

Secuencia de instrucciones
El tiempo de ejecución es igual a la suma de los tiempos de eje-
cución de cada una de las sentencias del bloque.

Ts (n) = Ts1 (n) + Ts2 (n) + · · · + Tsk (n).

Su orden, aplicando la regla de la suma, es:

O(Ts (n)) = O(máx(Ts1 (n), Ts2 (n), . . . , Tsk (n))).

s1;
s2;
...
sk;

A.M. Durán-Rosal 32/51


4. Cálculo de la Complejidad→ Algoritmos No Recursivos

Sentencias condicionales
El tiempo de ejecución es igual a la suma del tiempo de evaluación
Tg (n) más el máximo de los tiempos del consecuente Ts1 (n) y la
alternativa Ts2 (n).
Tif (n) = Tg (n) + máx(Ts1 (n), Ts2 (n)).
Su orden, aplicando la regla de la suma, es:
O(Tif (n)) = O(máx(Tg (n), Ts1 (n), Ts2 (n))).

if(g) {
s1;
}
else{
s2;
}

A.M. Durán-Rosal 33/51


4. Cálculo de la Complejidad→ Algoritmos No Recursivos

Sentencias iterativas

El tiempo de ejecución es igual a la suma del tiempo de evaluación


Tg (n) más la de los tiempos de las sucesivas iteraciones (I): Ts (n)+
Tg (n).
Tit (n) = Tg (n) + (Ts (n) + Tg (n)).
X

Su orden, aplicando la regla de la suma, es:

O(Tit (n)) = O(n máx(Ts (n), Tg (n))).

while(g){
s;
}

A.M. Durán-Rosal 34/51


4. Cálculo de la Complejidad→ Algoritmos No Recursivos

Llamada a funciones

El tiempo de ejecución es igual a la suma del tiempo de evaluación


de los argumentos Ta (n) más el de ejecución del cuerpo Tc (n).

Tf (n) = Ta (n) + Tc (n).

Su orden, aplicando la regla de la suma, es:

O(Tf (n)) = O(máx(Ta (n), Tc (n))).

F(a1, a2, ..., an){


c;
}

A.M. Durán-Rosal 35/51


4. Cálculo de la Complejidad→ Algoritmos No Recursivos

Ejercicio 2

a) Calcula el tiempo de ejecución (peor caso) y el orden de com-


plejidad de los siguientes algoritmos:

1 int i; 1 i=1; 1 for(i=1; i<=n; i++){


2 for(i=1; i<=n; i++) 2 while(i<=n){ 2 for(j=1; j<=n; j++){
3 { 3 s = s + i; 3 suma = suma + a[i][j];
4 r+=a*i; 4 i = i + r; 4 }
5 } 5 } 5 }

1 if(n %2==0){ 1 i=1; 1 x=1;


2 for(i=1;i<=n;i++){ 2 while(i<=n){ 2 while(x<=n)
3 a[i] = -a[i]; 3 x=x*i; 3 {
4 } 4 i=i+2; 4 x=2*x;
5 } 5 } 5 }

A.M. Durán-Rosal 36/51


4. Cálculo de la Complejidad→ Algoritmos Recursivos

Algoritmos recursivos

Antes de comenzar con el análisis de complejidad de algoritmos


recursivos, vamos a definir y a explicar lo que son estos algoritmos.
Para ello, veremos el pdf:
Tema2.2_Presentación.pdf

A.M. Durán-Rosal 37/51


4. Cálculo de la Complejidad→ Algoritmos Recursivos

Métodos

Se pueden utilizar distintos métodos para resolver ecuaciones recu-


rrentes:
• Método de la ecuación característica.
• Acotación.
• Expansión de recurrencias.
• Etcétera.

A.M. Durán-Rosal 38/51


4. Cálculo de la Complejidad→ Algoritmos Recursivos

Expansión de recurrencias

• Este método consiste en sustituir las recurrencias por su igual-


dad hasta llegar a cierta T (n) conocida, es decir, hasta los casos
base.
• Nos proporciona una cota superior.
• Es relativamente sencillo de aplicar en los programas y algorit-
mos que vamos a tratar durante el curso.

A.M. Durán-Rosal 39/51


4. Cálculo de la Complejidad→ Algoritmos Recursivos

Expansión de recurrencias

Supongamos la siguiente función que calcula el factorial de un nú-


mero:
1 int factorial (int n)
2 {
3 if (n <= 1)
4 {
5 return 1;
6 }
7 else
8 {
9 return (n*factorial(n-1));
10 }
11 }

A.M. Durán-Rosal 40/51


4. Cálculo de la Complejidad→ Algoritmos Recursivos

Expansión de recurrencias

Escribimos una ecuación de recurrencia que acota a T (n) superior-


mente:
1 int factorial (int n)
2 {
3 if (n <= 1)
4 {
5 return 1; (
1 si n ≤ 1
6 }
T (n) =
7 else T (n − 1) + 3 si n > 1
8 {
9 return (n*factorial(n-1));
10 }
11 }

A.M. Durán-Rosal 41/51


4. Cálculo de la Complejidad→ Algoritmos Recursivos

Expansión de recurrencias

Expandimos la función:
(
1 si n ≤ 1
T (n) =
T (n − 1) + 3 si n > 1

T (n) = T (n − 1) + 3
T (n) = T (n − 2) + 3 + 3
T (n) = T (n − 3) + 3 + 3 + 3
···
T (n) = T (n − k) + 3k

A.M. Durán-Rosal 42/51


4. Cálculo de la Complejidad→ Algoritmos Recursivos

Expansión de recurrencias

Damos un valor a k para llegar al caso base:


(
1 si n ≤ 1
T (n) =
T (n − 1) + 3 si n > 1

T (n) = T (n − k) + 3k

Si k es igual a n → T (n) = T (n − n) + 3n = T (0) + 3n

O(T (n)) = n

A.M. Durán-Rosal 43/51


4. Cálculo de la Complejidad→ Algoritmos Recursivos

Ejercicio 3 (1/3)
Dados los siguientes algoritmos:
a) Calcular la función de recurrencia de T (n).
b) Calcular el orden de complejidad.

1 int Recursiva(int n)
1 int Recursiva(int n)
2 {
2 {
3 if(n<=1)
3 if(n<=1)
4 {
4 {
5 return 1;
5 return 1;
6 }
6 }
7 else
7 else
8 {
8 {
9 return (Recursiva(n-1) +
9 return (2*Recursiva(n-1));
Recursiva(n-1));
10 }
10 }
11 }
11 }

A.M. Durán-Rosal 44/51


4. Cálculo de la Complejidad→ Algoritmos Recursivos

Ejercicio 3 (2/3)
Dados los siguientes algoritmos:
a) Calcular la función de recurrencia de T (n).
b) Calcular el orden de complejidad.
1 int Recursiva(int n, int x)
1 int Recursiva(int n) 2 {
2 { 3 if(n<=1)
3 if(n<=1) 4 {
4 { 5 return 1;
5 return 1; 6 }
6 } 7 else{
7 else 8 for(int i=1; i<=n; i++){
8 { 9 x = x + 1;
9 return (2*Recursiva(n/2)); 10 }
10 } 11 return Recursiva(n-1,x);
11 } 12 }
13 }

A.M. Durán-Rosal 45/51


4. Cálculo de la Complejidad→ Algoritmos Recursivos

Ejercicio 3 (3/3)

Dados los siguientes algoritmos:


a) Calcular la función de recurrencia de T (n).
b) Calcular el orden de complejidad.
1 int fibonacci(int n)
2 {
3 if(n<=1)
4 {
5 return n;
6 }
7 else
8 {
9 return (fibonacci(n-1) + fibonacci(n-2));
10 }
11 }

A.M. Durán-Rosal 46/51


4. Cálculo de la Complejidad→ Algoritmos Recursivos

Series recurrentes de utilidad

• Progresión aritmética: an = an−1 + c, siendo c constante.


n
n(a1 + an )
ai =
X
.
i=1
2

• Progresión geométrica: an = ran−1 , siendo r 6= 1 constante.


n
an r − a1
ai =
X
.
i=1
r −1

• Suma de cuadrados:
n
n(n + 1)(2n + 1)
i2 =
X
.
i=1
6

A.M. Durán-Rosal 47/51


4. Cálculo de la Complejidad→ Algoritmos Recursivos

Ejercicio 4
Obtener el orden de complejidad de los siguientes algoritmos:
a) Método de la burbuja recursivo:
(
1 si n = 1
T (n) =
T (n − 1) + (n − 1) si n > 1

b) Búsqueda en árbol binario ordenado y balanceado:


(
1 si n = 1
T (n) =
T (n/2) + 1 si n > 1

c) Búsqueda en árbol binario ordenado y no balanceado:


(
1 si n = 1
T (n) =
2T (n/2) + 1 si n > 1

A.M. Durán-Rosal 48/51


Referencias

Recursos electrónicos
• cppreference. (2020). Referencia C++:
https://en.cppreference.com/w/.
• Goalkicker.com (2018). C++: Note for Professionals.
• Goalkicker.com (2018). Algorithms: Notes for Professionals.
• Joyanes, L. (2000). Programación en C++: Algoritmos, Estruc-
turas de datos y Objetos.

A.M. Durán-Rosal 49/51


Referencias

Libros:
• Brassard, G., Bratley, P. (1997). Fundamentos de Algoritmia.
• Guerequeta, R., Vallecillo, A. (1998). Técnicas de diseño de
algoritmos.
• Joyanes, L. (2008). Fundamentos de programación: algoritmos,
estructura de datos y objetos.
• Knuth, D. (2011). The Art of Computer Programming, Volu-
mes 1-4. Third Edition.
• Martí, N., Ortega, Y., Verdejo, J.A. (2003). Estructuras de da-
tos y métodos algorítmicos: Ejercicios resueltos.
• Parker, A. Algorithms and Data Structures in C++. CRC Press.

A.M. Durán-Rosal 50/51


¿Preguntas?

También podría gustarte