CONTENIDO DE LA LECCIÓN 11

Tamaño: px
Comenzar la demostración a partir de la página:

Download "CONTENIDO DE LA LECCIÓN 11"

Transcripción

1 CONTENIDO DE LA LECCIÓN 11 RECURSIVIDAD 1. Introducción 2 2. Ejemplos de recursividad Ejemplos 11.1, 11.2, 11.3, 11.4, 11.5, 11.6, 3 3. Funcionamiento interno de la recursividad Ejemplos 11.7, 11.8, 11.9, Soluciones no recursivas (iterativas) Ejemplos 11.10, 11.11, El problema de las Torres de Hanoi Ejemplo Uso de las pilas para simular recursividad El problema de las ocho reinas Ejemplo Casos interesantes Ejemplo 11.15: Información genealógica Ejemplo 11.16: Árboles similares Ejemplo 11.17: Árboles no similares Retroceso Programación no determinista Retroceso cronológico Retroceso de dependencia dirigida Uso de la recursividad Examen breve Lo que necesita saber Preguntas y problemas Preguntas Problemas

2 LECCIÓN 11 RECURSIVIDAD INTRODUCCIÓN Una función que se llama a sí mismo se dice que es recursiva. La recursividad en las funciones puede darse de dos maneras diferentes: a. Directa. La función se llama directamente a sí misma. Por ejemplo, observe la figura 11.1, funciona() es una función y en alguna parte de ella aparece una llamada a sí misma: funciona() Llamada a funciona() Figura Recursividad directa b. Indirecta. La función llama a otra función y esta a su vez llama a la primera. Por ejemplo, en la figura 11.2a la función funciona() llama a la función funcionb() y esta a su vez invoca a la primera; es decir el control regresa a funciona(). funciona() Llamada a funcionb() funcionb() Llamada a funciona() funciona() Llamada a funcionb() funcionb() Llamada a funcionc() funcionc() a) b) Figura Recursividad indirecta También se da la recursividad indirecta cuando una función llama a otra y ésta a una tercera. Una vez ejecutada, el control regresa a la función que la llamó, lo mismo sucede en todos los niveles. Por ejemplo, en la figura 11.2b la función funciona() llama a la función funcionb(), y esta llama a la función funcionc() Cuando funcionc() concluye, el control regresa a funcionb(); y al terminar ésta, el control se transfiere a funciona() 11-2

3 En toda definición recursiva de un problema se debe establecer un estado básico (estado primitivo, estado de salida o estado de terminación) Es decir, un estado en el cual la solución no se presente de manera recursiva sino directamente. Además la entrada (datos) del problema debe ir acercándose al estado básico. Si dada la definición de un problema es posible determinar el estado básico y el acercamiento paulatino al mismo, entonces se puede llegar a una solución. En otro caso se estaría en presencia de una definición circular del problema. Es importante comprender que cada instanciación (copia activa) de una función recursiva es totalmente peculiar y tiene sus propios argumentos, variables locales, direcciones de retorno, etc. Objetivos de esta lección: Comprender y manejar el concepto de recursividad. Aprender como se escriben y utilizan funciones que se llaman a sí mismas. Resolver problemas utilizando recursividad. Los ejemplos que aparecen a continuación, a pesar de que pueden resolverse de manera no recursiva permiten ilustrar claramente el concepto de recursividad. EJEMPLOS DE RECURSIVIDAD Ejemplo 11.1 Solución Escriba una función recursiva C++ para encontrar la suma de todos los enteros desde 1 hasta N. Piense en esta operación por un minuto. No es una operación recursiva clásica? Para encontrar la suma de enteros de 1 a 5, podría adicionar 5 a la suma de enteros de 1 a 4? Entonces, para encontrar la suma de 1 a 4, adiciona 4 a la suma de enteros de 1 a 3, y así sucesivamente, correcto? Expresada en símbolos: sumanumeros(5) = 5 + sumanumeros(4) sumanumeros(4) = 4 + sumanumeros(3) sumanumeros(3) = 3 + sumanumeros(2) sumanumeros(2) = 2 + sumanumeros(1) sumanumeros(1) = 1 Observe que sumanumeros(1) es el estado básico, porque su valor es conocido. Ahora, traduciendo este proceso a una función recursiva, se obtiene: sumanumero s( n) 1 n + sumanumeros( n 1) Si Si n = n > 1 1 Esta expresión se puede expresar en seudocódigo como sigue: 11-3

4 Ejemplo 11.2 sumanumeros(n) si (n == 1) entonces regresar (1). si no regresar ( n + sumanumeros(n-1)). La función C++ se codifica entonces directamente desde el algoritmo como: /************************************************************* Esta función recursiva calculará la suma de los enteros entre 1 hasta N *************************************************************/ int sumanumeros(int n) if(n == 1) return (1) else return (n + sumanumeros(n 1)) // Fin de sumanumeros() Algoritmo sumanumeros El siguiente programa: SUMAENT.CPP, muestra el uso del algoritmo 11.1 /* Este programa: SUMAENT.CPP, calcula la suma de los números enteros positivos comprendidos entre 1 y el número dado. */ #include <iostream.h> //Para cin y cout int sumanumeros(int n); void main(void) int n; /* Tener en cuenta que el valor devuelto es de la clase int. Por lo tanto la suma esta limitada a un máximo de 32767, en caso contrario se producirá un sobreflujo. */ cout << "Dame un número entero mayor que cero: "; cin >> n; cout << "\nla suma de los números enteros comprendidos entre 1 y " << n << " es: " << sumanumeros(n) << endl; int sumanumeros(int n) if(n == 1) return(1); else return(n + sumanumeros(n-1)); 11-4

5 Ejemplo 11.3 Factorial de un número: La notación n! se lee factorial de n e indica el producto de los enteros positivos desde 1 hasta n. Por ejemplo: 3! = ! = ! = n! = (n-2) (n-1) (n) También definimos 1! = 1 y 0! = 1. Si se le pide que desarrolle una función que calcule el factorial de un número, cómo le haría? Si invertimos la definición de la fórmula tenemos: n! = n (n-1) (n-2) Por lo tanto, 4! = Observe que es 3!; entonces, podemos definir 4! de manera recursiva como: En general, podemos definir n! como: 4! = 4 3! n! = n (n-1)! (n-1)! = (n-1) (n-2)! (n-2)! = (n-2) (n-3)!... Llegamos a definir entonces, el factorial de un número n en términos del factorial del número (n-1) de la siguiente manera: 1 n! = n ( n 1)! Si Si n = 0 n > 1 o n = 1 En la definición recursiva del factorial se da un estado básico (si n = 0 o n = 1, entonces el factorial vale 1), en el cual el problema ya no se define en términos de sí mismo sino que se asigna un valor directamente. En el paso recursivo de la fórmula se utiliza el concepto de factorial aplicado a (n-1) Por ser un número entero positivo será (n-1) un valor más cercano al estado básico (n = 0 o n = 1) Una vez establecida la definición recursiva de los números factoriales, podemos comenzar a formular un algoritmo recursivo. Considere el siguiente seudocódigo: factorial(n) INICIO x = n -1. calcular x!. // (n-1)! regresar(n x!). // n! = n (n -1)! FIN. La función factorial() estima el valor de n! calculando el valor de (n-1)! y luego multiplicando el resultado por n. Sin embargo, como ya habrá notado, la segunda instrucción no está definida de modo correcto: tenemos que encontrar una forma de calcular el valor de x!. Si lo piensa bien, verá que ya tenemos una: factorial() Esta función calcula el factorial de un número. Apliquemos este conocimiento y volvamos a escribir la rutina como: 11-5

6 factorial(n) INICIO x = factorial(n-1). // (n-1)! regresar(n x). // n! = n (n -1)! FIN. Ahora bien, cuando calcule el valor de n!, la función se llamará a sí misma de modo recursivo para estimar el valor de (n-1)!. Cabe preguntarnos si la función está completa. Mirémosla con detenimiento y analicemos su ejecución cuando calcula 2!. El procesamiento se inicia cuando se llama a la función con un argumento de 2. Entonces ésta calcula 2! recursivamente llamándose a sí misma con un argumento de 1; para estimar 1!, vuelve a llamarse a sí misma otra vez con un argumento de 0. La tercera copia (instancia) de la función se llamará a sí misma con un argumento de 1, la siguiente con 2, y así sucesivamente. El problema está más claro ahora: la función es recursiva hasta el infinito. Todas las funciones recursivas necesitan una forma de detenerse, a la que hemos denominado estado básico o primitivo. Se coloca, por lo común, en la parte superior de una función recursiva, y contiene instrucciones que al final terminan la recursividad y comienzan a desapilar todas las llamadas anidadas. Si se le omite o está incorrecta, como acabamos de ver, el funcionamiento puede convertirse en infinitamente recursivo. Volviendo a nuestro ejemplo, identifiquemos un estado básico para la función factorial(). Por definición, sabemos que 0! = 1 y que 1! = 1. Por lo tanto, podemos añadir revisiones para estos valores en la parte superior del procedimiento, de este modo: factorial(n) INICIO si(n == 0 o n == 1) regresar(1). FIN. regresar(n * factorial(n-1)). Ahora, cuando se le llame con un argumento de 0 o 1, la función devolverá un valor explícito en lugar de realizar otra llamada recursiva. (Observe que hemos eliminado la innecesaria variable temporal x de nuestro algoritmo) Pero aún tenemos otro problema. La función puede ser llamada al comienzo con un argumento negativo. Por lo tanto, debemos añadir una revisión más para asegurar que la función ha sido llamada de modo apropiado: factorial(n) INICIO si(n < 0) /* Revisa Argumentos erróneos */ regresar(-1). si(n == 0 n == 1) regresar(1). regresar(n * factorial(n-1)). FIN. A continuación se muestra la versión final escrita en C++. int factorialrecurrente(int n) if(n < 0) /* Revisa argumentos erróneos */ return(-1); 11-6

7 if(n == 0 n == 1) return(1); return(n * factorialrecurrente(n-1)); Algoritmo 11.2: factorialrecurrente Ejemplo 11.4 Serie de Fibonacci: Otro caso clásico de problemas definidos recursivamente es el cálculo de la serie de Fibonacci: 0, 1, 1, 2, 3, 5, 8, 13, 21,..., etc. Recuérdese que el Fibonacci de un número se obtiene de la suma de los dos números Fibonacci anteriores. A continuación se ilustrará el concepto de números Fibonacci: Por definición: Fibonacci(0) = 0 Fibonacci(1) = 1 Los demás números de la serie en base a la definición son: Fibonacci(2) = Fibonacci(1) + Fibonacci(0) = = 1 Fibonacci(3) = Fibonacci(2) + Fibonacci(1) = = 2 Fibonacci(4) = Fibonacci(3) + Fibonacci(2) = = 3 La definición en forma recursiva de la serie de Fibonacci será: n Fibonacci ( n) = fibonacci( n 1) + fibonacci( n 2) Si Sí ( n = 0) n > 1 o ( n = 1) En este ejemplo el estado básico se presenta cuando n es cero o es uno. En el paso recursivo de la fórmula se utiliza el concepto de Fibonacci aplicado a (n-1) y (n-2) Por ser n un número entero positivo serán (n-1) y (n-2) valores más cercanos al estado básico. Empecemos ahora a construir una solución recursiva: fibonaccirecursivo(n) INICIO si(n < 0) regresar(-1). /* Argumento erróneo */ si((n = 0) o (n == 1)) regresar(n). FIN. regresar(fibonaccirecursivo(n-1) + fibonaccirecursivo(n-2)). Esta solución tiene un error, la verificación n < 0, que busca un argumento erróneo, solo es válida la primera vez, en llamadas subsecuentes a la función no tiene sentido. Por lo tanto se hace necesario realizar algunas modificaciones al algoritmo anterior: fibonaccirecursivoinicial(n) INICIO si(n < 0) regresar(-1). /* Argumento erróneo */ 11-7

