09.05.2013 Views

Universidad Católica de la Santísima Concepción Mariella Gutiérrez ...

Universidad Católica de la Santísima Concepción Mariella Gutiérrez ...

Universidad Católica de la Santísima Concepción Mariella Gutiérrez ...

SHOW MORE
SHOW LESS

You also want an ePaper? Increase the reach of your titles

YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.

Algoritmos y Estructuras <strong>de</strong> Datos<br />

1. Conceptos Básicos<br />

1.1. Algoritmo<br />

¿Qué es un algoritmo?<br />

“Un algoritmo es un conjunto <strong>de</strong> instrucciones sencil<strong>la</strong>s, c<strong>la</strong>ramente especificado, que se <strong>de</strong>be seguir para<br />

resolver un problema.” Weiss, M.A.<br />

“Secuencia finita <strong>de</strong> instrucciones, cada una <strong>de</strong> <strong>la</strong>s cuales tiene un significado preciso y pue<strong>de</strong> ejecutarse con<br />

una cantidad finita <strong>de</strong> esfuerzo en un tiempo finito”. Aho, A.V.<br />

De manera adicional los algoritmos <strong>de</strong>ben cumplir con los siguientes criterios:<br />

Las instrucciones <strong>de</strong>ben ser c<strong>la</strong>ras, concisas y lo suficientemente básica para que se pueda realizar en<br />

forma manual (al menos en teoría).<br />

En todos los casos, el algoritmo termina <strong>de</strong>spués <strong>de</strong> ejecutar una cantidad finita <strong>de</strong> instrucciones.<br />

El algoritmo cumple al menos una tarea, produce al menos un valor, o ambos.<br />

Un algoritmo es una técnica <strong>de</strong> resolución <strong>de</strong> problemas apropiada para ponerse en práctica mediante un<br />

programa computacional, pero no está atado a <strong>la</strong> implementación.<br />

Ejemplo: Algoritmo para calcu<strong>la</strong>r <strong>la</strong> suma <strong>de</strong> los enteros que van <strong>de</strong> 1 a n.<br />

Resolución en lenguaje natural:<br />

a. Inicialice un contador con el valor 1.<br />

b. Agregue a una variable acumu<strong>la</strong>dora el valor que contiene el contador.<br />

c. Incremente el contador en 1.<br />

d. Repita los pasos b y c hasta que el contador sea mayor que n.<br />

Resolución en pseudolenguaje:<br />

a. Contador = 1<br />

b. Mientras Contador


Suma2 (int n)<br />

{ int resulta;<br />

}<br />

resulta = n*(n+1)/2;<br />

return(resulta);<br />

Cuando damos una solución algorítmica a un problema <strong>de</strong>bemos preguntarnos:<br />

¿La solución propuesta es <strong>la</strong> única forma <strong>de</strong> solucionar el problema?<br />

¿Existe una forma más sencil<strong>la</strong> <strong>de</strong> resolver el problema?<br />

¿Es <strong>la</strong> forma óptima <strong>de</strong> resolver el problema?<br />

¿Funciona correctamente con cualquier cantidad <strong>de</strong> trabajadores?<br />

Lo que se quiere lograr es dar solución a un problema a través <strong>de</strong> un programa computacional. Esta tarea es<br />

compleja y requiere <strong>de</strong> varios pasos:<br />

1. Formu<strong>la</strong>ción y especificación <strong>de</strong>l problema: fase <strong>de</strong> análisis <strong>de</strong> necesida<strong>de</strong>s<br />

2. Diseño <strong>de</strong> <strong>la</strong> solución<br />

Diseñar <strong>la</strong>s estructuras <strong>de</strong> datos: <strong>de</strong>bes ser diseñanas <strong>de</strong> manera que faciliten <strong>la</strong> programación.<br />

Formu<strong>la</strong>r el algoritmo en Seudocódigo: Cada instrucción en seudocódigo <strong>de</strong>scribe tareas que el<br />

