INFORMATICA 3
Prof.ssa Sara Comai
ESERCIZI SESSIONE LIVE 3
Complessità, liste e alberi
Ing. Paola Spoletini, Sara Comai
1. Complessità
Si determini l’ordine di grandezza Q della complessità temporale di tale frammento
in funzione di n
i = i*i;
while ( i <= n) {
b[j] = a[i];
j++;
i = i*i;
}
Si determini l’ordine di grandezza Q della complessità temporale di tale frammento
in funzione di n
SOLUZIONE
Simuliamolo: 2 Æ 2*2 Æ 4*4Æ16*16 Æ …
Cioè 2Æ 22Æ22*22Æ24*24Æ…
Che è 2Æ22Æ24Æ28Æ…
Che si può vedere come 2Æ22Æ22^2Æ22^3Æ…Ælog(log n)
2. Alberi binari
In un albero binario la numerazione per livelli assegna a ogni nodo v dell’albero un
valore intero positivo p(v) in accordo alle seguenti regole:
• se v è la radice allora p(v) = 1
• se v è figlio sinistro di u allora p(v) = 2 * p(u)
• se v è figlio destro di u
allora p(v) = 2 * p(u) + 1
In figura è riportato un esempio di tale numerazione.
1
2
3
4
5
7
10
8
11
22
23
DOMANDA 1
Indicare qual è il valore massimo p(v) che può essere assegnato a un nodo v di un
albero binario che contiene n nodi, giustificando la risposta.
[Suggerimento: considerare, per un albero fissato, qual è il nodo cui viene assegnato
il valore massimo.]
DOMANDA 2
Disegnare un albero, con 4 nodi, in cui il limite indicato in precedenza viene
raggiunto dal p(x) di un nodo x dell’albero.
SOLUZIONE
DOMANDA 1
1
2
4
3
5
7
10
8
11
22
23
Il valore massimo nell’albero dell’esempio è assegnato al nodo più a dx del livello
più basso.
1
3
7
15
31
Proviamo a sviluppare un albero che si sviluppa solo a destra
31 è il nodo n (n=5) −−> 2n-1
DOMANDA 2
1
3
7
15
3. Alberi binari
Per un dato albero binario T, si definisce Lunghezza dei Cammini Interni, indicata
con LCI(T), la somma delle lunghezze dei cammini che vanno dalla radice ai nodi
interni dell’albero; si definisce Lunghezza dei Cammini Esterni, indicata con
LCE(T), la somma delle lunghezze dei cammini che vanno dalla radice alle foglie
dell’albero.
1. Indicare la relazione esistente, in un albero binario T pieno e con n nodi interni, tra
LCE(T), LCI(T) ed n.
Dimostrare tale relazione (suggerimento: operare per induzione)
SOLUZIONE
1. In un albero T binario pieno LCE(T) = LCI(T) + 2n
2. Dimostrazione per induzione sul numero n dei nodi interni.
Caso Base: Un albero con la sola radice ha n=0, LCI=LCE=0.
Induzione: In un albero T pieno con k nodi interni, sia LCI(T)=h ed LCE(T)=h+2k.
Otteniamo un albero T’ pieno con k+1 nodi interni aggiungendo due figli a una delle
foglie, che supponiamo (senza perdere in generalità) stia a profondità j. Nel nuovo
albero un “cammino esterno” di lunghezza j è diventato un “cammino interno”, e ci
sono due nuovi “cammini esterni” di lunghezza j+1. Valgono allora le seguenti
relazioni.
LCI(T’) = LCI(T) + j = h + j
LCE(T’) = LCE(T) – j + 2 * (j+1) =
= h + 2*k – j + 2*j + 2 =
= h + 2*k + j + 2 =
= h + j + 2*(k + 1) =
= LCI(T’) + 2*(#nodi interni)
4. Algoritmi e complessità
Siano dati due insiemi di record:
S1 = {<k1, i1>, <k2, i2>, …. <kn, in>},
S2 = {<h1, j1>, <h2, j2>, …. <hn, jn>},
dove kr e hr denotano le chiavi dei record e ir, jr i contenuti informativi di tipo
generico.
Le chiavi sono costituite da stringhe di al più 30 caratteri alfanumerici.
Si descriva brevemente, senza necessariamente codificarlo in un preciso linguaggio di
programmazione, un algoritmo per costruire l’intersezione S di S1 e S2 e se ne valuti
l’ordine di grandezza della complessità temporale.
Si discuta brevemente se la complessità ottenuta sia ottima o se sia possibile
migliorarne l’ordine di grandezza mediante un algoritmo più sofisticato.
NB1. Per semplicità si può assumere che i due insiemi abbiano la stessa cardinalità,
oppure fare riferimento alla cardinalità del maggiore dei due.
NB2. I due insiemi non sono ordinati rispetto al valore delle loro chiavi né dei campi
informativi.
SOLUZIONE
Un algoritmo banale che calcola S è il seguente:
for x in S1
for y in S2
if key(x)=key(y) then put x in S
Che è chiaramente Θ(n2).
Però sappiamo che, se S1 e S2 sono ordinati, si può scrivere un algoritmo banale che
costruisce S, con complessità Θ(n). Sappiamo che il problema dell’ordinamento
basato su confronto di chiavi è limitato inferiormente da Ω(n log n) nel caso peggiore
(es. QuickSort è Θ(n log n) in ogni caso), dunque possiamo risolvere il problema con
un algoritmo che ordina i due insiemi e ne sfrutta dunque l’ordinamento, ottenendo
una complessità Θ(n log n).
5. Pile e code
Utilizzando i seguenti ADT per le pile e per le code
// Stack abtract class
template <class Elem> class Stack {
public:
// Reinitialize the stack
virtual void clear() = 0;
// Push an element onto the top of the stack.
virtual bool push(const Elem&) = 0;
// Remove the element at the top of the stack.
virtual bool pop(Elem&) = 0;
// Get a copy of the top element in the stack
virtual bool topValue(Elem&) const = 0;
// Return the number of elements in the stack.
virtual int length() const = 0;
};
// Abstract queue class
template <class Elem> class Queue {
public:
// Reinitialize the queue. The user is responsible for
// reclaiming the storage used by the stack elements.
virtual void clear() = 0;
// Place an element at the rear of the queue. Return
// true if successful, false if not (if queue is full).
virtual bool enqueue(const Elem&) = 0;
// Remove the element at the front of the queue. Return
// true if succesful, false if queue is empty.
// The element removed is returned in the first parameter.
virtual bool dequeue(Elem&) = 0; // Remove Elem from front
// Return in first parameter a copy of the front element.
// Return true if succesful, false if queue is empty.
virtual bool frontValue(Elem&) const = 0;
// Return the number of elements in the queue.
virtual int length() const = 0;
};
Si specifichi il codice o pseudocodice per realizzare le seguenti operazioni
1) ConfrontoPile: date due pile P1 e P2 si verifichi se contengono le stesse sequenze
2) PilaPalindrome: data una pila P si determini se la sequenza contenuta nella pila è
palindrome
3) ConfrontoCode: date due code C1 e C2 si verifichi se contengono le stesse
sequenze
4) CodaPalindrome: data una coda C si determini se la sequenza contenuta nella coda
è palindrome
SOLUZIONE
1) ConfrontoPile(P1,P2)
if(P1.length() != P2.length())
return FALSE;
while (P1.length()){
P1.pop(elem1);
P2.pop(elem2);
if (elem1 != elem2) return FALSE;
}
return TRUE;
2) PilaPalindrome(P)
Stack S;
//pila vuota
lung = P.length()
for (i=1; i<(lung/2); i++)()){
P.pop(elem);
S.push(elem);
}
if (lung%2)
P.pop(elem);
return ConfrontoPile(P,S);
3) ConfrontoCode(C1,C2)
if(C1.length() != C2.length())
return FALSE;
while (C1.length()){
C1.dequeue(elem1);
C2.dequeue(elem2);
if (elem1 != elem2) return FALSE;
}
return TRUE;
4) CodaPalindrome(C)
Stack S;
//pila vuota
lung = C.length()
for (i=1; i<(lung/2); i++)()){
C.dequeue(elem);
S.push(elem);
}
if (lung%2) C.dequeue(elem);
while (C.length()){
C.dequeue(elem1);
S.pop(elem2);
if (elem1 != elem2) return FALSE;
}
return TRUE;