8 FIN. regresar(fibonaccirecursivo(n)). fibonaccirecursivo(n) INICIO si((n == 0) o (n == 1)) regresar(n). FIN. regresar(fibonaccirecursivo(n-1) + fibonaccirecursivo(n-2)). La versión en C++ del algoritmo anterior es: int fibonaccirecursivoinicial(n) if(n < 0) return(-1); return(fibonaccirecursivo(n)); int fibonaccirecursivo(n) if((n == 0) (n == 1)) return(n); return(fibonaccirecursivo(n - 1) + fibonaccirecursivo(n - 2)); Algoritmo 11.3: fibonaccirecursivo Ejemplo 11.5 El siguiente programa: FIBONA1.CPP, ilustra el uso del algoritmo /* El siguiente programa: FIBONA1.CPP, calcula los n términos de la serie de Fibonacci */ #include <iostream.h> //Para cout y cin int fibonaccirecursivoinicial(int n); int fibonaccirecursivo(int n); void main(void) int n; cout << "Dame el número de términos a calcular: "; cin >> n; cout << endl; while(n > 0) cout << "El valor del término " << n << " de la serie de Fibonacci es: " << fibonaccirecursivoinicial(n - 1) << endl; n = n - 1; 11-8

9 int fibonaccirecursivoinicial(n) if(n < 0) return(-1); return(fibonaccirecursivo(n)); int fibonaccirecursivo(n) if((n == 0) (n == 1)) return(n); return(fibonaccirecursivo(n - 1) + fibonaccirecursivo(n - 2)); Ejemplo 11.6 En este ejemplo presentamos el caso de una inversión en una institución bancaria. Se ha depositado un capital m por el cual se recibe un x% de interés anual. El problema consiste en determinar el capital que se tendrá al cabo de n años. Supóngase que m = $ y x = 10%, entonces: C 0 = 5000 C 1 = C 0 + C 0 * 10% C 2 = C 1 + C 1 * 10% [Capital Inicial] [Capital al finalizar el primer año de inversión] [Capital al finalizar el segundo año de inversión] En general, al cabo de n años se tendrá que: C n = C n-1 + C n-1 * 10% o C n = 1.10 * C n-1 Se llega a una definición recursiva del cálculo de inversiones. C n m = (1 + x)* C Sí n = 0 n 1 Sí n 0 > Nuevamente se cuenta con un estado básico, para n = 0, y un acercamiento a él en la otra expresión de la fórmula. El siguiente algoritmo presenta una solución recursiva del cálculo de una inversión: balance(n, m, x) FIN. INICIO si(n = 0) entonces regresar(m). //Estado básico sino regresar((1+x) * balance((n-1), m, x). Para simplificar el ejemplo: sí definimos el capital inicial m y la tasa x como variables globales; y la recapitalización es mensualmente tendremos: float balance(int m) if (n == 0) 11-9

10 return (m); else return((1 + x / 12 / 100) * balance(n 1)); //Fin de balance() Algoritmo 11.4: balance Esto es todo lo que hay que hacer! Esta función calculará al final de cualquier mes n que pase por la función. Observe cómo la función se llama a si misma en la cláusula else. Cuando la computadora encuentra la llamada recursiva en la cláusula else, deberá temporalmente retrasar el cálculo para evaluar la llamada de la función recursiva justo como se hizo el cálculo de interés compuesto. Cuando encuentra la cláusula else por segunda vez, la función se llama a sí misma otra vez y se mantiene llamándose cada vez que se ejecuta la cláusula else hasta que alcanza el estado primitivo. Cuando esto sucede, se ejecuta la cláusula if (porque n es cero), y la llamada recursiva termina. Ahora, insertaremos esta función en un programa llamado CAPITAL.CPP, para calcular el interés compuesto, como sigue: // Este programa: CAPITAL.CPP, ilustra el cálculo del interés compuesto de un capital inicial determinado #include <iostream.h> // Para cin y cout // Funciones prototipo y variables globales float balance(int); // Regresa nuevo balance float deposito = 0.0; // Capital inicial float tasa = 0.0; // Tasa de interés anual void main(void) // Define la variable argumento de la función int meses = 0; // Número de meses después del depósito // inicial para determinar el balance // Obtención del capital inicial, número de meses y tasa de interés cout << "Escriba el depósito inicial: $"; cin >> deposito; cout << "Escriba el número de meses (periodo): "; cin >> meses; cout << "Escriba la tasa de interés anual: "; cin >> tasa; // Establece la salida ajustada y la precisión cout.setf(ios::fixed); cout.precision(2); // Muestra resultados, haciendo la llamada a la función recursiva cout << "\n\ncon un depósito inicial de $" << deposito << " y una tasa de interés de " << tasa << "%\nel balance al final de " << meses << " meses deberá ser de $" << balance(meses) << endl; // Fin de main() 11-10

11 /*********************************************************************** Esta función recursiva calculará un balance de cuenta con base en una tasa de interés compuesto mensual. ************************************************************************/ float balance(int n) if(n == 0) return deposito; else return(1 + tasa / 12 / 100) * balance(n - 1); //Fin de balance() El programa anterior pide al usuario que escriba el depósito inicial, número de meses a calcular y la tasa de interés anual. Las variables deposito y tasa se definen en forma global para propósitos de ejemplo para que podamos concentrarnos en la función recursiva. El número de meses a calcular se pasa a la función como un parámetro por valor. Realmente las variables deposito y tasa podrían definirse en forma local para main() y pasar a la función como parámetros por valor. Esto se dejará como un ejercicio. Una vez que el usuario escribe los valores necesarios, se hace la llamada recursiva y el programa escribe el balance final. Aquí está una muestra de la salida del programa: Escriba el depósito inicial: $1000 Escriba el número de meses para calcular: 4 Escriba la tasa de interés anual: 12 Con un depósito inicial de $1000 y una tasa de interés de 12% el balance al final de 4 meses deberá ser de $ FUNCIONAMIENTO INTERNO DE LA RECURSIVIDAD Internamente se utiliza una estructura tipo pila para guardar los valores de las variables y constantes locales de la función que efectúa la llamada. De esta manera, una vez concluida la ejecución, se puede seguir con los pasos que quedaron pendientes recuperando los valores necesarios de la pila. Con cada llamada recursiva se crea una copia de todas las variables y constantes que estén vigentes, y se guarda esa copia en la pila. Además se guarda una referencia a la siguiente instrucción a ejecutar. Al regresar se toma la imagen guardada en el tope de la pila y se continúa operando. Esta acción se repita hasta que la pila quede vacía. Se tratará de ilustrar estos conceptos con ayuda de los ejemplos anteriores. Ejemplo 11.7 Retomando el problema del cálculo del factorial de un número n (véase el algoritmo 11.2), para mostrar el funcionamiento interno de la recursión. En la tabla 11.1 se presentan los valores que van adquiriendo las variables y los valores que son guardados en la pila, en el transcurso del cálculo del factorial de un número n = 4. PASO n PILA FactorialRecurrente *, 2 3 4*, 3*, 3 2 4*, 3*, 2*, 4 2 4*, 3*, 2* *, 3* 2(2*1) 6 3 4* 6(3*2) (4*6) Tabla Cálculo recursivo del factorial 11-11

12 En el primer paso n es igual a 4; por lo tanto, siguiendo el algoritmo 11.2 debe hacerse 4 * 3! Ante la imposibilidad de realizar esta operación (porque primero debe calcularse 3!) se guarda el valor de n en la pila y se continúa trabajando con n = 3. Con el nuevo valor de n procedemos de manera similar que con n = 4. La diferencia radica en que la entrada, n, está más cercana al estado básico. En consecuencia, en el paso 2 se agrega el valor 3 a la pila para multiplicarlo posteriormente por 2! En el paso 3 se agrega el valor 2 a la pila. Una vez alcanzado el estado básico, paso 4, se comienza a extraer los valores almacenados en la pila y a operar con ellos. En el paso 5 se extrae de la pila el valor 2 y se multiplica por el factorial de 1, obteniendo 2! Luego se extrae el 3 y se multiplica por el factorial de 2, para obtener 3! Se continúa así hasta que la pila quede vacía, lo cual ocurre en el paso 7 donde se calcula el factorial de 4. En la figura 11.3 se presenta gráficamente lo descrito anteriormente. factorialrecurrente(4) = 24 4 * factorialrecurrente(3) = * factorialrecurrente(2) = * factorialrecurrente(1) 1 = Ejemplo 11.8 Figura Representación gráfica de la recursividad Retomando ahora el problema del cálculo de un número Fibonacci n (véase el algoritmo 11.3), para mostrar nuevamente el funcionamiento interno de la recursividad. En la tabla 11.2 se presentan los valores que van adquiriendo las variables y los valores almacenados en la pila, durante el cálculo del número Fibonacci n = 4. PASO n PILA FibonacciRecursivo fibonaccirecursivo(2) +, 2 3 fibonaccirecursivo(2) +, fibonaccirecursivo(1) +, 3 2 fibonaccirecursivo(2) +, fibonaccirecursivo(1) +, fibonaccirecursivo(0) +, 4 1 fibonaccirecursivo(2) +, fibonaccirecursivo(1) +, 1 fibonaccirecursivo(0) +, 5 0 fibonaccirecursivo(2) +, fibonaccirecursivo(1) +, 1(1+0) 6 1 fibonaccirecursivo(2) +, 2(1+1) 7 2 fibonaccirecursivo(0) +, fibonaccirecursivo(0) +, 3(2+1) 9 0 3(3+0) Tabla Cálculo recursivo de un número Fibonacci 11-12

13 En la misma podemos observar que en este ejemplo se van guardando en la pila llamadas recursivas pendientes de ejecución. Para n igual a 4 se llama al proceso fibonaccirecursivo(3) y se guarda en la pila fibonaccirecursivo(2), paso 1. En el paso 2 se calcula fibonaccirecursivo(3), llamando al proceso fibonaccirecursivo(2) y almacenando en la pila fibonaccirecursivo(1) (una vez calculados, serán sumados) Se continúa de esta manera para los diferentes valores de n, hasta que éste sea 1 o 0. Cuando n es igual a 1, paso 4, se asigna directamente un valor a fibonaccirecursivo(1), ya que éste es un estado básico. Como se llegó a un estado básico, se comienzan a extraer sucesivamente de la pila los elementos dejados en ella. En el paso 5 se extrae de la pila a fibonaccirecursivo(0), el cual también tiene solución directa por ser un estado básico y se suma al número fibonacci obtenido en el paso anterior. Lo mismo sucede en el paso 6 al extraer fibonaccirecursivo(1) En el paso 7, al extraer fibonaccirecursivo(2) se procede de igual manera que en el paso 3. Es decir se llama a fibonaccirecursivo(1) y se almacena en la pila a fibonaccirecursivo(0) El proceso continúa hasta que la pila quede vacía, paso 9. En la figura 11.4 se presenta gráficamente lo descrito con anterioridad

