igor santos grueiro. para entender la recursividad, primero hay que entender lo qué es la...

73
Programación II Recursividad Igor Santos Grueiro

Upload: candelas-santibanez

Post on 21-Feb-2015

20 views

Category:

Documents


1 download

TRANSCRIPT

Page 1: Igor Santos Grueiro. Para entender la recursividad, primero hay que entender lo qué es la recursividad -Un programador anónimo

Programación IIRecursividad

Igor Santos Grueiro

Page 2: Igor Santos Grueiro. Para entender la recursividad, primero hay que entender lo qué es la recursividad -Un programador anónimo

“Para entender la

recursividad, primero hay que entender lo qué

es la recursividad”

-Un programador anónimo

?Hello world

Page 3: Igor Santos Grueiro. Para entender la recursividad, primero hay que entender lo qué es la recursividad -Un programador anónimo

¡¿QUÉ?!

Page 4: Igor Santos Grueiro. Para entender la recursividad, primero hay que entender lo qué es la recursividad -Un programador anónimo

La recursividad consiste en definir una entidad en función de sí misma

Page 5: Igor Santos Grueiro. Para entender la recursividad, primero hay que entender lo qué es la recursividad -Un programador anónimo

Podemos definir recursivamente

Tipos de datos Problemas

Page 6: Igor Santos Grueiro. Para entender la recursividad, primero hay que entender lo qué es la recursividad -Un programador anónimo

Definamos un tipo de datos de manera recursiva: clase Nodo

Object elementoNodo siguiente

Page 7: Igor Santos Grueiro. Para entender la recursividad, primero hay que entender lo qué es la recursividad -Un programador anónimo

Ejemplo de recursividad de tipos: Nodo

