Está en la página 1de 37

Recursividad

Jenny Carolina Ramrez

Recursividad
DEFINICIN
La
recursividad
es
una
tcnica
de
programacin que se utiliza para dar solucin
a un problema descomponindolo en
problemas ms pequeos del mismo tipo. Se
dice que un mtodo es recursivo cuando se
llama a s mismo desde el mismo mtodo.

Recursividad
CARACTERSTICAS
Un algoritmo recursivo consta de:
- Una parte recursiva
- Una parte iterativa o no recursiva
- Una condicin de terminacin.
La parte recursiva y la condicin de
terminacin siempre existen. En cambio la
parte no recursiva es opcional y puede
coincidir con la condicin de terminacin.

Recursividad
Algo muy importante a tener en cuenta
cuando usemos la recursividad es que es
necesario asegurarnos que llega un momento
en que no hacemos ms llamadas recursivas.
Si no se cumple esta condicin el programa
no parar nunca.

Tipos de recursividad
TIPOS DE RECURSIVIDAD

Recursividad simple

Recursividad
mltiple

Recursividad anidada

Aquella en cuya definicin slo aparece una llamada recursiva. Se puede transformar
con facilidad en algoritmos iterativos.

Se da cuando hay ms de una llamada a s misma dentro del cuerpo de la funcin,


resultando ms difcil de hacer de forma iterativa. Un ejemplo tpico es la funcin de
fibonacci.

En algunos de los argumentos de la llamada recursiva hay una nueva llamada a s


misma. Ejemplo: la funcin Ackermann

Son algoritmos donde una funcin provoca una llamada a s misma de forma
indirecta, a travs de otras funciones.
Recursividad cruzada
o indirecta