14 fibonaccirecursivo(4) = fibonaccirecursivo(3) + fibonaccirecursivo(2) = 3 MIGUEL Á. TOLEDO MARTÍNEZ fibonaccirecursivo(3) = fibonaccirecursivo(2) + fibonaccirecursivo(1) = 2 fibonaccirecursivo(2) = fibonaccirecursivo(1) + fibonaccirecursivo(0) = 1 fibonaccirecursivo(1) = fibonaccirecursivo(0) = fibonaccirecursivo(1) = fibonaccirecursivo(2) = fibonaccirecursivo(1) + fibonaccirecursivo(0) = 1 fibonaccirecursivo(1) = fibonaccirecursivo(0) = Figura Representación gráfica de la recursividad 11-14

15 Ejemplo 11.9 Para concluir esta serie de ejemplos sobre el funcionamiento interno de la recursividad, retomemos el problema del cálculo de una inversión en una institución bancaria (véase el algoritmo 11.4). En la tabla 11.3 se presentan los valores que van adquiriendo las variables y los valores almacenados en la pila, en el transcurso del cálculo de una inversión durante 4 años, con un capital inicial de $ y a un interés anual del 10%.(Nuevamente, para simplificar supondremos que los intereses se acumulan anualmente). PASO n PILA balance *, *, 1.10 *, *, 1.10 *, 1.10 *, *, 1.10 *, 1.10 *, 1.10 *, *, 1.10 *, 1.10 *, 1.10 *, *, 1.10 *, 1.10 *, 5500(5000 * 1.10) *, 1.10 *, 6050(5500 * 1.10) *, 6655(6050 * 1.10) (6655 * 1.10) Tabla Cálculo recursivo de una inversión bancaria En el primer paso n es igual a 4, por lo tanto siguiendo el algoritmo debe hacerse 1.10 por el capital obtenido durante la inversión de los 3 años anteriores. Como no se dispone de este valor, se almacena 1.10 en la pila para operar con él posteriormente y se continúa con el cálculo de balance(3), paso 2. Como no se tiene aún el estado básico se procede de manera similar al paso anterior, es decir se almacena 1.10 en la pila y se llama a balance(2). Se continúa así hasta llegar al estado básico, paso 5, en el cual el capital a utilizar en el cálculo de la inversión es el inicial, y por lo tanto puede ser asignado directamente. En el paso 6 se extrae de la pila el valor 1.10 y se multiplica por el capital, calculando así la inversión obtenida al cabo de un año. Se continúa realizando esta operación mientras haya elementos en la pila. En el paso 9 la pila queda vacía y así se obtiene, finalmente, el monto total de la inversión al cabo de 4 años. En la figura 11.5 se presenta gráficamente lo antes descrito. En esta sección se ha presentado el funcionamiento interno de la recursividad. Aunque es un proceso transparente al usuario, es muy importante conocerlo para comprender debidamente la herramienta que se está utilizando. También se ha mencionado en los párrafos anteriores que la recursividad es un instrumento poderoso para definir objetos en términos de sí mismos. Usando recursividad es posible escribir un código más compacto y, en ciertos casos, de más fácil comprensión. Sin embargo, debe quedar claro que la recursividad no da mayor rapidez a la ejecución del código y tampoco permite ahorrar espacio de memoria. Con respecto a este último punto debe tenerse en cuenta que la recursividad, para su funcionamiento utiliza una pila interna la cual consume memoria. En general, es recomendable usar recursividad cuando el problema por su naturaleza así lo exige. Es decir, cuando la solución simplifica y facilita de modo notable usando esta herramienta. En otro caso es más conveniente, computacionalmente hablando, utilizar alguna técnica iterativa para resolver el problema. Los casos que se presentaron antes, resueltos por algoritmos recursivos, son problemas que pueden resolverse fácilmente de manera iterativa. Ahora es preciso ejemplificar cada uno de estos problemas, con su correspondiente solución iterativa

16 balance(4) = * balance(3) = * balance(2) = * balance(1) = * balance(0) = Figura Representación gráfica de la recursividad SOLUCIONES NO RECURSIVAS (ITERATIVAS) Ejemplo Basándose en el algoritmo 11.2: factorialrecurrente antes diseñado, elaboraremos un algoritmo no recursivo. factorialiterativo(n) /* Este algoritmo calcula el factorial de un número n donde n es un valor numérico entero, positivo o nulo. */ INICIO si(n < 0) entonces regresar(-1). // Valida datos erróneos. factorial = 1. mientras (n > 0) hacer // Ciclo para calcular n! Inicio factorial = n * factorial. n = n-1. Fin. FIN. regresar(factorial)

17 Ejemplo La tabla 11.4 representa los valores que van adquiriendo las variables, durante el cálculo del factorial de un número n = 4. n factorial Tabla Cálculo iterativo del factorial A continuación se presenta un algoritmo no recursivo para el cálculo de los números de Fibonacci. fibonacciiterativo(n) /* Este algoritmo calcula el número Fibonacci correspondiente a n, donde n es un valor numérico entero, positivo o nulo. */ INICIO si((n = 0) o (n == 1)) entonces regresar(n).. si no Inicio fiba = 0. fibb = 1. i = 2. Fin. mientras(i <=n) Inicio Fin. fibo = fiba + fibb. fiba = fibb. fibb = fibo. i = i + 1. regresar(fibo). FIN. La tabla 11.5 representa los valores que van adquiriendo las variables, durante el cálculo del número Fibonacci n = 4. n fibo fiba fibb i Tabla Cálculo iterativo de un número Fibonacci A continuación presentamos un algoritmo con algunas variaciones respecto a la solución antes propuesta. Nuestro objetivo ahora es diseñar primero una función iterativa que acepte un número entero que no sea negativo como el argumento n y devuelva el valor F(n) La primera versión de nuestro seudocódigo puede ser así: 11-17

18 fibonacci(n) INICIO si (n = 0) regresar(0). si(n = 1) regresar(1). para i = 2 hasta n Inicio elementosiguiente = elementoanteanterior + elementoanterior. actualizar elementoanteanterior y elementoanterior. Fin. FIN. regresar(elementosiguiente). Observe que nuestro seudocódigo carece de algunos detalles relevantes: los valores iniciales de las variables, los incrementos para las variables que iteran (ciclos) y una prueba para detectar los argumentos válidos. Después de agregar esas instrucciones, el algoritmo queda así: fibonacci(n) INICIO si(n < 0) regresr(-1). si (n = 0) regresar(0). si(n = 1) regresar(1). elementoanteanterior = 0. elementoanterior = 1. para i = 2 hasta n Inicio elementosiguiente = elementoanteanterior + elementoanterior. ElementoAnteAnterior = elementoanterior. elementoanterior = elementosiguiente. Fin. FIN. regresar(elementosiguiente). Observe que hemos establecido la convención de devolver 1 para indicar un argumento erróneo. También observe que ya inicializamos y actualizamos las dos variables: elementoanteanterior y elementoanterior. Finalmente escribiremos un programa en C++ que llame a esta función. El programa se llamará FIBONA2.CPP

19 /* Este programa: FIBONA2.CPP, resuelve en forma iterativa la serie de Fibonacci */ #include <iostream.h> const int MAXIMO = 10; //Para cout //Máximo n int fibonacci(int n); void main(void) for(int i = -1; i <= MAXIMO; i++) cout << "\ti: " << i << " fib(" << i << "): " << fibonacci(i) << endl; int fibonacci(int n) int i; int elementosiguiente, elementoanteanterior, elementoanterior; if(n < 0) return(-1); if(n == 0) return(0); if(n==1) return(1); elementosiguiente = 0; elementoanteanterior = 0; elementoanterior = 1; for(i = 2; i <= n; i++) elementosiguiente elementoanteanterior elementoanterior = elementoanterior + elementoanteanterior; = elementoanterior; = elementosiguiente; return(elementosiguiente); Ejemplo Algoritmo no recursivo para el cálculo del capital obtenido en una inversión bancaria durante n años. balanceiterativo(n, m, x) /* Este algoritmo calcula el capital que se tendrá luego de invertir un capital inicial m, durante n años, con una tasa anual de x%. */ INICIO capital = m. i = 1. mientras(i <= n) hacer Inicio capital = capital + x * capital. i = i

20 Fin. FIN. regresar(capital). La tabla 11.6 presenta los valores que van adquiriendo las variables, en el transcurso del cálculo de una inversión durante 4 años con un capital inicial de $ a un interés anual del 10%. n m x capital i Tabla Cálculo iterativo de una inversión bancaria EL PROBLEMA DE LAS TORRES DE HANOI El problema de las Torres de Hanoi es un problema clásico de recursividad, ya que pertenece a la clase de problemas cuya solución se simplifica notablemente al utilizar recursividad. Tenemos tres torres: A, B y C, y un conjunto de cinco discos, todos de distintos tamaños. El enigma comienza con todos los discos colocados en la torre A de tal forma que ninguno de ellos cae sobre uno de menor tamaño; es decir, están apilados, uno sobre otro, con el más grande hasta abajo, encima de él el siguiente en tamaño y así sucesivamente (véase la figura 11.6, donde se muestra un ejemplo) El propósito del enigma es apilar los cinco discos, en el mismo orden, pero en la torre C. Durante la solución, puede colocar los discos en cualquier torre, pero debe apegarse a las siguientes reglas: Sólo puede mover el disco superior de cualesquiera de las torres. Un disco más grande nunca puede estar encima de uno más pequeño. Torre A Torre B Torre C Figura 11.6 Enigma de Las torres de Hanoi Intente resolver manualmente el enigma con una cantidad pequeña de discos, digamos cinco o seis, antes de proseguir con la solución algorítmica. El problema que enfrentamos es cómo escribir un programa que resuelva el enigma para cualquier cantidad de discos. Comencemos por considerar una solución general para n discos. Si tenemos la solución para n-1 discos, sería evidente que podemos resolver el problema para n discos: resolvemos el enigma para n-1 discos y luego movemos el disco n a la torre C. De modo 11-20

