Ricorsione
 Strumento potente per definizioni
matematiche
 Possibilità di definire insieme infinito di
oggetti con regola finita
 possibilità di descrivere un insieme infinito di
computazioni con un programma finito
Ricorsione in matematica
 Le formule matematiche sono spesso
espresse in termini ricorsivi
 Esempio: definizione di fattoriale
1!=1
N!=N * (N-1)!
Metodi ricorsivi
 Contengono riferimenti espliciti a sé stessi
 direttamente ricorsivi
 Un metodo ne invoca un altro e
l’esecuzione di quest’ultimo porta ad un
certo punto ad invocare nuovamente
(direttamente o indirettamente) il metodo
originale
 indirettamente ricorsivi
Ricorsione infinita
 Requisito fondamentale:
 chiamata ricorsiva subordinata ad una condizione che
ad un certo istante deve divenire non soddisfatta
 Qualsiasi definizione ricorsiva deve avere
una parte non ricorsiva, detta base della
ricorsione, che permette alla ricorsione
stessa di terminare
 Nell’esempio precedente del fattoriale la
base è 1! che è posto uguale ad 1
Variabili in metodi ricorsivi
 Ogni invocazione genera un nuovo
insieme di variabili locali
 Ogni parametro riceve un valore iniziale in
base alla nuova invocazione
 Ogni volta che il metodo termina si ritorna
al metodo che lo ha chiamato ( che
potrebbe essere lo stesso)
Numeri di Fibonacci
 Schema più complicato di composizione
ricorsiva che potrebbe (e dovrebbe)
essere tradotto in forma iterativa
 Definizione:
 fib0 = 0
 fib1 = 1
 fibn+1 = fibn + fibn-1
Implementazione ricorsiva
int computeFib(int n)
{
if (n == 0)
return 0;
if (n == 1)
return 1;
return computeFib(n-1)+computeFib(n2);
}
Numero di invocazioni
5
4
3
2
3
2
1
1
2
1
1
0
0
 Numero totale di invocazioni cresce
esponenzialmente
1
0
Implementazione iterativa
int computeFib(int n)
{
int i = 1, x = 1, y = 0;
while (i < n) {
i = i+1;
x = x+ y;
y = x -y;
}
return x;
}
Considerazioni
 Ricorsione deve essere evitata se esiste
una soluzione iterativa ovvia
 Non vuol dire evitare la ricorsione a
qualunque costo
 esistono molte buone applicazioni della
ricorsione
 algoritmi per loro natura ricorsivi vanno
implementati con metodi ricorsivi
Le torri di Hanoi
inventato nel 1880 da Lucas
 Tre aste (o torri) ed n dischi di dimensioni diverse
(con buco per inserirli nelle aste)
 All’inizio tutti i dischi sono nell’asta 1
 in ordine decrescente di grandezza
 Obiettivo: portarli nella torre 3 rispettando le
regole seguenti




nessun disco mai sopra uno più piccolo
si può spostare un solo disco alla volta
dischi sempre collocati su una torre (non a parte)
solo disco in cima ad una torre può essere spostato
Algoritmo ricorsivo
 Obiettivo: spostare k dischi da torre 1 a torre 3
 Algoritmo:
 Spostare k-1 dischi da torre originale a torre
temporanea
 Spostare 1 disco da torre originale a torre di
destinazione
 Spostare k-1 dischi da torre temporanea
a torre di destinazione
Implementazione 1
void moveTowers(int k, int o,int d)
{
if (k > 0)
{
moveTowers(k-1, o, 6-o-d);
System.out.println("Sposta da "+o+"a"+d);
moveTowers(k-1,6-o-d,d);
}
}