programador pondrá en funcionamiento mediante una o más instrucciones <strong>de</strong>l lenguaje.<br />

Análisis <strong>de</strong>l diseño: Se divi<strong>de</strong> en tres fases: (1) Determinar factibilidad <strong>de</strong> <strong>la</strong> solución: facilidad,<br />

necesidad <strong>de</strong> memoria, <strong>de</strong>sempeño, etc. (2) Revisar y convalidar <strong>la</strong> <strong>de</strong>scripción hecha en seudocódigo.<br />

(3) Análisis <strong>de</strong> <strong>la</strong> complejidad <strong>de</strong>l algoritmo: medida <strong>de</strong> <strong>la</strong> cantidad <strong>de</strong> trabajo realizada.<br />

Otros criterios <strong>de</strong> análisis: c<strong>la</strong>ridad, mantenimiento, portabilidad, uso <strong>de</strong> recursos.<br />

3. Imp<strong>la</strong>ntación <strong>de</strong> <strong>la</strong> solución: traducción <strong>de</strong>l algoritmo en seudocódigo a un lenguaje <strong>de</strong> programación.<br />

Implica escoger el lenguaje apropiado.<br />

4. Prueba: Consta <strong>de</strong> dos partes: (1) I<strong>de</strong>ar un conjunto <strong>de</strong> pruebas que intenten que el programa falle. (2)<br />

Depuración: i<strong>de</strong>ntificar qué está mal y arreg<strong>la</strong>rlo, para hacer nuevamente pruebas.<br />

5. Documentación: incorporar al código todos los comentarios y explicaciones que lo hagan entendible a<br />

cualquier programador.<br />

1. 2. Análisis <strong>de</strong> Algoritmos<br />

La eficiencia <strong>de</strong> un <strong>de</strong>terminado algoritmo <strong>de</strong>pen<strong>de</strong> <strong>de</strong> <strong>la</strong> maquina, y <strong>de</strong> otros factores externos al propio diseño.<br />

Para comparar dos algoritmos sin tener en cuenta estos factores externos se usa <strong>la</strong> complejidad. Esta es una<br />

medida informativa <strong>de</strong>l tiempo <strong>de</strong> ejecución <strong>de</strong> un algoritmo, y <strong>de</strong>pen<strong>de</strong> <strong>de</strong> varios factores:<br />

• Los datos <strong>de</strong> entrada <strong>de</strong>l programa. Dentro <strong>de</strong> ellos, lo más importante es <strong>la</strong> cantidad, su disposición, etc.<br />

• La calidad <strong>de</strong>l código generado por el compi<strong>la</strong>dor utilizado para crear el programa.<br />

• La naturaleza y rapi<strong>de</strong>z <strong>de</strong> <strong>la</strong>s instrucciones empleadas por <strong>la</strong> máquina y <strong>la</strong> propia máquina.<br />

• La propia complejidad <strong>de</strong>l algoritmo base <strong>de</strong>l programa.<br />

Tipos <strong>de</strong> análisis<br />

• Peor caso (usualmente): T(n) = Tiempo máximo necesario para un problema <strong>de</strong> tamaño n<br />

• Caso medio (a veces): T(n) = Tiempo esperado para un problema cualquiera <strong>de</strong> tamaño n<br />

Requiere establecer una distribución estadística<br />

• Mejor caso (engañoso)<br />

<strong>Universidad</strong> <strong>Católica</strong> <strong>de</strong> <strong>la</strong> <strong>Santísima</strong> <strong>Concepción</strong> Mariel<strong>la</strong> <strong>Gutiérrez</strong> Valenzue<strong>la</strong><br />

Facultad <strong>de</strong> Ingeniería Docente Área Informática


En cualquier caso se <strong>de</strong>fine T(n) como el tiempo <strong>de</strong> ejecución <strong>de</strong>l peor caso, es <strong>de</strong>cir, el máximo valor <strong>de</strong>l<br />