21 similar, si pudiéramos resolver para n-2 discos, el caso n-1 sería más sencillo. Podemos continuar de esta manera hasta llegar al caso trivial donde n = 1: simplemente movemos el disco de la torre A a la torre C. Aunque no sea obvio, lo que acabamos de describir es una solución recursiva para el problema, es decir, resolvimos el problema para una n dada en términos de n-1. Examinemos un ejemplo concreto y resolvamos el enigma con cinco discos. Supongamos que sabemos cómo resolverlo con cuatro discos, moviéndolos de la torre A a la torre B (utilizando C como torre auxiliar) Luego, para terminar la solución, sólo debemos mover el disco más grande de la torre A a la torre C y mover los cuatro discos de la torre B a la torre C (usando A como auxiliar). Podemos resumir la solución de un modo más preciso: 1. Si n = 1, movemos el disco de A a C y nos detenemos. 2. Movemos n-1 discos de A a B utilizando C como auxiliar. 3. Movemos el disco n de A a C. 4. Movemos n-1 discos de B a C usando A como auxiliar. Observe que los pasos 2 y 4 son recursivos porque nos sugieren que repitamos la solución para n-1 discos. También observe que las torres cambian su papel conforme avanza la solución. Ahora que comprendemos la solución, debemos convertir estas reglas en un algoritmo. Diseñaremos una función, llamada torres(), que mostrará los movimientos necesarios para resolver el enigma de acuerdo con un número dado de discos. Su salida estará constituida por comandos de este tipo: Mueve disco X de torre Y a la torre Z La función torres() necesita cuatro argumentos. El primero indica la cantidad de discos que se van a usar. Los otros tres determinan el papel que tendrán las tres torres: origen, destino y auxiliar. A continuación se muestra el seudocódigo que soluciona el enigma de Las torres de Hanoi. Observe cómo la rutina cambia el papel de cada torre con cada llamada recursiva. Sin embargo, la función carece de un detalle importante: no revisa valores erróneos que le fueron pasados como argumentos. Dejaremos esto como ejercicio. torres(entero n, carácter A, carácter B, carácter C) /* n: Cantidad de discos */ /* A: torre origen */ /* B: torre auxiliar */ /*C: torre destino */ INICIO si(n == 1) Inicio escribir( mueve disco, n, de la torre, A, a la torre, C). regresa. Fin. /* Mueve n-1 discos de la torre A a la torre B (C es e la torre auxiliar) */ torres(n-1, A, C, B). /* Mueve el enésimo aro de la torre A a la torre C */ escribir( mueve disco, n, de la torre, A, a la torre, C)

22 /* Mueve n-1 discos de la torre B a la torre C (A es la torre auxiliar) torres(n-1, B, A, C). FIN. regresar. Algoritmo 11.5: Torres El algoritmo recursivo anterior ofrece una solución clara y compacta al problema de las Torres de Hanoi. Es posible dar una solución iterativa a este problema, pero es conveniente mencionar que la misma es más complicada y extensa. Ejemplo El siguiente programa: HANOI.CPP, ilustra el uso del algoritmo Torres /* Este programa: HANOI.CPP, muestra el algoritmo para resolver el enigma de Las torres de Hanoi. */ #include <iostream.h> //Para cout y cin void torres(int n, char A, char B, char C); void main(void) int discos; char origen char auxiliar char destino = 'A'; = 'B'; = 'C'; cout << "Dame el número de discos: "; cin >> discos; cout << endl; torres(discos, origen, auxiliar, destino); void torres(int n, char A, char B, char C) /* n: Cantidad de discos */ /* A: torre origen */ /* B: torre auxiliar */ /*C: torre destino */ if(n == 1) cout << "Mueve disco " << n << " de la torre " << A << " a la torre " << C << endl; return; /* Mueve n-1 discos de la torre A a la torre B (C es la torre auxiliar) */ torres(n-1, A, C, B); /* Mueve el enésimo disco de la torre A a la torre C */ cout << "Mueve disco " << n << " de la torre " << A << " a la torre " << C << endl; /* Mueve n-1 discos de la torre B a la torre C (A es la torre auxiliar) */ torres(n-1, B, A, C); return; 11-22

23 Luego de realizar algunas pruebas, para distintos valores de n, se puede concluir que, para cualquier n, el número de movimientos está dado por la siguiente fórmula: numeromovimientos = 2 n -1 En la siguiente sección se estudiará cómo pueden plantearse soluciones no recursivas a problemas definidos en forma recursiva, usando pilas. USO DE LAS PILAS PARA SIMULAR RECURSIVIDAD Se ha presentado a la recursividad como una herramienta poderosa para crear algoritmos claros y concisos para problemas que se definen en términos de sí mismos. También se ha mencionado que el uso de la recursividad puede ser costoso en lo que a espacio de memoria se refiere. Por todo lo dicho y además, en consideración de que muchos lenguajes de programación no cuentan con esta facilidad, resulta conveniente contar con algún procedimiento que permita simular la recursividad. Una función puede tener variables locales y parámetros (argumentos) Cuando se hace una llamada recursiva a la función, los valores actuales de las variables y parámetros deben conservarse. Igualmente debe conservarse la dirección a la cual debe regresar el control una vez ejecutado la función llamada. En la función que se propone para simular recursividad sólo se conservan los valores de las variables y parámetros. Para ello se utilizan pilas. Nuevamente aparece el concepto de pila relacionado con recursividad. Una aplicación de éstas se estudió cuando se analizó la operación interna de la recursividad. Otra aplicación importante es el centro de atención de esta sección: simulación de recursividad mediante el uso de pilas. A continuación se presenta el problema de la Torres de Hanoi, pero con un enfoque no recursivo. Se verá cómo se puede modificar el algoritmo antes presentado para obtener una versión no recursiva del mismo. El algoritmo 11.5: Torres, trabaja con cuatro parámetros: n, origen, destino, auxiliar (el número de discos y los nombres de las tres torres que intervienen en el problema) Si se quieren conservar los valores de estos parámetros en cada llama, se deberá definir una pila para cada uno de ellos. (Otra alternativa sería definir una pila única, en la que cada elemento de la misma fuera capaz de almacenar los cuatro parámetros) Aquí se definirán cuatro pilas de trabajo: pilan: para almacenar imágenes de n. pilao: para almacenar imágenes de origen. pilad: para almacenar imágenes de destino. pilax: para almacenar imágenes de auxiliar. También será necesario manejar un tope para cada una de las pilas. El algoritmo siguiente es una solución iterativa al problema de las Torres de Hanoi. hanoiiterativo(n, origen, destino, auxiliar) INICIO /* Este algoritmo resuelve el problema de las torres de Hanoi de manera no recursiva. origen, destino y auxiliar son variables que almacenan los nombres de las tres torres, n representa el número de discos

24 pilan, pilao, pilad y pilax son estructuras de datos tipo pila. tope es una variable de tipo entero. varaux es una variable de tipo carácter. bandera es una variable de tipo booleano. */ tope = 0. bandera = falso. mientras(n > 0) Y (bandera = falso) Inicio mientras(n > 1) Inicio /* Guardar en las pilas los valores actuales de los parámetros. */ tope = tope + 1. pilan[tope] = n. pilao[tope] = origen. pilad[tope] = destino. pilax[tope] = auxiliar. /* Simular llamada a Hanoi con n-1, origen, auxiliar y destino. */ Fin. n = n 1. varaux = destino. destino = auxiliar. auxiliar = varaux. FIN. Fin. escribir( Mover un disco de, origen, a, destino). bandera = verdadero. si(tope > 0) entonces // Las pilas no están vacías. Inicio // Se extraen los elementos de tope de las pilas. n = pilan[tope]. origen = pilao[tope]. destino = pilad[tope]. auxiliar = pilax[tope]. tope = tope 1. Fin. escribir( Mover un disco de, origen, a, destino). /* Simular llamada a Hanoi con n 1, auxiliar, destino y origen. */ n = n 1. varaux = origen. origen = auxiliar. auxiliar = varaux. bandera = falso. Algoritmo 11.6: hanoiiterativo 11-24

25 A continuación se presenta un conjunto de tablas donde se analiza el algoritmo 11.6: hanoiiterativo para diferentes valores de n. Todas las tablas tienen las mismas columnas y éstas representan lo siguiente: C1: representa el parámetro origen. C2: representa el parámetro destino. C3: representa el parámetro auxiliar. C4: representa la variable tipo pilan. C5: representa la variable tipo pilao. C6: representa la variable tipo pilad. C7: representa la variable tipo pilax C8: representa los movimientos de disco entre dos torres. Los escribiremos [x:y], y se interpretarán como que un disco ha sido movido de la torre x a la torre y. C9: representa la variable de control bandera, la cual puede tomar los valores de v (verdadero) y f (falso). En la tabla 11.7 se expone un seguimiento del algoritmo para n = 1. Paso N C1 C2 C3 tope C4 C5 C6 C7 C8 C9 0 1 A B C 0 Falso 1 [A:B] Verdadero Tabla Solución iterativa del problema de las torres de Hanoi. En el paso 1 se escribió el movimiento necesario para alcanzar el estado final (C8), y se asignó a la variable de control el valor verdadero (C9) Como una de las dos condiciones evaluadas en el algoritmo es falsa, hemos llegado a la solución del problema. En la tabla 11.8 se presenta un seguimiento del algoritmo 11.6: hanoiiterativo para n = 2. Paso n C1 C2 C3 tope C4 C5 C6 C7 C8 C9 0 2 A B C 0 Falso A B C 2 1 A C B 3 [A:C] Verdadero 4 2 A B C 0 [A:B] 5 1 C B A Falso 6 [C:B] Verdadero Tabla Solución iterativa del problema de las Torres de Hanoi En el primer paso se guarda en las pilas (C4, C5, C6 y C7) una imagen de los datos (n, origen, destino y auxiliar) Se preparan las variables para realizar el movimiento de los (n 1) discos superiores de la torre origen a la torre auxiliar (C1, C2 y C3), paso 2. En el paso 3 se escribe el movimiento de la torre origen a la torre destino (C8) En el paso 4 se extraen los elementos del tope de las pilas y se asignan a sus correspondientes variables (n, C1, C2 y C3), con lo que se recuperan los valores almacenados en ellas en el paso 1. Se escribe también el movimiento de la torre origen a la torre destino (C8) En el paso 5 se preparan las variables para realizar el movimiento de los (n 1) discos superiores de la torre auxiliar a la torre destino (C1, C2 y C3) En el paso 6 se realizó el último movimiento de disco, necesario para alcanzar el estado solución (C8) 11-25

26 En la tabla 11.9 se presenta un seguimiento del algoritmo 11.6: hanoiiterativo para n = 3. Paso n C1 C2 C3 tope C4 C5 C6 C7 C8 C9 0 3 A B C 0 Falso A B C 2 2 A C B A C B 4 1 A B C 5 [A:B] Verdadero 6 2 A C B 1 [A:C] 7 1 B C A Falso 8 [B:C] Verdadero 9 3 A B C 0 [A:B] 10 2 C A B Falso C B A 12 1 C A B 13 [C:A] Verdadero 14 2 C B A 0 [C:B] 15 1 A B C Falso 16 [A:B] Verdadero Tabla Solución iterativa del problema de las Torres de Hanoi Una simple comparación entre los métodos recursivos e iterativos permite concluir que la solución recursiva del problema de las Torres de Hanoi es mucho más compacta y más fácil de comprender que la solución no recursiva. De cualquier manera es importante contar con un formalismo para traducir procesos recursivos en procesos no recursivos, porque, como ya se mencionó más arriba, algunos lenguajes no tienen esta herramienta de programación y además en ciertos problemas, el costo de usar recursividad es significativo. EL PROBLEMA DE LAS OCHO REINAS Otro ejemplo clásico de programación recursiva es el enigma de Las ocho reinas (o damas) El problema es colocar ocho reinas en un tablero de ajedrez de tal forma que ninguna ataque a las demás. En ajedrez una reina puede comerse a cualquier pieza desplazándose cualquier cantidad de casillas (escaques) por una fila, una columna o en diagonal( véase la figura 11.7). Por lo tanto, el dilema es colocar las ocho reinas en un tablero 8 x 8 sin que compartan la misma fila, columna o diagonal. Intente resolver manualmente el enigma antes de continuar. Para comenzar nuestra solución, vamos a suponer que desarrollamos el procedimiento reina(), que intentará colocar una reina en una fila mediante su propio parámetro fila. De este modo la función analizará todos los escaques de la fila especificada y, tras localizar uno que no esté bajo ataque, colocará la reina ahí; luego ella misma se llamará de modo recursivo para colocar otra reina en la siguiente fila. Si puede colocar las ocho reinas en el tablero, la función devolverá el valor RESUELTO. Si todos los escaques de la fila indicada están bajo ataque, entonces devolverá FALLO. Comencemos a esbozar el algoritmo (observe que para facilitar la programación, las filas y las columnas se indexarán de 0 a 7) 11-26