Recursividad Ejemplo
Bsico
void imprimir(int x)
{
if (x>0)
{
imprimir(x-1);
System.out.println(x);
}

Bsqueda de soluciones recursivas: cuatro


preguntas
bsicas.

Cmo se puede definir el problema en


trminos de uno o ms problemas ms
pequeos del mismo tipo que el original?
Qu instancias del problema harn de caso
base?
Conforme el problema se reduce de tamao
se alcanzar el caso base?
Cmo se usa la solucin del caso base
para construir una solucin correcta al
problema original?

Ejemplo: la sucesin de
Fibonacci.
1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144,
El tercer trmino de la sucesin se obtiene
sumando el segundo y el primero.
El cuarto, a partir de la suma del tercero y
el segundo.

El problema: calcular el valor del n-simo


trmino de la solucin, que se obtendr
sumando los trminos n-1 y n-2.

Ejemplo: la sucesin de
Fibonacci.
Las respuestas a la preguntas anteriores
seran:

Cmo se puede definir el problema en


trminos de uno o ms problemas ms
pequeos del mismo tipo que el
original?
fibonacci(n) = fibonacci(n-1) + fibonacci(n2).

Ejemplo: la sucesin de
Fibonacci.

Qu instancias del problema harn de


caso base?
Casos bases:
fibonacci(1) = 1 y fibonacci(2)=1

Ejemplo: la sucesin de
Fibonacci.

Conforme el problema se reduce de


tamao se alcanzar el caso base?
En cada llamada a la rutina fibonacci se
reduce el tamao del problema en uno o en
dos, por lo que siempre se alcanzar uno de
los dos casos bases.

Ejemplo: la sucesin de
Fibonacci.

Cmo se usa la solucin del caso base


para construir una solucin correcta al
problema original?
fibonacci(3) = fibonacci(2) + fibonacci(1) = 1 +
1.

Se construye la solucin del problema n==2


a partir de los dos casos bases.

Ejemplo: la sucesin de
Fibonacci.
int fibonacci(int n)
{
if ((n == 1) || (n == 2)) return 1;
else
return (fibonacci(n-2) + fibonacci(n1));
}

Ejemplo: la sucesin de
Fibonacci.

Ejemplo: Factorial de un numero

Ejemplo: Factorial de un numero


public long factorial (long n)
{
if (n == 0) return 1;
else
return n * factorial(n-1);
}

Ejemplo: Factorial de un numero

Elemplo
public void reves(int n)
{
System.out.print(n % 10);
if( n/10!=0 )
reves(n/10);
}

Realizar rbol e prueba

Una mejor manera de


hacerlo
int invertir (int n)
{
if (n < 10) //caso base
return n;
else
return (n % 10) *pow(10,longi(n)-1)+ invertir (n / 10);
}

Ejemplo
public void conversionBase(int n, int b)
{
if(n<b)
System.out.print(n);
else
{
conversionBase(n/b,b);
System.out.print(n%b);
}
}
Realizar rbol e prueba

RETO

Hacer que el ejercicio anterior retornen un


entero

Respuesta
public int base2(int x)
{
if(x<2)
return x;
else
{
if(x%2==0)
{
return base2(x/2)*10;
}
else
return base2(x/2)*10+(x%2);
}
}

Ejercicio

Programar un algoritmo recursivo


que permita hacer la divisin por
restas sucesivas

Respuesta
Int division( int a, int b)
{
if(b>a)
return0;
else

return division(a-b, b)+1;


}

Ejemplo
Funcin de Ackermann

Ejemplo
Funcin de Ackermann
publicint Ackermann(int p, int q)
{
if(p==0)
return q+1;
else
if(q==0)
return Ackermann(p-1,1);
else
return Ackermann(p-1,Ackermann(p,q-1));
}

Taller en grupos
1. Algoritmo recursivo que permita sumar
los dgitos de un nmero.
2. Algoritmo recursivo que muestre el
numero menor de un vector

Ejemplo: mximo comn divisor


de dos nmeros m y n.

[P1] Es evidente que MCD(m, n) ha sido


definida en trminos de un problema del
mismo tipo, pero justifiquemos que
MCD(m, n % m) es de tamao menor que
MCD(m, n):
El rango de m % n es 0, ..., n-1, por tanto el resto
es siempre menor que n.

Ejemplo: mximo comn divisor


de dos nmeros m y n.
Si m > n, entonces MCD(n, m % n) es
menor que MCD(m, n).
Si n > m, el resto de dividir m entre n es
m, por lo que la primera llamada
recursiva es MCD(n, m mod n) es
equivalente a MCD(n, m), lo que tiene el
efecto de intercambiar los argumentos y
producir el caso anterior.

Ejemplo: mximo comn divisor


de dos nmeros m y n.

[P2] Si n divide a m, si y slo si,


m mod n = 0, en cuyo caso MCD(m, n) = n,
por tanto, se conseguir el caso base
cuando el resto sea cero.

[P3] Se alcanzar el caso base ya que n se


hace ms pequeo en cada llamada y
adems se cumple que 0 * m mod n * n-1.

Ejemplo: mximo comn divisor


de dos nmeros m y n.

[P4] En este caso, cuando se llega al caso


base es cuando se obtiene la solucin final
al problema, por lo que no se construye la
solucin general en base a soluciones de
problemas ms simples.

Ejemplo: mximo comn divisor


de dos nmeros m y n.
public int mcd (int m, int n)
{
if (m % n == 0)
return n;
else
return (mcd(n, m % n));
}

Ejemplo: conteo de ocurrencias


de un valor en un vector.
[P1] Si el primer elemento = valor buscado,
entonces la solucin ser 1 ms el nmero
de veces que aparece dicho valor en el
resto del vector.
Si no, la solucin al problema original ser
el nmero de veces que el valor se
encuentra en las posiciones restantes

Ejemplo: conteo de ocurrencias


de un valor en un vector.

[P2] El vector a est vaco =>ocurrencias


en el vector= 0.

[P3] Cada llamada recursiva se reduce en


uno el tamao del vector, por lo que nos
aseguramos que en N llamadas habremos
alcanzado el caso base.

Ejemplo: conteo de ocurrencias


de un valor en un vector.

[P4] Cuando se encuentra una coincidencia


se suma uno al valor devuelto por otra
llamada recursiva. El retorno del control de
las
sucesivas
llamadas
comenzar
inicialmente sumando 0 cuando nos
hayamos salido de las dimensiones del
vector.

Ejemplo: conteo de ocurrencias


de un valor en un vector.
public int contarOcurrencias (int n, int[] vector, int objetivo,
int primero)
{
if (primero > n-1) return 0;
else
{
if (vector[primero] == objetivo)
return(1+contarOcurrencias(n,vector,objetivo,primero+1));
else
return(contarOcurrencias(n,vector, objetivo,primero+1));
}

el
el
el
el

tamao del vector (n),


propio vector (vector),
valor a buscar (objetivo) y
ndice del primer elemento del vector a procesar (primero).

Ejemplo recursividad
cruzada
public boolean impar (int numero)
{
if (numero==0)
return false;
else
return par(numero-1);
}
public boolean par (int numero)
{
if (numero==0)
return true;
else
return impar(numero-1);
}