tiempo <strong>de</strong> ejecución para <strong>la</strong>s entradas <strong>de</strong> tamaño n.<br />

Por ejemplo algunos programas pue<strong>de</strong>n tener un tiempo <strong>de</strong> ejecución. T(n)=Cn 2 , don<strong>de</strong> C es una constante que<br />

engloba <strong>la</strong>s características <strong>de</strong> <strong>la</strong> máquina y otros factores.<br />

Las unida<strong>de</strong>s <strong>de</strong> T(n) se <strong>de</strong>jan sin especificar, pero se pue<strong>de</strong> consi<strong>de</strong>rar a T(n) como el número <strong>de</strong><br />

instrucciones ejecutadas en un computador i<strong>de</strong>alizado y es lo que se entien<strong>de</strong> por complejidad.<br />

Base Matemática<br />

Definición 1: T(n) = O(f(n)), si existen constantes c y n0 tales que T(n) =n0<br />

Definición 2: T(n) = Ω(g(n)), si existen constantes c y n0 tales que T(n) >= cg(n) cuando n>=n0<br />

Definición 3: T(n) = Θ(h(n)) si y solo si T(n) = O(h(n)) y T(n) = Ω(h(n))<br />

Definición 4: T(n) = o(p(n)) si T(n) = O(p(n)) y T(n) ? Θ(p(n))<br />

El objetivo <strong>de</strong> estas <strong>de</strong>finiciones es establecer un or<strong>de</strong>n re<strong>la</strong>tivo entre dos funciones. Generalmente esto se<br />

hace en base a su tasa <strong>de</strong> crecimiento. No tiene sentido <strong>de</strong>cir que f(n) < g(n).<br />

Ejemplo: Sea f(n) = 1000n y g(n)= n 2 . Se tiene que f es mayor que g para valores pequeños <strong>de</strong> n, pero n 2 crece<br />

con una tasa mayor, así g será finalmente <strong>la</strong> función mayor. El punto <strong>de</strong> cambio es n = 1000.<br />

2500000<br />

2000000<br />

1500000<br />

1000000<br />

500000<br />

0<br />

200 400 600 800 1000 1200 1400<br />

n<br />

Si se consi<strong>de</strong>ra <strong>la</strong> <strong>de</strong>finición 1: T(n) = O(f(n)), si existen constantes c y n0 tales que T(n) =n0<br />

Suponga T(n)= 1000n y f(n)= n 2 , n0=1000 y c = 1, entonces 1000n =1000.<br />

Se pue<strong>de</strong> <strong>de</strong>cir que T(n) = O(n 2 ), es <strong>de</strong>cir, el tiempo <strong>de</strong> ejecución T es <strong>de</strong>l "or<strong>de</strong>n n cuadrada". En <strong>la</strong> <strong>de</strong>finición1<br />

se establece una cota superior para el tiempo <strong>de</strong> ejecución T(n).<br />

La <strong>de</strong>finición 2 establece una cota inferior para el tiempo <strong>de</strong> ejecución.<br />

En <strong>la</strong> <strong>de</strong>finición 3 se dice que el tiempo <strong>de</strong> ejecución es exactamente igual a una función.<br />

La <strong>de</strong>finición 4 establece una cota superior que nunca se alcanza.<br />

Ejemplo: f(n)= n 2 y g(n)= n 3 , <strong>la</strong> tasa <strong>de</strong> crecimiento <strong>de</strong> g es mayor que f si consi<strong>de</strong>ramos los enteros positivos.<br />

<strong>Universidad</strong> <strong>Católica</strong> <strong>de</strong> <strong>la</strong> <strong>Santísima</strong> <strong>Concepción</strong> Mariel<strong>la</strong> <strong>Gutiérrez</strong> Valenzue<strong>la</strong><br />

Facultad <strong>de</strong> Ingeniería Docente Área Informática<br />