27 reina(fila) INICIO para i = 0 hasta i < 8 i incrementado en 1 //Revisa cada columna si (asalvo(fila, i) //Prueba escaque Inicio Colocar la reina en el tablero: fila, i. si(reina(fila+1) == RESUELTO) regresa RESUELTO. FIN. Fin. regresa(fallo). //Todos los escaques están bajo ataque R Figura 11.7 Filas, columnas y diagonales de ataque de la reina. Es evidente que la descripción está incompleta. Primero, necesitamos una condición para detener la recursión. Pensemos en esto unos instantes. Sabemos que, por definición, hay un máximo de ocho reinas en el enigma. Por lo tanto, podemos revisar fila > 7 desde el comienzo de la función; Pero reflexionemos un momento en la importancia del valor que contiene el argumento fila. Si hacemos una llamada recursiva a reina() con fila equivalente a un valor n, significa que hemos resuelto de la fila 0 a la fila n-1. Por lo tanto, si debemos llamar a reina() cuando fila = 8, significa que todas las demás reinas (filas 0 a 7) ya fueron colocadas y la función debe devolver el valor RESUELTO. Después necesitamos una forma de registrar la posición de las reinas a medida que procede la función. Para hacerlo, utilizaremos un arreglo de caracteres de 8 x 8, que hará las veces de tablero. En cada posición, guardaremos (con propósito de mostrarlo) uno de los siguientes caracteres: - (guión) para indicar un escaque vacío; * (asterisco) para señalar un escaque donde se encuentra una reina. Por último, debemos definir la función asalvo(), que determina si un escaque específico está bajo ataque. Pero pospongamos el análisis de asalvo() hasta que no terminemos de definir reina() Incorporemos los cambios que hemos sugerido y veamos cómo toma forma nuestra función: 11-27

28 reina(fila) INICIO si(fila > 7) regresa(resuelto). //Estado de salida FIN. //Revisa cada columna: de 0 a 7 para i = 0 hasta i < 8 en incrementos de uno en uno de i //Verifica si el escaque esta o no bajo ataque si(asalvo(fila, i)) Inicio //Coloca la reina en el tablero tablero[fila][i] = REINA. //Prueba la fila siguiente si(reina(fila + 1) = RESUELTO regresa(resuelto). si no tablero[fila][i] = VACIA. Fin. regresa(fallo). Algoritmo 11.7: reina Observe que hemos añadido la instrucción: tablero[fila][i] = VACIA. porque si alguna llamada recursiva a reina() falla en encontrar una solución (con una reina ubicada en esa posición), esta instrucción restaura el tablero a su estado anterior; Luego la función queda en libertad para revisar el siguiente escaque disponible. Nuestro algoritmo empieza a tomar forma, por lo que ahora debemos analizar cómo implementar la función asalvo() El problema que debemos plantear es cómo determinará la función si un escaque específico está bajo ataque de una reina colocada con anterioridad. Primero, observe que, en realidad, no es necesario revisar posibles ataques a lo largo de las filas. Gracias a nuestra implementación, podemos tener la certeza de que la única reina que puede permanecer en una fila es la que intentamos colocar. Además, la revisión de ataques desde las columnas puede hacerse de modo directo, burdamente, indexando el tablero junto con la columna que vamos a revisar. Los ataques diagonales son los más difíciles de resolver. Como se ilustra en la figura 11.8, una reina colocada en cualesquiera de los escaques rojos sería atacada por la reina colocada en el escaque [3,3] Qué tan fácil podemos determinar si un escaque está bajo ataque a lo largo de sus dos diagonales (ascendente y descendente)? 11-28

29 R Figura 11.8 Ataques diagonales Diagonal ascendente Diagonal descendente Si mira con atención el tablero de la figura 11.8, observará que cada diagonal puede identificarse de modo único como una función de sus índices. Por ejemplo, examinemos la figura 11.9a. La suma de los índices (fila + columna) de cada escape en la diagonal ascendente es igual a 6. Por lo tanto, cualquier reina que haya sido colocada antes en un escaque cuyos índices sumen 6 estará bajo el ataque de la casilla [3,3] De modo similar, podemos derivar un valor único para las diagonales descendentes (véase la figura 11.9b.) restando los índices (columna fila). Observe que cada una de las 15 diagonales ascendentes tienen un intervalo de valores que va de 0 a 14, y las diagonales descendentes uno de 7 a R Figura 11.9a Diagonal Ascendente Figura 11.9b Diagonal descendente Podemos integrar este concepto en nuestra función asalvo() La idea es que cada vez que coloquemos una reina en el tablero actualicemos dos arreglos: uno que registre la diagonal ascendente y otro la descendente. El índice de cada arreglo será el valor de índice de cada diagonal (por comodidad para programar, sumaremos 7 al valor del índice de la diagonal descendente) Así, asalvo() sólo necesita revisar el arreglo de escaques apropiado para determinar si uno de éstos está bajo ataque desde alguna de sus diagonales. Debemos extender esta idea para rastrear ataques a lo largo de las columnas. En este caso, sólo usamos el valor de la columna como índice en el tercer arreglo

30 Ejemplo A continuación se muestra la solución completa del enigma, mediante el programa REINAS.CPP. Este programa conduce la rutina; inicializa el tablero y los arreglos de las banderas; luego llama a reinasiguiente() para que resuelva el enigma. Si esta última función devuelve RESUELTO, REINAS.CPP también llama a muestratablero() para que imprima la solución. /* Estre programa: REINAS.CPP, resuelve el problema de ubicar 8 reinas dentro de un tablero de ajedrez, sin que se ataquen la una con la otra. */ #include <iostream.h> #define FALLO 0 #define RESUELTO 1 #define VACIO '-' #define REINA '*' /* Banderas para revisar filas y diagonales */ char columnas[8]; char diagonalascendente[15]; char diagonaldescendente[15]; char tablero[8][8]; int reinasiguiente(int fila); void ponerbanderas(int fila, int columna); void restablecerbanderas(int fila, int columna); int asalvo(int fila, int columna); void muestratablero(); void main(void) int i, j; /* Inicializa tablero y banderas */ for(i = 0; i < 8; i++) for(j = 0; j < 8; j++) tablero[i][j] = VACIO; for(i = 0; i < 15; i++) diagonalascendente[i] = VACIO; diagonaldescendente[i] = VACIO; for(i = 0; i < 8; i++) columnas[i] = VACIO; /* Intenta resolver el problema de las ocho reinas */ if(reinasiguiente(0) == RESUELTO) muestratablero(); else cout << " No se hallaron soluciones!" << endl; 11-30

UNIVERSIDAD DE LOS ANDES NUCLEO UNIVERSITARIO RAFAEL RANGEL (NURR) DEPARTAMENTO DE FISICA Y MATEMATICA AREA COMPUTACION TRUJILLO EDO.

UNIVERSIDAD DE LOS ANDES NUCLEO UNIVERSITARIO RAFAEL RANGEL (NURR) DEPARTAMENTO DE FISICA Y MATEMATICA AREA COMPUTACION TRUJILLO EDO. UNIVERSIDAD DE LOS ANDES NUCLEO UNIVERSITARIO RAFAEL RANGEL (NURR) DEPARTAMENTO DE FISICA Y MATEMATICA AREA COMPUTACION TRUJILLO EDO. TRUJILLO Recursividad: La recursividad es una técnica de programación

Más detalles

Programación II Recursividad Dr. Mario Rossainz López

Programación II Recursividad Dr. Mario Rossainz López 5. RECURSIVIDAD 5.1. Introducción La recursividad es una técnica en la que una función o método se hace llamadas a sí misma en el proceso de la realización de sus tareas. La recursividad da al programador

Más detalles

4.1 Definición. Se dice que algo es recursivo si se define en función de sí mismo o a sí mismo. Un objeto (problemas, estructuras de datos) es

4.1 Definición. Se dice que algo es recursivo si se define en función de sí mismo o a sí mismo. Un objeto (problemas, estructuras de datos) es Recursividad 4.1 Definición. Se dice que algo es recursivo si se define en función de sí mismo o a sí mismo. Un objeto (problemas, estructuras de datos) es recursivo si forma parte de sí mismo o interviene

Más detalles

UNIVERSIDAD AUTÓNOMA CHAPINGO DPTO. DE PREPARATORIA AGRÍCOLA ÁREA DE FÍSICA RECURSIÓN. Guillermo Becerra Córdova

UNIVERSIDAD AUTÓNOMA CHAPINGO DPTO. DE PREPARATORIA AGRÍCOLA ÁREA DE FÍSICA RECURSIÓN. Guillermo Becerra Córdova UNIVERSIDAD AUTÓNOMA CHAPINGO DPTO. DE PREPARATORIA AGRÍCOLA ÁREA DE FÍSICA RECURSIÓN Guillermo Becerra Córdova E-mail: gllrmbecerra@yahoo.com OBJETIVOS: Este trabajo tiene por objetivo mostrar las características

Más detalles

Tema 7: Recursividad

Tema 7: Recursividad Tema 7: Recursividad Objetivos: en este tema estudiaremos funciones recursivas; esto es, funciones que se invocan a sí mismas. Estas funciones son equivalentes a estructuras tipo bucle pero permiten especificar

Más detalles

Recursividad. Definición de Recursividad: Técnica de programación muy potente que puede ser usada en lugar de la iteración.

Recursividad. Definición de Recursividad: Técnica de programación muy potente que puede ser usada en lugar de la iteración. Capítulo IV Recursividad Aprende a nacer desde el dolor y a ser más grande que el más grande de los obstáculos, mírate en el espejo de ti mismo y serás libre y fuerte y dejarás de ser un títere de las

Más detalles

UAA Sistemas Electrónicos Estructura de Datos Muñoz / Serna

UAA Sistemas Electrónicos Estructura de Datos Muñoz / Serna 2 Recursividad 2.1 Concepto de recursividad Se dice que una función es recursiva cuando dicha función se define en términos de la misma función. Es importante recordar que no todas la funciones pueden

Más detalles

Introducción Algoritmos de tipo dividir para vencer Algoritmos de rastreo Inverso. Recursividad. Programación Avanzada. 8 de septiembre de 2017

Introducción Algoritmos de tipo dividir para vencer Algoritmos de rastreo Inverso. Recursividad. Programación Avanzada. 8 de septiembre de 2017 Recursividad Programación Avanzada 8 de septiembre de 2017 Contenido Introducción Objetivos Definición y características Caso de análisis: factorial Contenido Introducción Objetivos Definición y características

Más detalles

TEMA 5: Subprogramas, programación modular

TEMA 5: Subprogramas, programación modular TEMA 5: Subprogramas, programación modular 5.1.-Definición de módulo. Programación modular La programación modular está basada en la técnica de diseño descendente, que como ya vimos consiste en dividir

Más detalles

Práctica 5.- Recursividad

