Está en la página 1de 17

TEMA 1 RECURSIVIDAD INTRODUCCIN La recursividad, recursin o recurrencia, es una definicin o especificacin de una entidad o proceso, en trminos de s misma.

Este concepto se encuentra, en la prctica, aplicado a diferentes elementos como en definiciones textuales; figuras y grficas; objetos; expresiones matemticas; etc. Ejemplo, una frase recursiva es la siguiente: Para entender lo que es la recursividad, primero hay que saber qu es la recursividad. Ejemplo, una definicin recursiva corresponde a la definicin de la lnea y del punto: Una lnea es una sucesin de puntos y Un punto es la interseccin de dos lneas. Evidentemente es una definicin recursiva indirecta por cuanto tanto la lnea como el punto se definen, una en funcin de la otra, de forma recproca. Ejemplo, un objeto que conlleva la recursividad es la Matriushka, que es una mueca tradicional rusa que contiene en su interior otra mueca idntica de menor tamao y a su vez sta contiene otra y as sucesivamente.

A continuacin se muestra una fotografa de varias Matriuskas

Ej. Una imagen recursiva fcil, de obtener con un par de espejos, es la siguiente:

Algunas grficas que incluyen recursividad son las siguientes:

Incluyendo algunos comics, como el siguiente:

Un fractal tambin es un ejemplo clsico de figura recursiva, considerando que cada seccin de la misma es una rplica de su figura base, por ejemplo:

En matemtica, tambin se presentan expresiones recursivas, por ejemplo:

