Lezione 12: Funzioni Ricorsive e Ricerca

Chiamate Ricorsive

Le funzioni in C posso chiamare se stesse in modo ricorsivo. Questo permette di implementare algoritmi in modo chiaro. Per cenni su come le chiamate ricorsive sono implementate, consultate stack.

Esempi

Calcolo del fattoriale (n! = 1×2×3× ⋅⋅⋅ ×n, n! = (n - 1)! × n):

// corretto fino a 20!
long long fattoriale(int n) {    
    if (n <= 1) return 1;
    else return n*fattoriale(n - 1);
}

Calcolo di una potenza intera:

// ritorna x elevato alla y
long long power(int x, int y) {    
    if (y == 0) return 1;
    long long p = power(x, y/2);
    return (y % 2 == 1 ? p*p*x : p*p);
}

Calcolo del minimo comune denominatore (algoritmo di Euclide):

long long mcd(long long a, long long b) {
    if (a == 0) return b;
    else if (a <= b) return mcd(b % a, a);
    else return mcd(a % b, b);
}

Calcolo dei coefficienti binomiali (C(n, k) = C(n − 1, k) + C(n − 1, k − 1)):

long long coeffbin(int n, int k) {
    if (n == 1 || k == 0) return 1;
    else return coeffbin(n - 1, k) + coeffbin(n - 1, k - 1);
}

Versione ricorsiva del selectionsort:

void swapint(int *a, int *b);

void selectionsortRicorsivo(int V[], int n) {
    if (n > 1) {
        int indmax = 0;
        for (int i = 1 ; i < n ; i++)
            if (V[i] > V[indmax]) indmax = i;
        swapint(&V[indmax], &V[n - 1]);
        selsortR(V, n - 1);
    }
}

Ricerca Binaria

 Ricerca binaria : versioni iterativa e ricorsiva:
/* Ricerca binaria versione ricorsiva. Assumendo che l'array A è 
 * ordinato in senso crescente, ritorna l'indice del valore x nel
 * sottoarray A[i, j], se non è presente ritorna -1. */
int binaryssearchRicorsivo(int A[], int i, int j, int x) {
    if (i > j) return -1;
    int m = (i + j)/2;
    if (A[m] == x) 
        return m;
    else if (A[m] < x)
        return bsearchR(A, m + 1, j, x);
    else
        return bsearchR(A, i, m - 1, x);
}

/* Ricerca binaria versione iterativa. Assumendo che l'array A (di
 * dimensione n) è ordinato in senso crescente, ritorna l'indice del
 * valore x, se non è presente ritorna -1. */
int binarysearch(int A[], int n, int x) {
    int a = 0, b = n - 1;
    while (a <= b) {
        int m = (a + b)/2;
        if (A[m] == x) return m;
        else if (A[m] < x) a = m + 1;
        else b = m - 1;
    }
    return -1;
}

Esercizi

Esercizio 12.1 Scrivere una funzione ricorsiva int binarysearchIns(int A[], int i, int j, int x) che esegue una ricerca binaria nell'array ordinato A, tra gli indici i e j, del valore x. Se x è presente ritorna l'indice in cui si trova, altrimenti ritorna l'indice della posizione in cui dovrebbe essere inserito per mantenere l'array ordinato. Ad esempio, se A = {2, 4, 7, 9}, x = 5, i = 0 e j = 3, la funzione deve ritornare 2.

Esercizio 12.2 Scrivere una funzione ricorsiva int pal(char C[], int n) che ritorna vero se l'array di n caratteri è palindromo, cioè, rimane lo stesso se letto da sinistra a destra o da destra a sinistra. Ad esempio, se C = {'r','o','t','o','r'}, ritorna vero; se invece C = {'r','o','t','o','r','e'} ritorna falso.