public class Nodo{private Object elemento;

private Nodosiguiente;

// Seguiría la definición …}

Page 8: Igor Santos Grueiro. Para entender la recursividad, primero hay que entender lo qué es la recursividad -Un programador anónimo

Ahora, a por la difícil: recursividad de ejecución o recursividad de problema

Page 9: Igor Santos Grueiro. Para entender la recursividad, primero hay que entender lo qué es la recursividad -Un programador anónimo

La recursividad de ejecución es la posibilidad de definir un problema en función del propio problema

Page 10: Igor Santos Grueiro. Para entender la recursividad, primero hay que entender lo qué es la recursividad -Un programador anónimo

Dicho de otro modo: una función que dentro

de su código se llama …

¡A SÍ MISMA!

Page 11: Igor Santos Grueiro. Para entender la recursividad, primero hay que entender lo qué es la recursividad -Un programador anónimo

Si se llama directamente a sí misma:recursividad directa

Si llama a otra a función que vuelve a llamar a la función original (1-n veces):

recursividad indirecta o mutua

Page 12: Igor Santos Grueiro. Para entender la recursividad, primero hay que entender lo qué es la recursividad -Un programador anónimo

Recursividad directa

public static int funcionRec(int n){if (n == 0){

return 1;}else{

return n * funcionRec(n-1);}

}

Se llama a sí misma directamente

Page 13: Igor Santos Grueiro. Para entender la recursividad, primero hay que entender lo qué es la recursividad -Un programador anónimo

Recursividad indirecta o mutua

public static boolean impar (int numero){ if (numero==0) return false; else return par(numero-1); }

public static boolean par (int numero){ if (numero==0) return true; else return impar(numero-1); }

Se llaman entre ellas

Page 14: Igor Santos Grueiro. Para entender la recursividad, primero hay que entender lo qué es la recursividad -Un programador anónimo

Para que una función pueda ser recursiva tienen que cumplirse

ciertos requisitos:

Page 15: Igor Santos Grueiro. Para entender la recursividad, primero hay que entender lo qué es la recursividad -Un programador anónimo

Que pueda definirse en términos de sí misma

Page 16: Igor Santos Grueiro. Para entender la recursividad, primero hay que entender lo qué es la recursividad -Un programador anónimo

Que exista un criterio de finalización o “caso base”

Page 17: Igor Santos Grueiro. Para entender la recursividad, primero hay que entender lo qué es la recursividad -Un programador anónimo

public static int funcionRec(int n){if (n == 0){

return 1;}else{

return n * funcionRec(n-1);}

}

Es el caso base

Page 18: Igor Santos Grueiro. Para entender la recursividad, primero hay que entender lo qué es la recursividad -Un programador anónimo

Que en cada llamada recursiva se esté más cerca de cumplirse

el Caso Base

Page 19: Igor Santos Grueiro. Para entender la recursividad, primero hay que entender lo qué es la recursividad -Un programador anónimo

public static int funcionRec(int n){if (n == 0){

return 1;}else{

return n * funcionRec(n-1);}

}

Al ir restando 1, nos acercamos al caso base: el número es 0

Page 20: Igor Santos Grueiro. Para entender la recursividad, primero hay que entender lo qué es la recursividad -Un programador anónimo

Que se resuelva el problema en un tiempo limitado o finito

Page 21: Igor Santos Grueiro. Para entender la recursividad, primero hay que entender lo qué es la recursividad -Un programador anónimo

Un ejemplo mítico: el

cálculo del factorial de un número

x!

Page 22: Igor Santos Grueiro. Para entender la recursividad, primero hay que entender lo qué es la recursividad -Un programador anónimo

Lo definimos matemáticamente

Solución iterativa:

x! = 1 · 2 · … · (x -1) · x

Solución recursiva:

Si x = 0 x! = 1Si x > 0 x! = x · (x-1)!

Page 23: Igor Santos Grueiro. Para entender la recursividad, primero hay que entender lo qué es la recursividad -Un programador anónimo

public static int factorial(int n){int fact = 1;for (int i = 1 ; i <= n ; i++){

fact *= i;}return fact;

}

Solución iterativa en Java

Page 24: Igor Santos Grueiro. Para entender la recursividad, primero hay que entender lo qué es la recursividad -Un programador anónimo

Haced la solución recursiva del procedimiento de cálculo del

factorial de un número

Page 25: Igor Santos Grueiro. Para entender la recursividad, primero hay que entender lo qué es la recursividad -Un programador anónimo

1 Definimos el caso base

public static int factorial(int n){if (n == 0){

return 1;}

}

El factorial de 0 es 1

Page 26: Igor Santos Grueiro. Para entender la recursividad, primero hay que entender lo qué es la recursividad -Un programador anónimo

2 Llamamos a la función

acercándonos al caso base

public static int factorial(int n){if (n == 0){

return 1;}else{

return n * factorial(n-1);}

}

Page 27: Igor Santos Grueiro. Para entender la recursividad, primero hay que entender lo qué es la recursividad -Un programador anónimo

Ejemplo n= 3

public static int factorial(int n){

if (n == 0){return 1;

}else{

return n * factorial(n-1);

}}

n

Valor de retorno 3 *

32

2 *

1

1 *

0

16

Page 28: Igor Santos Grueiro. Para entender la recursividad, primero hay que entender lo qué es la recursividad -Un programador anónimo

¡Hecho!

Page 29: Igor Santos Grueiro. Para entender la recursividad, primero hay que entender lo qué es la recursividad -Un programador anónimo

Ejercicio 1

Ejercicio:Escribir un programa que calcule todos los factoriales del 1 hasta el valor

entero N que se introduce por teclado, el valor de N es mayor de cero.

Diseñad un método que calcule la potencia de un numero real elevado a

un entero (en función de multiplicaciones sucesivas).

Tanto solución iterativa como recursiva

Page 30: Igor Santos Grueiro. Para entender la recursividad, primero hay que entender lo qué es la recursividad -Un programador anónimo

public static double potencia(double base, int exp){double pot = 1;for (int i=1; i<= exp; i++){ pot = pot * base;}return pot;

}

Solución iterativa

Page 31: Igor Santos Grueiro. Para entender la recursividad, primero hay que entender lo qué es la recursividad -Un programador anónimo

public static double potencia(double base, int exp){if (exp == 0) return 1;else return (base * potencia(base, exp - 1));

}

Solución recursiva

Page 32: Igor Santos Grueiro. Para entender la recursividad, primero hay que entender lo qué es la recursividad -Un programador anónimo

Ejercicio 2

Ejercicio:Escribir un programa que calcule todos los factoriales del 1 hasta el valor

entero N que se introduce por teclado, el valor de N es mayor de cero.

Escribid un método que calcule la suma de los N (N>0) primeros números naturales.

Solución recursiva

Page 33: Igor Santos Grueiro. Para entender la recursividad, primero hay que entender lo qué es la recursividad -Un programador anónimo

public static int sumaNaturales(int n) {// Caso base: la suma de los números hasta 0 es 0if (n == 0)

return 0;else

return (n + sumaNaturales(n - 1));}

Solución recursiva primera versión

Page 34: Igor Santos Grueiro. Para entender la recursividad, primero hay que entender lo qué es la recursividad -Un programador anónimo

public static int sumaNaturales(int n) {// Caso base: la suma de los números hasta 1 es 1if (n == 1)

return 1;else

return (n + sumaNaturales(n - 1));}

Solución recursiva segunda versión

Page 35: Igor Santos Grueiro. Para entender la recursividad, primero hay que entender lo qué es la recursividad -Un programador anónimo

Ejercicio 3

Ejercicio:Escribir un programa que calcule todos los factoriales del 1 hasta el valor

entero N que se introduce por teclado, el valor de N es mayor de cero.

Escribid un método que visualice los N primeros números naturales del 1 al N

Solución recursiva

Page 36: Igor Santos Grueiro. Para entender la recursividad, primero hay que entender lo qué es la recursividad -Un programador anónimo

public static void visualizarNumerosHastaN(int n) {if (n > 0) {

visualizarNumerosHastaN(n - 1);System.out.println(n);

}// Caso base: Si hemos llegado a 0 no muestro // nada

}

Solución recursiva

Page 37: Igor Santos Grueiro. Para entender la recursividad, primero hay que entender lo qué es la recursividad -Un programador anónimo

Ejercicio 4

Ejercicio:Escribir un programa que calcule todos los factoriales del 1 hasta el valor

entero N que se introduce por teclado, el valor de N es mayor de cero.

Escribir un método que visualice los N primeros números naturales del N al 1

Solución recursiva

Page 38: Igor Santos Grueiro. Para entender la recursividad, primero hay que entender lo qué es la recursividad -Un programador anónimo

public static void visualizarNumerosDesdeN(int n) {if (n > 0) {

System.out.println(n);// Se hace después la llamada para ir de // N a 1visualizarNumerosDesdeN(n - 1);

}// Caso base: Si hemos llegado a 0 no muestro // nada

}

Solución recursiva

Page 39: Igor Santos Grueiro. Para entender la recursividad, primero hay que entender lo qué es la recursividad -Un programador anónimo

Ejercicio 5

Ejercicio:Escribir un programa que calcule todos los factoriales del 1 hasta el valor

entero N que se introduce por teclado, el valor de N es mayor de cero.

Escribid un método que visualice los dígitos de un número natural N al revés

N = 7815 visualizar el numero 5187

Page 40: Igor Santos Grueiro. Para entender la recursividad, primero hay que entender lo qué es la recursividad -Un programador anónimo

public static void visualizarDigitosReves(int n) {// El caso base es que hemos llegado // al último digito (<10)

if (n < 10) {System.out.println(n);

} else {System.out.print(n % 10);visualizarDigitosReves(n / 10);

}}

Solución recursiva

Page 41: Igor Santos Grueiro. Para entender la recursividad, primero hay que entender lo qué es la recursividad -Un programador anónimo

Ejercicio 6

Ejercicio:Escribir un programa que calcule todos los factoriales del 1 hasta el valor

entero N que se introduce por teclado, el valor de N es mayor de cero.

Escribid un método que visualice los dígitos de un número natural N, uno por línea.

Page 42: Igor Santos Grueiro. Para entender la recursividad, primero hay que entender lo qué es la recursividad -Un programador anónimo

public static void visualizarDigitos(int n) {// El caso base es que hemos llegado // al último digito (<10)if (n < 10){

System.out.println(n);}else {

int digito = n % 10;visualizarDigitos(n / 10);System.out.println(digito);

}}