Práctica 5.- Recursividad Benemérita Universidad Autónoma de Puebla Facultad de Ciencias de la Computación Programación Avanzada en Java Prim. 2009 Práctica 5.- Recursividad Datos de la práctica Fecha 6 de marzo de 2009 Conceptos

Más detalles

ESTRUCTURA DE DATOS: Tema 3. Recursividad

ESTRUCTURA DE DATOS: Tema 3. Recursividad ESTRUCTURA DE DATOS: Tema 3. Recursividad Presenta: David Martínez Torres Universidad Tecnológica de la Mixteca Instituto de Computación Oficina No. 37 dtorres@mixteco.utm.mx Contenido 1. Directa e indirecta

Más detalles

ESTRUCTURA DE DATOS: Tema 3. Recursividad

ESTRUCTURA DE DATOS: Tema 3. Recursividad ESTRUCTURA DE DATOS: Tema 3. Recursividad Presenta: David Martínez Torres Universidad Tecnológica de la Mixteca Instituto de Computación Oficina No. 37 dtorres@mixteco.utm.mx Contenido 1. Directa e indirecta

Más detalles

Tema 06: Recursividad

Tema 06: Recursividad Tema 06: Recursividad M. en C. Edgardo Adrián Franco Martínez http://www.eafranco.com edfrancom@ipn.mx @edfrancom edgardoadrianfrancom (Prof. Edgardo A. Franco) 1 Contenido Recursión Recursividad Programación

Más detalles

M.C. Yolanada Moyao Martínez

M.C. Yolanada Moyao Martínez M.C. Yolanada Moyao Martínez Es una técnica de programación que permite que un bloque de instrucciones se ejecute n veces. En Java los métodos pueden llamarse a sí mismos. Si dentro de un método existe

Más detalles

UNIVERSIDAD DON BOSCO FACULTAD DE ESTUDIOS TECNOLÓGICOS ESCUELA DE COMPUTACION

UNIVERSIDAD DON BOSCO FACULTAD DE ESTUDIOS TECNOLÓGICOS ESCUELA DE COMPUTACION UNIVERSIDAD DON BOSCO FACULTAD DE ESTUDIOS TECNOLÓGICOS ESCUELA DE COMPUTACION CICLO: 01/ 2013 Nombre de la Practica: Lugar de Ejecución: Tiempo Estimado: MATERIA: GUIA DE LABORATORIO #11 Funciones recursivas

Más detalles

Complejidad de algoritmos recursivos

Complejidad de algoritmos recursivos Tema 3. Complejidad de algoritmos recursivos 1. INTRODUCCIÓN... 1 CLASIFICACIÓN DE FUNCIONES RECURSIVAS... 1 DISEÑO DE FUNCIONES RECURSIVAS... 2 2. VENTAJAS E INCONVENIENTES DE LA RECURSIVIDAD... 4 3.

Más detalles

Fundamentos de la programación

Fundamentos de la programación Fundamentos de la programación 10 Grado en Ingeniería Informática Grado en Ingeniería del Software Grado en Ingeniería de Computadores Facultad de Informática Universidad Complutense Concepto de recursión

Más detalles

Unidad 2 Recursividad. 2.1 Definición 2.2 Procedimientos Recursivos 2.3 Ejemplos de Casos Recursivos

Unidad 2 Recursividad. 2.1 Definición 2.2 Procedimientos Recursivos 2.3 Ejemplos de Casos Recursivos Unidad 2 Recursividad 2.1 Definición 2.2 Procedimientos Recursivos 2.3 Ejemplos de Casos Recursivos 2.1 Definición de Recursividad La Recursividad es una técnica de programación muy poderosa usada ampliamente

Más detalles

Pilas Motivación

Pilas Motivación Capítulo 4 Pilas Las pilas son estructuras muy sencillas y poderosas, también conocidas como LIFO (last in, first out) por la forma en que se trabaja con ellas. Ejemplo de ellas son las pilas de charolas

Más detalles

Tema: Programación Dinámica.

Tema: Programación Dinámica. Programación IV. Guía No. 12 1 Facultad: Ingeniería Escuela: Computación Asignatura: Programación IV Tema: Programación Dinámica. Objetivos Específicos Definir el concepto de programación dinámica. Interpretar

Más detalles

Unidad 2 Recursividad. 2.1 Definición 2.2 Procedimientos Recursivos 2.3 Ejemplos de Casos Recursivos

Unidad 2 Recursividad. 2.1 Definición 2.2 Procedimientos Recursivos 2.3 Ejemplos de Casos Recursivos Unidad 2 Recursividad 2.1 Definición 2.2 Procedimientos Recursivos 2.3 Ejemplos de Casos Recursivos 2.1 Definición de Recursividad La Recursividad es una técnica de programación muy poderosa usada ampliamente

Más detalles

Recursividad Definición

Recursividad Definición Recursividad Definición Un procedimiento o función se dice recursivo si durante su ejecución se invoca directa o indirectamente a sí mismo. Esta invocación depende al menos de una condición que actúa como

Más detalles

Análisis de algoritmos. Recursividad

Análisis de algoritmos. Recursividad Análisis de algoritmos Recursividad 1 Matrushka La Matrushka es una artesanía tradicional rusa. Es una muñeca de madera que contiene otra muñeca más pequeña dentro de sí. Ésta muñeca, también contiene

Más detalles

La recursividad forma parte del repertorio para resolver problemas en Computación y es de los métodos más poderosos y usados.

La recursividad forma parte del repertorio para resolver problemas en Computación y es de los métodos más poderosos y usados. RECURSIVIDAD La recursividad forma parte del repertorio para resolver problemas en Computación y es de los métodos más poderosos y usados. Los algoritmos recursivos ofrecen soluciones estructuradas, modulares

Más detalles

Tema: Programación Dinámica.

Tema: Programación Dinámica. Programación IV. Guía 11 1 Facultad: Ingeniería Escuela: Computación Asignatura: Programación IV Tema: Programación Dinámica. Objetivos Específicos Definir el concepto de programación dinámica. Interpretar

Más detalles

Estructura de Datos. Recursividad. Primer Semestre, Indice

Estructura de Datos. Recursividad. Primer Semestre, Indice Estructura de Datos Recursividad Prof.: Mauricio Solar Prof.: Lorna Figueroa Primer Semestre, 2 Indice Introducción Definición Condiciones para la Recursividad Tipos de Recursividad Aplicaciones Ejemplo

Más detalles

Qué es la recursividad?

Qué es la recursividad? Recursividad 1 Ejemplo Matrushka La Matrushka es una artesanía tradicional rusa. Es una muñeca de madera que contiene otra muñeca más pequeña dentro de sí. Esta muñeca, también contiene otra muñeca dentro.

Más detalles

Recursividad. Facultad de Ciencias de la Computación. Juan Carlos Conde R. Object-Oriented Programming I

Recursividad. Facultad de Ciencias de la Computación. Juan Carlos Conde R. Object-Oriented Programming I Recursividad Facultad de Ciencias de la Computación Juan Carlos Conde R. Object-Oriented Programming I Contenido 1 Introducción 2 Escritura de Funciones 3 Tipos de Recursión 1 / 23 Contenido 1 Introducción

Más detalles

Funciones Tipos de funciones y Recursividad

Funciones Tipos de funciones y Recursividad Funciones Tipos de funciones y Recursividad SESION 4 Definición Una función es una subrutina o subprograma que forman un programa que realiza tareas bien definidas. Todo programa en C consta de una o más

Más detalles

Concepto de Recursión. Características de algoritmos recursivos. Ejemplos

Concepto de Recursión. Características de algoritmos recursivos. Ejemplos RECURSION Temario Concepto de Recursión Características de algoritmos recursivos Ejemplos RECURSION Metodologías para resolver problemas: 1. Diseño Top Down 2. Recursión 3. Abstracción de Datos 4. Diseño

Más detalles

Programación 1 Tema 5. Instrucciones simples y estructuradas

Programación 1 Tema 5. Instrucciones simples y estructuradas Programación 1 Tema 5 Instrucciones simples y estructuradas Índice Instrucciones simples Instrucciones estructuradas 2 Instrucción ::= 3 Instrucciones.

Más detalles

Recursión. Capítulo 4

Recursión. Capítulo 4 Recursión Capítulo 4 Introducción La recursión o recursividad es un concepto amplio, con muchas variantes, y difícil de precisar con pocas palabras.. Actividades Cotidianas; fotografía donde se observa

Más detalles

PROGRAMACION ESTRUCTURADA: Tema 3. Funciones

PROGRAMACION ESTRUCTURADA: Tema 3. Funciones PROGRAMACION ESTRUCTURADA: Tema 3. Funciones Presenta: David Martínez Torres Universidad Tecnológica de la Mixteca Instituto de Computación Oficina No. 37 dtorres@mixteco.utm.mx Contenido 1. Definiciones

Más detalles

Funciones: Pasos por Referencia Recursividad

Funciones: Pasos por Referencia Recursividad Funciones: Pasos por Referencia Recursividad Fundamentos de Programación Fundamentos de Programación I Parámetros por referencia Con la instrucción return sólo se puede devolver un valor calculado. A veces

Más detalles

Cursosindustriales. Curso de C / C++ Por Deimos_hack

Cursosindustriales. Curso de C / C++ Por Deimos_hack MÓDULO 1. ESTRUCTURAS Y FUNCIONES. En los capítulos anteriores has visto como los arrays permiten almacenar diferentes datos, pero todos del mismo tipo de dato. En la práctica esto no compensa debido a

Más detalles

Semana Lenguajes 7de programación Tipos de lenguajes de programación

Semana Lenguajes 7de programación Tipos de lenguajes de programación Semana Lenguajes 7de programación Semana 6 Empecemos! Estimados participantes, bienvenidos a esta nueva semana, en la que estudiaremos los lenguajes de programación más utilizados. No olvides repasar los

Más detalles

Programación I Recursividad.

Programación I Recursividad. Programación I Recursividad http://proguno.unsl.edu.ar proguno@unsl.edu.ar Recursividad Técnica de resolución de problemas particulares. La definición de un concepto es recursiva si el concepto es definido

Más detalles

n! = 1 2 n 0! = 1 (n+1)! = (n + 1) n!

n! = 1 2 n 0! = 1 (n+1)! = (n + 1) n! Capítulo 3 Recursión La recursión es un estilo autoreferencial de definición usado tanto en matemática como en informática. Es una herramienta de programación fundamental, particularmente importante para

Más detalles

PILAS. Prof. Ing. M.Sc. Fulbia Torres

PILAS. Prof. Ing. M.Sc. Fulbia Torres S ESTRUCTURAS DE DATOS 2006 Prof. UNIDAD II ESTRUCTURAS DE DATOS PILAS Definición. Operaciones. Implementación secuencial. Aplicaciones. Ejemplos. Ejercicios. DEFINICIÓN Una PILA (o stack) es una estructura

Más detalles

CAPITULO 6: FUNCIONES

CAPITULO 6: FUNCIONES CAPITULO 6: FUNCIONES 1. INTRODUCCIÓN Un problema de programación en C se resuelve descomponiéndolo en varias partes. Cada una de estas partes se puede asociar a una función que resuelva su fracción correspondiente

Más detalles

Funciones II. Fundamentos de Programación Fundamentos de Programación I

Funciones II. Fundamentos de Programación Fundamentos de Programación I Funciones II Fundamentos de Programación Fundamentos de Programación I Ejercicio 1: Escribe una función que transforme un punto en coordenadas polares a cartesianas Entradas: Un punto como coordenadas