RECURSIVIDAD EN INFORMTICA Definicin: La recursividad es una tcnica de programacin que consiste en la definicin de un algoritmo en trminos de s mismo. Este concepto, en la prctica, se concretiza cuando un mtodo, funcin o procedimiento se invoca a s mismo. Para que un algoritmo recursivo sea til y prctico, debe satisfacerse los dos casos siguientes: Caso Base, es aquel estado particular del algoritmo que puede ser resuelto de forma directa, sin recursividad. En ciertos algoritmos puede presentarse ms de un caso base. Caso Recursivo, es aquel estado de un algoritmo, diferente del caso base, que puede resolverse invocndose a s mismo, de forma directa o indirecta, con parmetros que se aproximen al caso base. Una variedad de algoritmos presentan naturaleza recursiva por definicin; estos algoritmos tienen, en general, una solucin simple, estructurada y elegante. Por ejemplo, la definicin recursiva del factorial de un nmero n, puede ser implementada en java de la siguiente manera: public int factorial(int n){ if (n==0) return 1; // Caso Base else return (n*factorial(n-1)); // CasoRecursivo }

El algoritmo anterior presenta los casos Base y Recursivo y que el parmetro de este ltimo tiende al valor del caso Base en cada nueva llamada al mtodo factorial, de acuerdo a la definicin de la recursividad. En cada nueva llamada o invocacin al mtodo factorial, el mtodo que llama queda pendiente en su ejecucin a la espera de que la nueva llamada le otorgue la respuesta. TIPOS DE RECURSIVIDAD Por la forma de llamada, la recursividad se clasifica en: Recursividad Directa, se presenta cuando un proceso se invoca a s mismo. Por ejemplo el caso del factorial. Recursividad Indirecta, se presenta cuando un proceso invoca a otro y ste invoca al primero. Por ejemplo en la definicin del punto y la lnea. Por el nmero de llamadas recursivas que realiza un algoritmo, la recursividad se clasifica en simple y mltiple. Recursividad Simple, se presenta cuando un algoritmo recursivo, en su ejecucin realiza una sola llamada recursiva. Por ejemplo en el caso del factorial o de la definicin del punto y la lnea. Recursividad Mltiple, se presenta cuando un algoritmo recursivo, en su ejecucin realiza ms de una llamada recursiva. Por ejemplo en el caso de la serie de Fibonacci. La siguiente tabla resume las diferentes combinaciones de los tipos de recursividad:

La serie de Fibonacci es un buen ejemplo de recursividad mltiple, la cual se define como:

Por ejemplo, el siguiente mtodo devuelve el n-simo trmino de la serie de Fibonacci: public int Fibonacci(int n){ if (n==1 || n==2) return 1; else return Fibonacci(n-1)+Fibonacci(n-2); }

PROBLEMAS DE LA RECURSIVIDAD Cuando un mtodo recursivo se invoca a si mismo varias veces, en cada invocacin se crean copias independientes de las variables involucradas, esta situacin puede implicar el uso de gran cantidad de memoria, principalmente, cuando el nmero de llamadas es elevado e implica un tiempo de ejecucin prolongado.

En consecuencia, el un problema de la recursividad es que, en general conforman algoritmos ms ineficientes que los algoritmos iterativos equivalentes, por cuanto hacen uso excesivo de los dos recursos fundamentales de las computadoras: tiempo y memoria. Un segundo problema surge debido a que el mecanismo computacional interno de la recursividad hace uso intensivo de la pila (stack). En cada nueva llamada, los datos de las variables del algoritmo en ejecucin se almacenan en la pila, se crean nuevas variables que reciben los valores pasados por los parmetros y se pasa el control de la ejecucin al nuevo algoritmo a la espera de que ste d su resultado. De esta manera la pila va acumulando los datos de las diferentes llamadas que se realizan en la ejecucin de un algoritmo recursivo. Por ejemplo, recordando el algoritmo del factorial, la siguiente figura muestra el comportamiento de la pila durante las diferentes llamadas.

El problema surge cuando el nmero de llamadas es excesivo tal que puede desbordar la pila de la memoria, que tiene un tamao limitado, generando un error insalvable, denominado desbordamiento de pila (stack overflow), que generalmente provoca la interrupcin abrupta de la aplicacin. La redundancia es otro problema que se presenta en algunos algoritmos recursivos; consiste en la resolucin reiterativa del mismo proceso. Por ejemplo, en la ilustracin del clculo de Fib(4) visto anteriormente, se observa que Fib(2) se repite y calcula dos veces, Fib(1) se realiza cuatro veces, etc., lo cual colabora a reducir la eficiencia del algoritmo.

Por lo expuesto, se concluye que la recursividad solo debe emplearse en casos particualres, cuando el problema tenga una solucin iterativa muy compleja, no exista riesgo de desbordamiento de la pila y cuando el tiempo de ejecucin y el tamao de memoria empleados no constituyan factores crticos en la ejecucin de los programas. Ejemplos y ejercicios, para cada uno de los siguientes problemas, escribir un programa con un mtodo principal que invoque a uno o ms mtodos recursivos. Ejemplo 1: Escribir un programa que lea un nmero natural N y despliegue todos los enteros desde N hasta 1. Entrada 4 Salida 4 3 2 1 import java.util.Scanner; public class Ejemplo{ public static void main (String[] args) { Scanner tec=new Scanner(System.in); int N=tec.nextInt(); desplegar(N); } public static void desplegar(int N){ if (N>0){ System.out.println (N); desplegar(N-1); } } } Ejemplo 2: Escribir un programa que lea un nmero natural N y despliegue todos los enteros desde 1 hasta N. Entrada 4 Salida

1 2 3 4 import java.util.Scanner; public class Ejemplo{ public static void main (String[] args) { Scanner tec=new Scanner(System.in); int N=tec.nextInt(); desplegar(N); } public static void desplegar(int N){ if (N>0){ desplegar(N-1); System.out.println (N); } } } Ejemplo 3: Escribir un mtodo que, sin usar arreglos, lea del teclado varios nmeros naturales hasta el ingreso del nmero -1, que solo indica el final de los datos; luego desplegar los nmeros naturales en orden inverso al ingresado (no se debe usar arreglos). Entrada 42 12 79 22 -1 Salida 22 79 12 42 import java.util.Scanner; public class Ejemplo{ static Scanner tec=null; public static void main (String[] args) { tec=new Scanner(System.in); ingresar(); } public static void ingresar(){ int N=tec.nextInt(); if (N>=0){ ingresar();

System.out.println (N); } } } Ejemplo 4: Escribir un mtodo que lea diferentes nmeros enteros, hasta el ingreso del nmero de control: -1, y los despliegue en orden inverso, indicando cuales son primos. Entrada 20, 31, 9, 10, 17, -1 Salida 17 es primo 10 9 es primo 31 es primo 20 import java.util.Scanner; public class Ejemplo{ static Scanner tec=null; public static void main (String[] args) { tec=new Scanner(System.in); ingresar(); } public static void ingresar(){ int N=tec.nextInt(); if (N>=0){ ingresar(); if(esPrimo(N)) System.out.println(N+" es primo"); else System.out.println(N); } } public static boolean esPrimo(int n){ if(n==0) return false; else{ boolean primo=true; for(int i=2; i<(n/2+1); i++) if(n%i==0) primo=false; return primo; } } }

Ejemplo 5: Escribir un mtodo que reciba por parmetro un nmero natural N (0<N<999) y devuelva la suma de los primeros N nmeros naturales, es decir: 1+2+3++N. Entrada 4 Salida 10

import java.util.Scanner; public class Ejemplo{ public static void main (String[] args){ Scanner tec=new Scanner(System.in); int N=tec.nextInt(); System.out.println (suma(N)); } public static int suma(int N){ if (N==1)return 1; else return N+suma(N-1); } } Ejemplo 6: Escribir un mtodo que reciba por parmetro un arreglo de enteros y devuelva el ndice del mximo valor del arreglo. Entrada 34 85 21 43 78 Salida 1 import java.util.Scanner; public class Ejemplo{ public static void main (String[] args){ Scanner tec=new Scanner(System.in); int v[]={34, 85, 21, 43, 78}; System.out.println (indiceMax(v)); } public static int indiceMax(int[] v){ return indiceMaxRec(v, v.length-1, v.length-1); } public static int indiceMaxRec(int[] v, int n, int max){ if (n==-1)return max; else{

if(v[n]>v[max])max=n; return indiceMaxRec(v, n-1, max); } } } Ejercicio 1 Escribir un mtodo que reciba por parmetros dos nmeros naturales A y B (A<=B) y devuelva la suma de todos los nmeros naturales entre A y B, incluyendo stos. Entrada 5 10 Salida 45 Ejercicio 2 Escribir un mtodo que reciba un nmero natural N y devuelva la suma de todos los nmeros naturales pares desde 2 hasta N. Considerar que si N es un nmero impar la suma se realizar hasta N-1. Entrada 11 Salida 30 Ejercicio 3 Escribir un mtodo que reciba por parmetros dos enteros m y n (m > 0; n >= 0); y devuelva el resultado de la potencia m^n. Aplicar la definicin recursiva:

Entrada 32 Salida 9 Entrada 15 0 Salida 1 Ejercicio 4 Escribir un mtodo que reciba por parmetros dos enteros m y n (n >= 0; m > 0); y devuelva el resultado de la potencia m^n empleando la siguiente definicin recursiva:

Entrada 32 Salida 9 Entrada 15 0 Salida 1 Ejercicio 5 Escribir un mtodo que reciba por parmetros dos enteros m y n (n >= 0; m > 0); y devuelva el producto de x.y ({x, y}>=0), si est definido de la siguiente forma:

Entrada 32 Salida 6 Ejercicio 6 Escribir un mtodo que reciba un nmero natural y devuelva una cadena con el nmero binario equivalente. Entrada 19 Salida 10011 Ejercicio 7 Escribir un mtodo que reciba dos nmeros naturales m y n, y devuelva el mximo comn divisor (MCD) de m y n, calculado mediante el algoritmo de Euclides definido por:

Entrada 25 60 Salida 5 Ejercicio 8 Escribir un mtodo que reciba dos nmeros naturales m y n ({m, n}>=0), y devuelva la suma de los mismos, empleando la siguiente definicin:

Entrada 33 22 Salida 55 Ejercicio 9 Escribir un mtodo que reciba dos nmeros naturales m y n y devuelva el producto de ambos, calculado mediante el algoritmo ruso cuyo procedimiento consiste en duplicar sucesivamente m, mientras que paralelamente n se divide entre dos hasta que sea 1; luego se suman todos los valores de m que corresponden a los valores impares de n. Entrada 7 11 Salida 77 Ejercicio 10 Dado un nmero natural n (0<n<100), determinar el resultado de la serie definida como:

Entrada 5 Salida 63 Ejercicio 11 Escribir un mtodo que reciba los nmeros x y n (0<=x<1000) y (0<=n<100), y devuelva el resultado de la serie S(n)=1+x+x^2+x^3++x^n para cualquier x y n. La serie S(n) se define como:

Entrada 32 Salida 13 Ejercicio 12 Escribir un mtodo que reciba un nmero natural n (0<n<100) que indica el nmero de trminos con el que se calcular y devolver el valor del nmero neperiano e, en base a la siguiente expresin:

. Entrada 5

Salida 2.70833333 Ejercicio 13 Escribir un mtodo que despliegue los movimientos de discos de las torres de Hanoi, para llevar n discos de la torre A a la torre C, empleando la torre B como torre auxiliar. Los movimientos se realizan sujeto a las siguientes reglas: i) todos los discos son de tamao diferente; ii) los discos de menor tamao obligatoriamente van sobre discos de mayor tamao; iii) nicamente puede trasladarse un disco en la vez. Entrada 3 Salida A-C A-B C-B A-C B-A B-C A-C Ejercicio 14 La funcin de Ackerman A(m, n) se define para nmeros enteros no negativos m y n, del modo siguiente: A(0, n) = n + 1 A(m, 0) = A(m-1, 1) , siempre que m > 0 A(m, n) = A(m-1, A(m, n-1) , siempre que m > 0 y n > 0 Escribir un mtodo que implemente la funcin de Ackerman y un programa que la ejecute con todas las combinaciones de m y n desde 0 a 5, registrando el nmero de llamadas recursivas en cada caso. Ejercicio 15 Escribir un mtodo que reciba por parmetros dos nmeros naturales a y b (0<a<100), (0<=b<100), (a<=b), y devuelva el nmero de combinaciones de a elementos tomados de a b elementos, aplicando la definicin:

Entrada 53 Salida 10 Ejercicio 16 Escribir un mtodo que reciba un nmero natural n y devuelva true si n es par y false si n es impar, empleando recursividad indirecta. Entrada

24 Salida true Ejercicio 17 Escribir un mtodo que reciba un nmero natural n y devuelva true si ste es un factorial y false en caso contrario. Entrada 24 Salida true

También podría gustarte