Solución recursiva

Page 43: Igor Santos Grueiro. Para entender la recursividad, primero hay que entender lo qué es la recursividad -Un programador anónimo

Ejercicio 7

Ejercicio:Escribir un programa que calcule todos los factoriales del 1 hasta el valor

entero N que se introduce por teclado, el valor de N es mayor de cero.

Escribid un método que sirva para subrayar un texto

Page 44: Igor Santos Grueiro. Para entender la recursividad, primero hay que entender lo qué es la recursividad -Un programador anónimo

public static void subrayar(int longitud){if (longitud > 0) {

System.out.print("_");subrayar(longitud-1);

}// El caso base es que la longitud sea 0

}

Solución recursiva

Page 45: Igor Santos Grueiro. Para entender la recursividad, primero hay que entender lo qué es la recursividad -Un programador anónimo

Búsqueda binaria

Ejercicio:Escribir un programa que calcule todos los factoriales del 1 hasta el valor

entero N que se introduce por teclado, el valor de N es mayor de cero.

Escribid un método que busque un valor en un array de enteros de un modo dicotómico (el array está ordenado de menor a mayor).

Page 46: Igor Santos Grueiro. Para entender la recursividad, primero hay que entender lo qué es la recursividad -Un programador anónimo

Búsqueda dicotómica o binaria

1 3 5 8 9

