Sei sulla pagina 1di 3

Algoritmi e Principi dell'Informatica

II Prova in itinere (parte Algoritmi)


17 maggio 2019

Esercizio 1 (1 punto)
Si consideri un albero binario i cui nodi contengono valori interi. Si scriva una funzione C++ che stampi la
sequenza di nodi che permette di raggiungere la foglia avente il valore maggiore. In caso di più foglie
aventi lo stesso valore, si consideri il percorso verso una delle foglie con valore massimo.

SOLUZIONE (traccia)

L’esercizio è stato discusso in classe con gli studenti in presenza, che hanno proposto varie soluzioni. Ne
riporto un paio.

1) Possibile soluzione: si trova il valore massimo e successivamente si visita l’albero a partire dalla
radice e si seleziona il figlio di sinistra o di destra se questo è la radice di un sottoalbero che
contiene una foglia con quel valore massimo

template <class Elem> int MaxFoglia(BinNode<Elem>* subroot) {


if (subroot == NULL)
return MIN_INT;
if (subroot->isleaf())
return subroot->value();
int l=MaxFoglia(subroot->left());
int r=MaxFoglia(subroot->right());
return l>r)?l:r;
}
template <class Elem> void print(BinNode<Elem>* subroot, int max) {
if (subroot == NULL)
return;
cout << subroot->value();
if EsisteMax(subroot->left(), max) {
print(subroot->left());
else {
print(subroot->right());
}
return;
}

template <class Elem> int esisteMax(BinNode<Elem>* subroot, int max) {


if (subroot == NULL)
return false;
if (subroot->isleaf()) && subroot->value()==max)
return true;
return (esisteMax(subroot->left()) || esisteMax(subroot->right()));
}

2) Altra soluzione: viene passato un array dalle foglie verso l’alto. Ciascuna foglia inserisce
nell’array il proprio valore (in prima posizione). Il padre riceverà 1 o 2 array: se ne riceve 1
aggiunge il proprio valore (mantenendo il valore della foglia in prima posizione) e restituisce
l’array al padre; se ne riceve 2 sceglie quello con il valore massimo (guardando la prima
posizione che contiene il valore della foglia) e aggiunge il proprio valore (può distruggere l’altro
array)

Esercizio 2 (1 punto)
Si determini la complessità della seguente funzione:
int function(int n) {

if (n < 10)

return 0;

else if (n%10==0){

int a=0;

for (i=1; i<n; i*=4)

for (j=1; j<i; j++)

a++;

return a;

else

return function(n/4) + function(n/4)+ n;

SOLUZIONE
int function(int n) {

if (n < 10)

return 0; Se n<10 Theta(1)

else if (n%10==0){ Se n divisibile per 10


int a=0;
for (i=1; i<n; i*=4) ciclo eseguito log4 n volte

for (j=1; j<i; j++) ciclo dipendente eseguito i volte (vedi sotto (*))
a++;

return a;

else Negli altri casi (n>=10 e n non divisibile per 10)

return function(n/4) + function(n/4)+ n; T(n)=2T(n/4)+Theta(1) (vedi sotto (**))


}

(*)

Doppio ciclo for

i j

1 1 volta = 4^0

4 4 volte = 4^1

16 16 volte = 4^2

….

Ignorando il primo passo e (senza perdita di generalità) includendo un ciclo esterno in più si ha:

Sommatoria per i che va da 1 a log4 n di 4^i = (4n-1)/3 = Theta(n)

(**)

Si può applicare il master theorem oppure la relazione di ricorrenza comune (con a=2, b=4  =1/2
mentre β=0) ottenendo O (n^(1/2))

Conclusioni:

Theta(1) per n<1;

T(n) = Theta(n) per n divisibile per 10;

O (n^(1/2)) altrimenti

Potrebbero piacerti anche