f(n)<br />

g(n)


600<br />

500<br />

400<br />

300<br />

200<br />

100<br />

0<br />

1 2 3 4 5 6 7 8<br />

Se pue<strong>de</strong> <strong>de</strong>cir que: f(n)=O(g(n)) y g(n)=Ω(f(n))<br />

Reg<strong>la</strong>1: Si T1(n)=O(f(n)) y T2(n)=O(g(n)), entonces<br />

a) T1(n) + T2(n) = máx(O(f(n)),O(g(n))),<br />

b) T1(n) * T2(n) = O(f(n)*g(n))<br />

Reg<strong>la</strong>2: Si T(x) es un polinomio <strong>de</strong> grado n, entonces<br />

a) T(x) = O(x n )<br />

n<br />

Reg<strong>la</strong>3: log k n = O(n) para cualquier k constante. Esto indica que los logaritmos crecen muy lentamente.<br />

Ejemplo: f(n)=n 2 y g(n)=n, entonces g(n) =n0, entonces O(f(n) + g(n)) = O(f(n)), es <strong>de</strong>cir,<br />

O(n 2 + n) = O(n 2 )<br />

Ejemplo: f(n)=c y g(n)= n 2 , f(n)*g(n)=cn 2 entonces si c es una constante positiva O(f(n)*g(n))=O(g(n)), es <strong>de</strong>cir,<br />

O(2n 2 ) = O(n 2 ) si c=2.<br />

Tasas <strong>de</strong> crecimiento típicas<br />

Se dice que O(f(n)) <strong>de</strong>fine un "or<strong>de</strong>n <strong>de</strong> complejidad". Se pue<strong>de</strong> <strong>de</strong>finir una jerarquía <strong>de</strong> ór<strong>de</strong>nes <strong>de</strong><br />

complejidad, dado por <strong>la</strong> siguiente tab<strong>la</strong>:<br />

Función Nombre<br />

c or<strong>de</strong>n constante<br />

log n or<strong>de</strong>n logarítmico<br />

log 2 n or<strong>de</strong>n logarítmica cuadrada<br />

n or<strong>de</strong>n lineal<br />

n log n<br />

n 2 or<strong>de</strong>n cuadrático<br />

n a or<strong>de</strong>n polinomial (a > 2)<br />

2 n or<strong>de</strong>n exponencial<br />

n! or<strong>de</strong>n factorial<br />

Impacto Práctico<br />

Suponga que tiene un problema que se pue<strong>de</strong> resolver con algoritmos <strong>de</strong> diferentes complejida<strong>de</strong>s, y que se<br />

dispone <strong>de</strong> 1000 segundos para resolver el problema. Interesa respon<strong>de</strong>r a:<br />

<strong>Universidad</strong> <strong>Católica</strong> <strong>de</strong> <strong>la</strong> <strong>Santísima</strong> <strong>Concepción</strong> Mariel<strong>la</strong> <strong>Gutiérrez</strong> Valenzue<strong>la</strong><br />

Facultad <strong>de</strong> Ingeniería Docente Área Informática<br />

g(n)<br />

f(n)


• ¿Qué tamaño <strong>de</strong>l problema se pue<strong>de</strong> resolver?<br />

• ¿Qué suce<strong>de</strong> si se dispone <strong>de</strong> una máquina 10 veces más rápida sin costo adicional?<br />

• ¿Qué tamaño <strong>de</strong> problema se pue<strong>de</strong> resolver?<br />

T(n)=O(f(n))<br />

Tamaño máx <strong>de</strong>l problema<br />

para 10 3 seg<br />

Tamaño máx <strong>de</strong>l problema<br />

para 10 4 seg<br />

100n 10 100 10<br />

5n 2 14 45 3.2<br />

n 3 /2 12 27 2.3<br />

2 n 10 13 1.3<br />