Valor a buscar 3

Valor medio

Si el valor medio es mayor que el valor a buscar …

1 3

Valor medioComo el valor medio es igual que el valor a buscar

Devolvemos la posición del valor medio: 1

Page 47: Igor Santos Grueiro. Para entender la recursividad, primero hay que entender lo qué es la recursividad -Un programador anónimo

public static int busquedaBinaria(int [] aEnteros, int valor, int rangoMenor, int rangoMayor){

int med = (rangoMayor - rangoMenor)/2 + RangoMenor;

if (rangoMenor > rangoMayor){return -1;

}else if (aEnteros[med] < valor){

return busquedaBinaria(aEnteros, valor, med + 1,rangoMayor);

}else if (aEnteros[med] > valor){

return busquedaBinaria(aEnteros, valor, rangoMenor, med - 1);

}else{

return med;}

}

Solución recursiva

Page 48: Igor Santos Grueiro. Para entender la recursividad, primero hay que entender lo qué es la recursividad -Un programador anónimo

Un ejemplo

Ejercicio:Escribir un programa que calcule todos los factoriales del 1 hasta el valor

entero N que se introduce por teclado, el valor de N es mayor de cero.

Escribir un método que sume los elementos de un array de manera recursiva

Page 49: Igor Santos Grueiro. Para entender la recursividad, primero hay que entender lo qué es la recursividad -Un programador anónimo

public static void main(String[] args){int [] aNumeros = {1, 3, 5, 7, 9, 11, 13};int suma =sumarArray(aNumeros);

System.out.println(suma);}

public static int sumarArray(int [] a) {

}

Partimos de esto

Page 50: Igor Santos Grueiro. Para entender la recursividad, primero hay que entender lo qué es la recursividad -Un programador anónimo

A veces se llama un método que llama a un método recursivo para

añadir parámetros necesarios de la solución recursiva

Page 51: Igor Santos Grueiro. Para entender la recursividad, primero hay que entender lo qué es la recursividad -Un programador anónimo

public static int sumarArray(int [] aEnteros) { sumarArrayRec(aEnteros,0);

}

public static int sumarArrayRec(int [] aEnteros, int pos){

// Si hemos llegado al final // del array la suma es 0if (pos == aEnteros.length){

return 0;} else{

return aEnteros[pos] + sumarArrayRec(aEnteros, pos+1);

}}

Solución

Page 52: Igor Santos Grueiro. Para entender la recursividad, primero hay que entender lo qué es la recursividad -Un programador anónimo

Es lo que se conoce como

recursividad en concha

Page 53: Igor Santos Grueiro. Para entender la recursividad, primero hay que entender lo qué es la recursividad -Un programador anónimo

Ejercicio 1

Ejercicio:Escribir un programa que calcule todos los factoriales del 1 hasta el valor

entero N que se introduce por teclado, el valor de N es mayor de cero.

Diseñar un método para visualizar los elementos de un array de enteros.

Con recursividad en concha

Page 54: Igor Santos Grueiro. Para entender la recursividad, primero hay que entender lo qué es la recursividad -Un programador anónimo

public static void visualizarArray(int[] aEnteros) { visualizarArrayRec(aEnteros, aEnteros.length - 1);}

public static void visualizarArrayRec(int[] aEnteros, int pos){

if (pos >= 0) {visualizarArrayRec(aEnteros, pos - 1);System.out.println(aEnteros[pos]);

}}

Solución

Page 55: Igor Santos Grueiro. Para entender la recursividad, primero hay que entender lo qué es la recursividad -Un programador anónimo

Ejercicio 2

Ejercicio:Escribir un programa que calcule todos los factoriales del 1 hasta el valor

entero N que se introduce por teclado, el valor de N es mayor de cero.

Diseñar un método para visualizar los elementos de un fichero de alumnos(Alumno tiene un método mostrar)

Page 56: Igor Santos Grueiro. Para entender la recursividad, primero hay que entender lo qué es la recursividad -Un programador anónimo

public static void visualizarAlumnos(String nFic) throws Exception{

FileInputStream fis = new FileInputStream(nFic);ObjectInputStream ois =

new ObjectInputStream(fis);visualizarAlumnosRec(ois);ois.close();

}

public static void visualizarAlumnosRec(ObjectInputStream ois) throws Exception{

Alumno a = (Alumno) ois.readObject();if (a != null){

a.mostrar();visualizarAlumnosRec (ois);

}}

Solución

Page 57: Igor Santos Grueiro. Para entender la recursividad, primero hay que entender lo qué es la recursividad -Un programador anónimo

