Docsity
Docsity

Prepara i tuoi esami
Prepara i tuoi esami

Studia grazie alle numerose risorse presenti su Docsity


Ottieni i punti per scaricare
Ottieni i punti per scaricare

Guadagna punti aiutando altri studenti oppure acquistali con un piano Premium


Guide e consigli
Guide e consigli


ritorsione informatica, Dispense di Elementi di Informatica

teoria degli algoritmi ricorsivi del corso di informatica

Tipologia: Dispense

2017/2018

Caricato il 08/06/2018

chiara-illiano
chiara-illiano 🇮🇹

1 documento

1 / 14

Toggle sidebar

Questa pagina non è visibile nell’anteprima

Non perderti parti importanti!

bg1
Algoritmi ricorsivi
Leonardo Lanzi [email protected]
Dipartimento di Fisica e Astronomia
Informatica (B015854) ·2017-2018
Corso di Laurea triennale in Fisica e Astrofisica
Leonardo Lanzi Algoritmi ricorsivi 1 / 14
pf3
pf4
pf5
pf8
pf9
pfa
pfd
pfe

Anteprima parziale del testo

Scarica ritorsione informatica e più Dispense in PDF di Elementi di Informatica solo su Docsity!

Algoritmi ricorsivi

Leonardo Lanzi – [email protected]

Dipartimento di Fisica e Astronomia

Informatica (B015854) · 2017-

Corso di Laurea triennale in Fisica e Astrofisica

Ricorsione

Spesso risulta naturale progettare un algoritmo usando lo stesso algoritmo

applicato ad uno o pi`u sotto-casi.

Esempio: cercare un nome all’interno dell’elenco telefonico.

(1) aprire l’elenco nel mezzo

(2) se il nome che si cerca `e in quella pagina, ritornare il numero di

telefono;

(3) se il nome `e alfabeticamente prima di quella pagina, cercare nella

prima parte dell’elenco;

(4) se il nome `e alfabeticamente dopo di quella pagina, cercare nella

seconda parte dell’elenco.

La ricerca all’interno di una parte dell’elenco telefonico avviene applicando

esattamente lo stesso algoritmo, che quindi in due casi invoca se stesso

(con argomenti differenti): per questo motivo, questo tipo di algoritmo `e

detto ricorsivo.

1 da P. Crescenzi, bozze II ed. “Gocce di Java”, 2014

Esempio di ricorsione diretta

unsigned long long int RFact ( int n ) { if ( n > 2) return n * RFact ( n - 1); if ( n > 0) return n ; }

int main () { int n = -1; while ( n < 1) { printf ( " n > 0: " ); scanf ( " % d " , & n ); } printf ( " n! = % lld \ n " , RFact ( n )); return 0; }

Esempio di ricorsione indiretta

void stampaNumeroDispari ( int n ) { printf ( " Numero dispari : % d \ n " , n ); if ( n > 1) { stampaNumeroPari ( n - 1); } }

void stampaNumeroPari ( int n ) { printf ( " Numero pari : % d \ n " , n ); stampaNumeroDispari ( n -1); }

int main () { int n = 0; while ( n <= 0) { printf ( " n : " ); scanf ( " % d " , & n ); } if ( n % 2 == 0) { stampaNumeroPari ( n ); } else { stampaNumeroDispari ( n ); } }

La torre di Hanoi

64 dischi d’oro su tre paletti di

diamante...

Si deve spostare la pila di dischi da

un piolo ad un altro, con le

condizioni:

I si pu`o spostare un solo disco

alla volta,

I un disco piu grande non puo

stare sopra un disco pi`u piccolo.

Soluzione ricorsiva

Si etichettano i pioli con A, B e C , e i dischi numerati da 1 (il pi`u piccolo)

a n (il pi`u grande). L’algoritmo si esprime come segue:

I sposta i primi n − 1 dischi da A a B (questo lascia il disco n da solo

sul piolo A);

I sposta il disco n da A a C ;

I sposta n − 1 dischi da B a C.

I Numero di spostamenti richiesti: O(2n^ − 1).

Codice Torre di Hanoi

include < stdio .h >

define DISCHI 5

int mossa ;

void muovi ( int nd , char pP , char pA ) { char invio ; mossa = mossa + 1; printf ( " \ n %3 d " , mossa ); printf ( " : muovi disco % d da % c a % c " , nd , pP , pA ); scanf ( " % c " , & invio ); return ; }

void hanoi ( int n , char pP , char pA , char aux ) { if ( n == 1) muovi (1 , pP , pA ); else { hanoi ( n - 1 , pP , aux , pA ); muovi (n , pP , pA ); hanoi ( n - 1 , aux , pA , pP ); } }

int main () { mossa = 0; printf ( " Mosse da eseguire per spostare % d dischi \ n " , DISCHI ); hanoi ( DISCHI , ’A ’ , ’B ’ , ’C ’ ); return 0; }

Codice sequenze binarie I

void BinGen ( int a [] , int n , int b ) { if ( b == 0) { stampaArray (a , n ); } else { a [ b - 1] = 0; BinGen (a , n , b - 1); a [ b - 1] = 1; BinGen (a , n , b - 1); } }

Esercizio: scrivere main e stampaArray per provare BinGen.

Ordinamento quicksort

I sceglie un elemento per il confronto (pivot);

I scorre gli elementi a sinistra finch´e non ne trova uno maggiore, e gli

elementi a destra finch´e non ne trova uno minore;

I scambia i due elementi trovati;

I continua finch´e a sinistra si trovano tutti elementi minori, a destra

tutti elementi maggiori;

I ripete i passi precedenti sui due sottoinsiemi, delimitati dal pivot,

finch´e i due sottoinsiemi sono ordinabili (indici sinistro e destro non

coincidono).

Codice Quicksort I

include < stdio .h >

void quicksort ( int a [] , int l , int r ); int partition ( int a [] , int l , int r ); int n ;

int main () { int i ; n = 10; int a [] = {5 , 4 , 12 , 2 , 7 , 12 , 18 , 4 , 1 , 3}; quicksort (a , 0 , 9);

for ( i = 0; i < n ; i ++) printf ( " % d " , a [ i ]); printf ( " \ n " );

return 0; }

Codice Quicksort II

void quicksort ( int a [] , int l , int r ) { int j ; if ( l < r ) { j = partition (a , l , r ); quicksort (a , l , j -1); quicksort (a , j +1 , r ); } } int partition ( int a [] , int l , int r ) { int pivot , i , j , t ; pivot = a [ l ]; i = l ; j = r +1; while (1) { do ++ i ; while ( a [ i ] <= pivot && i <= r ); do --j ; while ( a [ j ] > pivot ); if ( i >= j ) break ; t = a [ i ]; a [ i ] = a [ j ]; a [ j ] = t ; } t = a [ l ]; a [ l ] = a [ j ]; a [ j ] = t ; return j ; }