Reg<strong>la</strong>s <strong>de</strong> cálculo <strong>de</strong> complejidad <strong>de</strong> T(n)<br />

Incremento en el tamaño<br />

máximo <strong>de</strong>l problema<br />

• El tiempo <strong>de</strong> ejecución <strong>de</strong> cada sentencia simple, por lo común pue<strong>de</strong> tomarse como O(1).<br />

• El tiempo <strong>de</strong> ejecución <strong>de</strong> una secuencia <strong>de</strong> proposiciones se <strong>de</strong>termina por <strong>la</strong> reg<strong>la</strong> <strong>de</strong> <strong>la</strong> suma. Es el<br />

máximo tiempo <strong>de</strong> ejecución <strong>de</strong> una proposición <strong>de</strong> <strong>la</strong> sentencia.<br />

• Para <strong>la</strong>s sentencias <strong>de</strong> bifurcación (IF, CASE) el or<strong>de</strong>n resultante será el <strong>de</strong> <strong>la</strong> bifurcación con mayor<br />

or<strong>de</strong>n.<br />

• Para los bucles es el or<strong>de</strong>n <strong>de</strong>l cuerpo <strong>de</strong>l bucle sumado tantas veces como se ejecute el bucle.<br />

• El or<strong>de</strong>n <strong>de</strong> una l<strong>la</strong>mada a un subprograma no recursivo es el or<strong>de</strong>n <strong>de</strong>l subprograma.<br />

Reg<strong>la</strong>s Prácticas<br />

Aunque no existe una receta que siempre funcione para calcu<strong>la</strong>r <strong>la</strong> complejidad <strong>de</strong> un algoritmo, si es posible<br />

tratar sistemáticamente una gran cantidad <strong>de</strong> ellos, basándonos en que suelen estar bien estructurados y<br />

siguen pautas uniformes. Los algoritmos bien estructurados combinan <strong>la</strong>s sentencias <strong>de</strong> alguna <strong>de</strong> <strong>la</strong>s formas<br />

siguientes:<br />

• secuencia (;)<br />

• <strong>de</strong>cisión (IF ... THEN ... ELSE ...)<br />

• bucles (WHILE, REPEAT, FOR)<br />

• l<strong>la</strong>madas a procedimientos<br />

1. Sentencias sencil<strong>la</strong>s<br />

Correspon<strong>de</strong>n a <strong>la</strong>s sentencias <strong>de</strong> asignación, entrada/salida, etc. siempre y cuando no trabajen sobre variables<br />

estructuradas cuyo tamaño este re<strong>la</strong>cionado con el tamaño N <strong>de</strong>l problema. La inmensa mayoría <strong>de</strong> <strong>la</strong>s<br />

sentencias <strong>de</strong> un algoritmo requieren un tiempo constante <strong>de</strong> ejecución, siendo su complejidad O(1).<br />

2. Secuencia (;)<br />

La complejidad <strong>de</strong> una serie <strong>de</strong> elementos <strong>de</strong> un programa es <strong>de</strong>l or<strong>de</strong>n <strong>de</strong> <strong>la</strong> suma <strong>de</strong> <strong>la</strong>s complejida<strong>de</strong>s<br />

individuales, aplicándose <strong>la</strong>s operaciones arriba expuestas.<br />

3. Decisión (IF ... THEN ... ELSE ... END)<br />

La condición suele ser <strong>de</strong> O(1), complejidad a sumar con <strong>la</strong> peor posible, o bien en <strong>la</strong> rama THEN o en <strong>la</strong> rama<br />

ELSE. En <strong>de</strong>cisiones múltiples (ELSIF, CASE), se tomara <strong>la</strong> peor <strong>de</strong> <strong>la</strong>s ramas.<br />

<strong>Universidad</strong> <strong>Católica</strong> <strong>de</strong> <strong>la</strong> <strong>Santísima</strong> <strong>Concepción</strong> Mariel<strong>la</strong> <strong>Gutiérrez</strong> Valenzue<strong>la</strong><br />