Ahora, a por la

recursividad múltiple

Cuando una función se llama a sí misma

varias veces

Page 58: Igor Santos Grueiro. Para entender la recursividad, primero hay que entender lo qué es la recursividad -Un programador anónimo

La serie de

Fibonaccif(0) = 0f(1) = 1

f(n) = f(n-1) + f(n-2)

Page 59: Igor Santos Grueiro. Para entender la recursividad, primero hay que entender lo qué es la recursividad -Un programador anónimo

Ejercicio 1

Ejercicio:Escribir un programa que calcule todos los factoriales del 1 hasta el valor

entero N que se introduce por teclado, el valor de N es mayor de cero.

Realizar una función recursiva quecalcule el termino n de la serie deFibonacci

Page 60: Igor Santos Grueiro. Para entender la recursividad, primero hay que entender lo qué es la recursividad -Un programador anónimo

public static int fibonacci(int n){// Caso base primero si el término es 0// entonces es 0if (n == 0){

return 0;}// Caso base segundo si el término es 1 // entonces 1else if (n == 1){

return 1;}// Caso recursivo. Se llama dos veces a la // función recursivaelse{

return fibonacci(n-1) + fibonacci(n-2);}

}

Solución

Page 61: Igor Santos Grueiro. Para entender la recursividad, primero hay que entender lo qué es la recursividad -Un programador anónimo

Ejercicio 2

Ejercicio:Escribir un programa que calcule todos los factoriales del 1 hasta el valor

entero N que se introduce por teclado, el valor de N es mayor de cero.

Diseñar un método para calcular el número combinatorio de “m” elementos tomados de “n” en “n”.

Page 62: Igor Santos Grueiro. Para entender la recursividad, primero hay que entender lo qué es la recursividad -Un programador anónimo

Primera forma de solución:

Cm,n = m! / n!(m-n)!

Page 63: Igor Santos Grueiro. Para entender la recursividad, primero hay que entender lo qué es la recursividad -Un programador anónimo

No tiene recursividad propia

Page 64: Igor Santos Grueiro. Para entender la recursividad, primero hay que entender lo qué es la recursividad -Un programador anónimo

Segunda forma de solución: Iterativa

Cm,n = 1 * (m-1+1) / 1 * (m-2+1) / 2 * ... *(m-i+1) / i

Page 65: Igor Santos Grueiro. Para entender la recursividad, primero hay que entender lo qué es la recursividad -Un programador anónimo

No tiene recursividad

Page 66: Igor Santos Grueiro. Para entender la recursividad, primero hay que entender lo qué es la recursividad -Un programador anónimo

Tercera forma de solución:

Recursividad Directa Simple

si n = 0 Cm,n = 1si n > 0 Cm,n = Cm,n-1 * (m-n+1) / n

Page 67: Igor Santos Grueiro. Para entender la recursividad, primero hay que entender lo qué es la recursividad -Un programador anónimo

public static int combinacionesSimple(int m , int n){if (n == 0){

return 1;}else{

return combinacionesSimple(m, n - 1) * (m – n + 1)/n;

}}

Solución

Page 68: Igor Santos Grueiro. Para entender la recursividad, primero hay que entender lo qué es la recursividad -Un programador anónimo

Cuarta forma de solución:

Recursividad Directa Múltiple

si n = 0 Cm,n = 1si n = m Cm,n = 1si n > m Cm,n = 0si m > n > 0 Cm,n = Cm-1,n + Cm-1,n-1

Page 69: Igor Santos Grueiro. Para entender la recursividad, primero hay que entender lo qué es la recursividad -Un programador anónimo

public static int combinacionesMultiple(int m , int n){

if (n == 0 || m == n){return 1;

}else{

return combinacionesMultiple(m -1 ,n) * combinacionesMultiple(m-1 , n - 1);

}}

Solución

Page 70: Igor Santos Grueiro. Para entender la recursividad, primero hay que entender lo qué es la recursividad -Un programador anónimo

Para entender la recursividad, había que saber

lo qué era la recursividad

Page 71: Igor Santos Grueiro. Para entender la recursividad, primero hay que entender lo qué es la recursividad -Un programador anónimo

La recursividad NO es eficiente

Page 72: Igor Santos Grueiro. Para entender la recursividad, primero hay que entender lo qué es la recursividad -Un programador anónimo

La recursividad proporciona

soluciones elegantes

Page 73: Igor Santos Grueiro. Para entender la recursividad, primero hay que entender lo qué es la recursividad -Un programador anónimo

“Hay pocas virtudes sin prudencia”

-Marco Tulio Cicerón