Más detalles

Tema: Funciones, Procedimientos y Recursividad en C#.

Tema: Funciones, Procedimientos y Recursividad en C#. 2 Programación I Programación I. Guía 6 3 Facultad: Ingeniería Escuela: Ingeniería en Computación Asignatura: Programación I Tema: Funciones, Procedimientos y Recursividad en C#. Objetivos Utilizar la

Más detalles

INSTITUTO NACIONAL SUPERIOR DEL PROFESORADO TÉCNICO - TÉCNICO SUPERIOR EN INFORMÁTICA APLICADA - PROGRAMACIÓN I

INSTITUTO NACIONAL SUPERIOR DEL PROFESORADO TÉCNICO - TÉCNICO SUPERIOR EN INFORMÁTICA APLICADA - PROGRAMACIÓN I RESOLUCIÓN DE PROBLEMAS Y ALGORITMOS La principal razón para que las personas aprendan lenguajes de programación es utilizar una computadora como una herramienta para la resolución de problemas. Cinco

Más detalles

UNIDAD 7 Recursividad Concepto. Algoritmos recursivos. Seguimiento de la recursión. Algunos métodos recursivos de búsqueda y ordenación: M-Sort y

UNIDAD 7 Recursividad Concepto. Algoritmos recursivos. Seguimiento de la recursión. Algunos métodos recursivos de búsqueda y ordenación: M-Sort y Recursividad Concepto. Algoritmos recursivos. Seguimiento de la recursión. Algunos métodos recursivos de búsqueda y ordenación: M-Sort y Q-Sort. Comparación de eficiencia en métodos Iterativos vs recursivos

Más detalles

Paradigmas de lenguajes de programación. Introducción a la programación imperativa. Lenguaje C. Programación imperativa

Paradigmas de lenguajes de programación. Introducción a la programación imperativa. Lenguaje C. Programación imperativa Paradigmas de lenguajes de programación Introducción a la programación imperativa Algoritmos y Estructuras de Datos I Paradigma: Definición del modo en el que se especifica el cómputo (que luego es implementado

Más detalles

Sentencias de Procesamiento Iterativo: while y do-while

Sentencias de Procesamiento Iterativo: while y do-while ESTRUCTURAS CÍCLICAS Se discuten en este documento las sentencias que se utilizan en el lenguaje C++ para representar la tercera de las estructuras utilizadas en la programación estructurada: La Estructura

Más detalles

Paso de parámetros. Universidad Europea de Madrid. Todos los derechos reservados.

Paso de parámetros. Universidad Europea de Madrid. Todos los derechos reservados. Todos los derechos de propiedad intelectual de esta obra pertenecen en exclusiva a la Universidad Europea de Madrid, S.L.U. Queda terminantemente prohibida la reproducción, puesta a disposición del público

Más detalles

Programación 2. Lección 3. Introducción a la recursividad

Programación 2. Lección 3. Introducción a la recursividad Programación 2 Lección 3. Introducción a la recursividad 1 1. Definiciones recursivas Número natural y número entero Múltiplos de 7 Secuencia de datos Factorial de un número natural Sucesión de Fibonacci

Más detalles

APUNTADORES. Un apuntador es un objeto que apunta a otro objeto. Es decir, una variable cuyo valor es la dirección de memoria de otra variable.

APUNTADORES. Un apuntador es un objeto que apunta a otro objeto. Es decir, una variable cuyo valor es la dirección de memoria de otra variable. APUNTADORES Un apuntador es un objeto que apunta a otro objeto. Es decir, una variable cuyo valor es la dirección de memoria de otra variable. No hay que confundir una dirección de memoria con el contenido

Más detalles

RECURSIVIDAD. Prof. Ing. M.Sc. Fulbia Torres

RECURSIVIDAD. Prof. Ing. M.Sc. Fulbia Torres ESTRUCTURAS DE DATOS 2006 Prof. UNIDAD II ESTRUCTURAS DE DATOS RECURSIVIDAD Definición. Estado base. Estado general. Ejemplos. Ejercicios. DEFINICIÓN Es una técnica de programación muy potente que permite

Más detalles

Estructuración del programa en partes más pequeñas y sencillas

Estructuración del programa en partes más pequeñas y sencillas Introducción Estructuración del programa en partes más pequeñas y sencillas Modularización Propósito único Identificable Reusable Mayor claridad: programación, depuración, etc. Construcción de librerías

Más detalles

INFORMATICA TECNICATURA DE NIVEL SUPERIOR ALGUNOS EJERCICIOS DE SELECCIÓN E ITERACION

INFORMATICA TECNICATURA DE NIVEL SUPERIOR ALGUNOS EJERCICIOS DE SELECCIÓN E ITERACION INFORMATICA TECNICATURA DE NIVEL SUPERIOR ALGUNOS EJERCICIOS DE SELECCIÓN E ITERACION DIIAGRAMAS DE FLUJO Un diagrama de flujo es un dibujo que utiliza símbolos estándar de diagramación de algoritmos para

Más detalles

Introducción a c++ Introducción a la programación EIS Informática III

Introducción a c++ Introducción a la programación EIS Informática III Introducción a c++ Un lenguaje de programación es un lenguaje formal diseñado para realizar procesos que pueden ser llevados a cabo por máquinas como las computadoras. Pueden usarse para crear programas

Más detalles

CONTENIDO DE LA LECCIÓN 22

CONTENIDO DE LA LECCIÓN 22 CONTENIDO DE LA LECCIÓN 22 UNIONES 1. Introducción 2 2. Almacenamiento de las Uniones en C++ 2 2.1. Ejemplo 22.1 3 3. Uniones anónimas en C++ 4 3.1. Ejemplo 22.2 4 4. Lo que necesita saber 5 22-1 LECCIÓN

Más detalles

TECNICAS DE PROGRAMACION Universidad Católica Los Angeles de Chimbote RECURSIVIDAD Y SOBRECARGA DE METODOS

TECNICAS DE PROGRAMACION Universidad Católica Los Angeles de Chimbote RECURSIVIDAD Y SOBRECARGA DE METODOS RECURSIVIDAD Y SOBRECARGA DE METODOS RECURSIVIDAD Un método es recursivo cuando se llama a si mismo ya sea directamente e indirectamente. Si un método recursivo se invoca con un caso base, simplemente

Más detalles

Tema: Funciones, Procedimientos y Recursividad en C#.

Tema: Funciones, Procedimientos y Recursividad en C#. Tema: Funciones, Procedimientos y Recursividad en C#. Objetivos Programación I, Guía 6 1 Utilizar la sintaxis de las funciones definidas por el usuario (programador) para resolver problemas. Identificar

Más detalles

Tema: Funciones, Procedimientos y Recursividad en C#.

Tema: Funciones, Procedimientos y Recursividad en C#. Tema: Funciones, Procedimientos y Recursividad en C#. Objetivos Programación I, Guía 7 1 Facultad: Ingeniería Escuela: Ingeniería en Computación Asignatura: Programación I Utilizar la sintaxis de las funciones

Más detalles

Diseño y Análisis de Algoritmos

Diseño y Análisis de Algoritmos 1. Recursividad 2. "Dividir para Reinar" 3. Recursividad y Tabulación (Programación Dinámica) 4. Métodos Matemáticos Funciones discretas Notación O Ecuaciones de recurrencia 5. Casos de Estudio Breve descripción

Más detalles

Recursividad. 1.1 Concepto de Recursividad. Objetivos. Metodología de la Programación II Entender el concepto de recursividad.

Recursividad. 1.1 Concepto de Recursividad. Objetivos. Metodología de la Programación II Entender el concepto de recursividad. Objetivos Metodología de la Programación II Entender el concepto de recursividad. Conocer los fundamentos del diseño de algoritmos recursivos. Recursividad Comprender la ejecución de algoritmos recursivos.

Más detalles

Tema: Funciones, Procedimientos y Recursividad en C#.

Tema: Funciones, Procedimientos y Recursividad en C#. Programación I, Guía 6 1 Tema: Funciones, Procedimientos y Recursividad en C#. Objetivos Utilizar la sintaxis de las funciones definidas por el usuario (programador) para resolver problemas. Identificar

Más detalles

Secuencias Calculadas

Secuencias Calculadas Secuencias Calculadas Estructuras de Iteración y Recursividad Prof. Hilda Contreras Programación 1 hildac.programacion1@gmail.com Secuencias Calculadas Se aplican a los problemas donde los elementos de

Más detalles

Algoritmos. Medios de expresión de un algoritmo. Diagrama de flujo

Algoritmos. Medios de expresión de un algoritmo. Diagrama de flujo Algoritmos En general, no hay una definición formal de algoritmo. Muchos autores los señalan como listas de instrucciones para resolver un problema abstracto, es decir, que un número finito de pasos convierten

Más detalles

1. Una pila funciona según el método LIFO (Last In First Out ). Se define la clase Pila de la siguiente forma:

1. Una pila funciona según el método LIFO (Last In First Out ). Se define la clase Pila de la siguiente forma: Facultad de Ingeniería Establecimiento Público de Educación Superior, adscrito al Departamento de Antioquia Lógica de Programación II Taller Nº 3: Pilas, colas y recursividad Período 02 de 2014 Profesor:

Más detalles

Fundamentos de la POO 1

Fundamentos de la POO 1 Fundamentos de la POO 1 La correcta aplicación de los conocimientos de clases y objetos nos permitirán llegar a los objetivos planteados y a generar programas que puedan ser fáciles de comprender para

Más detalles

1. Los objetos conocidos, es decir, aquellos objetos de los cuales poseemos información total o parcial útil en la búsqueda de los objetos desconocido

1. Los objetos conocidos, es decir, aquellos objetos de los cuales poseemos información total o parcial útil en la búsqueda de los objetos desconocido 3. METODOLOGÍA DE SOLUCIÓN DE PROBLEMAS CON EL COMPUTADOR El desarrollo de un programa que resuelva un problema dado es una tarea compleja, ya que es necesario tener en cuenta de manera simultánea muchos

Más detalles

Una clasificación de los tipos de datos existentes en los diferentes lenguajes de programación se presenta a continuación:

Una clasificación de los tipos de datos existentes en los diferentes lenguajes de programación se presenta a continuación: Clase teórica 2 Algoritmos en C Página 1 de 6 TIPOS DE DATOS Una clasificación de los tipos de datos existentes en los diferentes lenguajes de programación se presenta a continuación: Por el momento nuestro

Más detalles

Trabajo Práctico Nº 06

Trabajo Práctico Nº 06 Tema: Recursividad 1. Dado el siguiente método: static int puzle (int base, int limite) if (base > limite) return -1; if (base = = limite) return base * puzle(base+1,limite); 1.1 Identificar: a) el caso(s)

Más detalles

Procedimientos y funciones

Procedimientos y funciones Procedimientos y funciones 3 Contenido 3.1. Justificación 3.2. Declaración y llamada a procedimientos 3.2.1. La sentencia nula 3.3. Localidad, anidamiento, ámbito y visibilidad 3.4. Procedimientos con

Más detalles

Manual de referencia de C++ Parte IV Variables Punteros. Preparado por Prof. Luis A. Ortiz Ortiz