Facultad <strong>de</strong> Ingeniería Docente Área Informática


4. Bucles (WHILE, REPEAT, FOR)<br />

En los bucles con contador explícito, po<strong>de</strong>mos distinguir dos casos, que el tamaño N forme parte <strong>de</strong> los límites<br />

o que no. Si el bucle se realiza un número fijo <strong>de</strong> veces, in<strong>de</strong>pendiente <strong>de</strong> N, entonces <strong>la</strong> repetición sólo<br />

introduce una constante multiplicativa que pue<strong>de</strong> absorberse.<br />

Ejemplos<br />

Ejemplo: K constante<br />

FOR i:= 1 TO K DO<br />

algo_<strong>de</strong>_O(1) ; => K*O(1) = O(1)<br />

END;<br />

Ejemplo: Si el tamaño N aparece como límite <strong>de</strong> iteraciones<br />

FOR i:= 1 TO N DO<br />

algo_<strong>de</strong>_O(1) => N * O(1) = O(n)<br />

END;<br />

Ejemplo: Ciclo for anidados<br />

FOR i:= 1 TO N DO<br />

FOR j:= 1 TO N DO => Se tiene N * N * O(1) = O(n 2 )<br />

algo_<strong>de</strong>_O(1)<br />

Ejemplo: Ciclo for anidados<br />

FOR i:= 1 TO N DO<br />

FOR j:= 1 TO K DO => Se tiene N * K * O(1) = O(N)<br />

algo_<strong>de</strong>_O(1)<br />

Ejemplo: Ciclo for anidados<br />

FOR i:= 1 TO N DO<br />

FOR j:= 1 TO i DO<br />

algo_<strong>de</strong>_O(1)<br />

El bucle exterior se realiza N veces, mientras que el interior se realiza 1, 2, 3, ... N veces respectivamente.<br />

1 + 2 + 3 + ... + N = N*(1+N)/2 -> O(n 2 )<br />

A veces aparecen bucles multiplicativos, don<strong>de</strong> <strong>la</strong> evolución <strong>de</strong> <strong>la</strong> variable <strong>de</strong> control no es lineal (como en los<br />

casos anteriores)<br />

Ejemplo:<br />

c:= 1;<br />

WHILE c < N DO<br />

algo_<strong>de</strong>_O(1)<br />

c:= 2*c;<br />

El valor inicial <strong>de</strong> "c" es 1, siendo "2 k " al cabo <strong>de</strong> "k" iteraciones. El número <strong>de</strong> iteraciones es tal que<br />

2 k >= N => k = log2 N [el entero inmediato superior] y por tanto, <strong>la</strong> complejidad <strong>de</strong>l bucle es O(log n).<br />

Ejemplo: c:= N;<br />

WHILE c > 1 DO<br />

algo_<strong>de</strong>_O(1)<br />

c:= c/2;<br />

<strong>Universidad</strong> <strong>Católica</strong> <strong>de</strong> <strong>la</strong> <strong>Santísima</strong> <strong>Concepción</strong> Mariel<strong>la</strong> <strong>Gutiérrez</strong> Valenzue<strong>la</strong><br />

Facultad <strong>de</strong> Ingeniería Docente Área Informática


Un razonamiento análogo nos lleva a log2(N) iteraciones y, por tanto, a un or<strong>de</strong>n O(log n) <strong>de</strong> complejidad.<br />

Ejemplo: FOR i:= 1 TO N DO<br />

c:= i;<br />

WHILE c > 0 DO<br />

algo_<strong>de</strong>_O(1)<br />

c:= c/2;<br />

Tenemos un bucle interno <strong>de</strong> or<strong>de</strong>n O(log n) que se ejecuta N veces, luego el conjunto es <strong>de</strong> or<strong>de</strong>n O(n log n)<br />

5. L<strong>la</strong>madas a procedimientos<br />

La complejidad <strong>de</strong> l<strong>la</strong>mar a un procedimiento viene dada por <strong>la</strong> complejidad <strong>de</strong>l contenido <strong>de</strong>l procedimiento en<br />

sí. El coste <strong>de</strong> l<strong>la</strong>mar no es sino una constante que po<strong>de</strong>mos obviar inmediatamente <strong>de</strong>ntro <strong>de</strong> nuestros análisis<br />

asintóticos. El cálculo <strong>de</strong> <strong>la</strong> complejidad asociada a un procedimiento pue<strong>de</strong> complicarse notablemente si se<br />

trata <strong>de</strong> procedimientos recursivos. Es fácil que tengamos que aplicar técnicas propias <strong>de</strong> <strong>la</strong> matemática<br />

discreta, tema que queda fuera <strong>de</strong> los límites <strong>de</strong> esta nota técnica.<br />

Propieda<strong>de</strong>s<br />

n<br />

1. ∑ 2 i = 2 n+1 -1 4. log (a b ) = b log a 7. logb x = logc x / logc b<br />

i=0<br />

n n<br />

2. ∑ 2 i = ∑ 2 i - 2 0 = 2 n+1 -1 - 1= 2 n+1 – 2 5. log (ab) = log a + log b<br />

i=1 i=0<br />

n<br />

3. ∑ i ≈ n 2 /2 6. log (a/b) = log a – log b<br />

i=1<br />

Ejercicio<br />

Problema: Calcu<strong>la</strong>r números <strong>de</strong> Fibonacci<br />

La secuencia Fibonacci se <strong>de</strong>fine como: 0, 1, 1, 2, 3, 4, 8, 13, ….<br />

Se inicia F0 = 0 ; F1 = 1; y el siguiente número se calcu<strong>la</strong> sumando los dos anteriores. Por ejemplo:<br />

Entonces:<br />

F(3) = F(2) + F(1) = 1 + 1 = 2<br />

F(4) = F(3) + F(2) = 2 + 1 = 3<br />

F0 = 0<br />

F1 = 1<br />

Fn = Fn-1 + Fn-2, don<strong>de</strong> n >=2<br />

Comprensión <strong>de</strong>l Problema:<br />

• Se <strong>de</strong>be diseñar e implementar una función que acepte un entero no negativo como argumento n y<br />

<strong>de</strong>vuelva el valor <strong>de</strong> F(n).<br />

• Si se le entrega un valor negativo como argumento <strong>la</strong> función <strong>de</strong>be hacer algo razonable.<br />

Estructura <strong>de</strong> datos:<br />

Se usarán variables enteras para calcu<strong>la</strong>r cada número <strong>de</strong> Fibonacci.<br />

<strong>Universidad</strong> <strong>Católica</strong> <strong>de</strong> <strong>la</strong> <strong>Santísima</strong> <strong>Concepción</strong> Mariel<strong>la</strong> <strong>Gutiérrez</strong> Valenzue<strong>la</strong><br />

Facultad <strong>de</strong> Ingeniería Docente Área Informática


Seudocódigo<br />

Si se utiliza <strong>la</strong> <strong>de</strong>finición formar <strong>de</strong> <strong>la</strong> serie <strong>de</strong> Fibonacci, se tiene:<br />

Versión 1:<br />

Fib (n)<br />

If n = 0<br />

Return (0);<br />

If n = 1<br />

Return (1);<br />

For i = 2 to n<br />

fib = fmin1 + fmin2;<br />

Actualizar fmin1 y fmin2;<br />

Return (fib)<br />

Este seudocódigo presenta algunos problemas como:<br />

• No se han inicializado variables.<br />

• No resuelve el caso <strong>de</strong> números negativos.<br />

• No se explicita como se actualiza fmin1 y fmin2.<br />

Versión 2:<br />

Fib (n)<br />

If n < 0<br />

Return (-1);<br />