Manual de referencia de C++ Parte IV Variables Punteros. Preparado por Prof. Luis A. Ortiz Ortiz Manual de referencia de C++ Parte IV Variables Punteros Preparado por Prof. Luis A. Ortiz Ortiz TABLA DE CONTENIDO Memoria de la computadora... 1 Representación de la memoria de la computadora... 1 Declaración

Más detalles

Fundamentos de Programación. Resolución de Problemas y Diseño de Programas. Fundamentos de Programación. Página 0 de 27

Fundamentos de Programación. Resolución de Problemas y Diseño de Programas. Fundamentos de Programación. Página 0 de 27 Fundamentos de Programación. Resolución de Problemas y Diseño de Programas. Fundamentos de Programación. Página 0 de 27 Metodología general para la solución de un problema Comprensión del problema (entiende

Más detalles

ALGORITMICA Y PROGRAMACION POR OBJETOS I

ALGORITMICA Y PROGRAMACION POR OBJETOS I ALGORITMICA Y PROGRAMACION POR OBJETOS I Nivel 1 Problemas, Soluciones y Programas Marcela Hernández Hoyos Solucionar un Problema = Construir un Programa Problema Programador Herramientas y Lenguajes Análisis

Más detalles

Programación 1. Tema II. Diseño de programas elementales. Lección 7. Diseño modular y descendente de programas

Programación 1. Tema II. Diseño de programas elementales. Lección 7. Diseño modular y descendente de programas Programación 1 Tema II. Diseño de programas elementales Lección 7. Diseño modular y descendente de programas 1 Objetivos de la lección : En esta lección se aprende: a dotar a un programa C++ de una estructura

Más detalles

Tema 3. Estructuras de control

Tema 3. Estructuras de control Tema 3. Estructuras de control 3.1. Secuencial 3.2. Selección 3.3. Repetición 2 Objetivos Objetivos del tema: Conocer y saber la utilidad de las tres estructuras de control (secuencial, alternativa y repetitiva)

Más detalles

Recursividad... un análisis posterior. Jaime Gutiérrez Alfaro Introducción a la programación

Recursividad... un análisis posterior. Jaime Gutiérrez Alfaro Introducción a la programación Recursividad... un análisis posterior Jaime Gutiérrez Alfaro Introducción a la programación I semestre, 2015 Agenda Introducción Cálculos por aproximación Tipos de recursión Concepto de error Depuración

Más detalles

Programación Unidad 5. Recursividad. Programación TIG - TUP 1. Sede Regional Orán UNIVERSIDAD NACIONAL DE SALTA

Programación Unidad 5. Recursividad. Programación TIG - TUP 1. Sede Regional Orán UNIVERSIDAD NACIONAL DE SALTA Unidad 5 Recursividad 1 Recursión Se dice que un elemento es recursivo, cuando en la definición de ese elemento, utilizamos nuevamente a ese elemento. Por ejemplo, para definir la relación familiar de

Más detalles

Objetivos. 1. Realizar exitosamente programas que involucren procesos que requieran iteraciones. Antecedentes

Objetivos. 1. Realizar exitosamente programas que involucren procesos que requieran iteraciones. Antecedentes Objetivos a) El alumno conocerá las tres formas básicas existentes en C para realizar iteraciones y aprenderá a manejar las sentencias while, do-while y for. b) El alumno comprenderá la importancia que

Más detalles

Laboratorio 5 Tema 7. Tipos de Datos Estructurados: Arreglos, Registros y Archivos

Laboratorio 5 Tema 7. Tipos de Datos Estructurados: Arreglos, Registros y Archivos Laboratorio 5 Tema 7. Tipos de Datos Estructurados: Arreglos, Registros y Archivos PARTE 1. Arreglos Unidimensionales o Vectores Un arreglo es una estructura de datos conformada por una sucesión de celdas,

Más detalles

Estructuras dinámicas lineales (i)

Estructuras dinámicas lineales (i) Estructuras dinámicas lineales (i) Introducción En la lección anterior se explicaron los conceptos de dinámicas y puntero; vimos la forma en que se implementan dichas tanto en la notación algorítmica como

Más detalles

Programación 1. Tema II. Diseño de los primeros programas. Lección 4. Diseño de algunos programas elementales

Programación 1. Tema II. Diseño de los primeros programas. Lección 4. Diseño de algunos programas elementales Programación 1 Tema II. Diseño de los primeros programas Lección 4. Diseño de algunos programas elementales 1 Objetivos de la lección: Aprender, paso a paso, una metodología de programación descendente

Más detalles

Informática PRÀCTICA 2 Curs

Informática PRÀCTICA 2 Curs Práctica Nº 2: Estructura general de un programa en C/C++. Introducción a las funciones de Entrada y salida en C++ (cin y cout) sin formato. Objetivos de la práctica: - Presentar la estructura general

Más detalles

Este método de diseño de algoritmos en etapas, yendo de los conceptos generales a los de detalle, se conoce como método descendente (top-down).

Este método de diseño de algoritmos en etapas, yendo de los conceptos generales a los de detalle, se conoce como método descendente (top-down). PLANTEMAIENTO DEL PROBLEMA Identificación de entradas y salidas Un algoritmo puede ser definido como la secuencia ordenada de pasos, sin ambigüedades, que conducen a la resolución de un problema dado y

Más detalles

Técnicas de prueba y corrección de algoritmos

Técnicas de prueba y corrección de algoritmos Técnicas de prueba y corrección de algoritmos Diseño y Análisis de Algoritmos Cátedra de Programación Carrera de Ingeniería de Sistemas Prof. Isabel Besembel Carrera Algoritmos recursivos Aparente circularidad

Más detalles

Ejercicios sobre recursividad

Ejercicios sobre recursividad Ejercicios sobre recursividad 11 de febrero de 2003 1. Implementa una función recursiva que devuelva la suma de los dígitos de un número natural, que se le pasa por parámetro. 2. Implementa una función

Más detalles

U.A.B.C. Facultad de Ingeniería Programación Estructurada UNIDAD III

U.A.B.C. Facultad de Ingeniería Programación Estructurada UNIDAD III UNIDAD III Funciones 3.1 Forma general de una función. C fué diseñado como un lenguaje de programación estructurado, también llamado programación modular. Por esta razón, para escribir un programa se divide

Más detalles

UNIVERSIDAD DON BOSCO FACULTAD DE ESTUDIOS TECNOLÓGICOS ESCUELA DE COMPUTACION

UNIVERSIDAD DON BOSCO FACULTAD DE ESTUDIOS TECNOLÓGICOS ESCUELA DE COMPUTACION UNIVERSIDAD DON BOSCO FACULTAD DE ESTUDIOS TECNOLÓGICOS ESCUELA DE COMPUTACION CICLO: 01/ 2012 Nombre de la Practica: Lugar de Ejecución: Tiempo Estimado: MATERIA: GUIA DE LABORATORIO #10 Programación

Más detalles

Lenguaje C, tercer bloque: Funciones

Lenguaje C, tercer bloque: Funciones Lenguaje C, tercer bloque: Funciones José Otero 1 Departamento de informática Universidad de Oviedo 28 de noviembre de 2007 Índice 1 Tipo puntero Concepto de puntero Operador dirección Operador indirección

Más detalles

Metodología de la Programación II. Recursividad

Metodología de la Programación II. Recursividad Metodología de la Programación II Recursividad Objetivos Entender el concepto de recursividad. Conocer los fundamentos del diseño de algoritmos recursivos. Comprender la ejecución de algoritmos recursivos.

Más detalles

UNIVERSIDAD AUTÓNOMA DEL ESTADO DE MÉXICO CENTRO UNIVERSITARIO UAEM ATLACOMULCO INGENIERÍA EN COMPUTACIÓN

UNIVERSIDAD AUTÓNOMA DEL ESTADO DE MÉXICO CENTRO UNIVERSITARIO UAEM ATLACOMULCO INGENIERÍA EN COMPUTACIÓN UNIVERSIDAD AUTÓNOMA DEL ESTADO DE MÉXICO CENTRO UNIVERSITARIO UAEM ATLACOMULCO INGENIERÍA EN COMPUTACIÓN REPORTE DE INVESTIGACIÓN PROGRAMA FUNCIÓN FACTORIAL ALGORITMO PROGRAMA FUNCION FIBONACCI ALGORITMO

Más detalles

Trabajo avanzado con consultas

Trabajo avanzado con consultas 1. ESTABLECER CRITERIOS H emos estado trabajando con consultas, incluso aplicando criterios más o menos complejos, pero sin pararnos mucho en cómo se construyen las expresiones que nos permiten recuperar

Más detalles

FRACCION GENERATRIZ. Pasar de decimal exacto a fracción

FRACCION GENERATRIZ. Pasar de decimal exacto a fracción FRACCION GENERATRIZ Un número decimal exacto o periódico puede expresarse en forma de fracción, llamada fracción generatriz, de las formas que indicamos: Pasar de decimal exacto a fracción Si la fracción

Más detalles

PARTE II: ALGORÍTMICA

PARTE II: ALGORÍTMICA Programa de teoría Parte I. Estructuras de Datos.. Abstracciones y especificaciones.. Conjuntos y diccionarios.. Representación de conjuntos mediante árboles. 4. Grafos. Parte II. Algorítmica.. Análisis

Más detalles

Algoritmos y Estructuras de Datos Curso 06/07. Ejercicios

Algoritmos y Estructuras de Datos Curso 06/07. Ejercicios 6.1.(Clase) Un programa que utiliza la técnica divide y vencerás, divide un problema de tamaño n en a subproblemas de tamaño n/b. El tiempo g(n) de la resolución directa (caso base) se considerará constante.

Más detalles

Tema 07: Backtraking. M. en C. Edgardo Adrián Franco Martínez edgardoadrianfrancom

Tema 07: Backtraking. M. en C. Edgardo Adrián Franco Martínez edgardoadrianfrancom Tema 07: Backtraking M. en C. Edgardo Adrián Franco Martínez http://www.eafranco.com edfrancom@ipn.mx @edfrancom edgardoadrianfrancom (Prof. Edgardo A. Franco) 1 Contenido Backtraking Búsqueda en profundidad

Más detalles

Programación Dinámica

Programación Dinámica Leopoldo Taravilse Facultad de Ciencias Exactas y Naturales Universidad de Buenos Aires Training Camp 2012 Leopoldo Taravilse (UBA) TC 2012 1 / 34 Contenidos 1 Recursión Principio de Optimalidad Ejemplos

Más detalles

SUBPROGRAMAS. Los subprogramas pueden ser invocados varias veces desde diferentes partes del programa.

SUBPROGRAMAS. Los subprogramas pueden ser invocados varias veces desde diferentes partes del programa. SUBPROGRAMAS Los subprogramas son un conjunto de instrucciones que realizan una labor específica y se comportan de manera independiente en un programa. Los subprogramas facilitan: Descomponer la complejidad

Más detalles

Capítulo 4. Control de flujo. Continuar

Capítulo 4. Control de flujo. Continuar Capítulo 4 Control de flujo Continuar Introducción El control de flujo permite encausar a la computadora sobre la ruta que debe seguir al momento de la ejecución de un programa, para ello se apoya en las

Más detalles

Análisis de algoritmos

Análisis de algoritmos Tema 09: Programación dinámica M. en C. Edgardo Adrián Franco Martínez http://www.eafranco.com edfrancom@ipn.mx @edfrancom edgardoadrianfrancom 1 Contenido Introducción Programación dinámica Enfoques de

Más detalles