If n = 0<br />

Return (0);<br />

If n = 1<br />

Return (1);<br />

fmin1 = 0;<br />

fmin2 = 1;<br />

For i = 2 to n<br />

fib = fmin1 + fmin2;<br />

fmin2 = fmin1;<br />

fmin1 = fib;<br />

Return (fib)<br />

Análisis <strong>de</strong>l algoritmo:<br />

Fib (n)<br />

If n < 0<br />

Return (-1); O(1)<br />

If n = 0<br />

Return (0); O(1)<br />

If n = 1<br />

Return (1); O(1)<br />

fmin1 = 0; O(1)<br />

fmin2 = 1; O(1)<br />

For i = 2 to n El ciclo se ejecuta (n-1) veces. Se tiene 3*(n-1) => 3n => O(n)<br />

fib = fmin1 + fmin2; O(1)<br />

fmin2 = fmin1; O(1)<br />

fmin1 = fib; O(1)<br />

Return (fib) O(1) Resultado: El algoritmo es <strong>de</strong> or<strong>de</strong>n lineal, O(n)<br />

<strong>Universidad</strong> <strong>Católica</strong> <strong>de</strong> <strong>la</strong> <strong>Santísima</strong> <strong>Concepción</strong> Mariel<strong>la</strong> <strong>Gutiérrez</strong> Valenzue<strong>la</strong><br />

Facultad <strong>de</strong> Ingeniería Docente Área Informática


Implementación<br />

El algoritmo en seudocódigo permite hacer una traducción directa a lenguaje C.<br />

int Fib ( int n)<br />

{<br />

int i;<br />

int fibn, fib1, fib2;<br />

}<br />

If (n < 0)<br />

return (-1);<br />

If (n == 0)<br />

return (0);<br />

If (n == 1)<br />

return (1);<br />

fibn = 0;<br />

fib1 = 0; /* F(n-2) */<br />

fib2 = 1; /* F(n-1) */<br />

for (i = 2; I


Ejercicios<br />

n<br />

1. Escriba un algoritmo para calcu<strong>la</strong>r ∑ i 3<br />

Evaluar el or<strong>de</strong>n <strong>de</strong>l algoritmo i=1<br />

2. Analice el tiempo <strong>de</strong> ejecución <strong>de</strong> los siguientes algoritmos para calcu<strong>la</strong>r x n :<br />

Algoritmo 1:<br />

función potencia(x,n) {don<strong>de</strong> x y n son enteros positivos}<br />

comienzo<br />

si n = 0 entonces<br />

potencia = 1;<br />

sino<br />

si n=1 entonces<br />

potencia = x<br />

sino<br />

potencia = x<br />

para i = 2 hasta n haga<br />

potencia = potencia * x<br />

fin para<br />

fin<br />

fin<br />

fin {potencia}<br />

Algoritmo 2:<br />

función potencia(x,n) {don<strong>de</strong> x y n son enteros positivos}<br />

comienzo<br />

si n = 0 entonces<br />

potencia = 1;<br />

sino<br />

si n=1 entonces<br />

potencia = x<br />

sino<br />

si n es par entonces<br />

potencia = potencia(x*x, n div 2)<br />

sino<br />

potencia = potencia( x * x, n div 2) * x<br />

fin<br />

fin<br />

fin<br />

fin {potencia}<br />

3. Escriba un algoritmo recursivo para visualizar los dígitos <strong>de</strong> un número entero no negativo.<br />

Evaluar el or<strong>de</strong>n <strong>de</strong>l algoritmo.<br />

<strong>Universidad</strong> <strong>Católica</strong> <strong>de</strong> <strong>la</strong> <strong>Santísima</strong> <strong>Concepción</strong> Mariel<strong>la</strong> <strong>Gutiérrez</strong> Valenzue<strong>la</strong><br />

Facultad <strong>de</strong> Ingeniería Docente Área Informática

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!