Salta al contenuto
Note per Studenti Esercizio 9 · foglia più profonda di un albero binario proprio

Esercizio 9foglia più profonda di un albero binario proprio

Esame
In questa pagina 6

Testo (esempio di tema d'esame e scritto del 09/09/2025, seconda parte, esercizio 1, 5 punti). Si vuole progettare un algoritmo ricorsivo deepLeaf per trovare la foglia più profonda in un albero binario proprio TT. Detta deepLeaf(T, v) la generica invocazione su un nodo v∈Tv \in T, per risolvere il problema si eseguirà deepLeaf(T, T.root()) (che può anche restituire informazioni aggiuntive). Si ricordi che in ogni sottoalbero TvT_v la profondità (in TvT_v) della sua foglia più profonda è pari all'altezza di TvT_v.

(a) Descrivere deepLeaf(T, v) tramite pseudocodice, specificandone con attenzione l'input e l'output. (b) Analizzare la complessità di deepLeaf(T, T.root()) in funzione del numero nn di nodi in TT.


Idea

Il suggerimento del testo: l'altezza di TvT_v è la massima profondità delle sue foglie (vedi AlberiAlbero radicato (definizione per padre e ricorsiva), terminologia (antenati, discendenti, nodi interni ed esterni, sottoalbero, albero ordinato), profondità, livello, altezza; altezza = massima profondità delle foglie; algoritmi depth e height con costo; somma dei figli = n-1; esempio di algoritmo Omega(n^2) (heightBad).Alberi →). Quindi la foglia più profonda di TvT_v è, tra le foglie più profonde dei due sottoalberi figli, quella del sottoalbero più alto. Per decidere serve conoscere l'altezza dei due figli: si restituisce una coppia (foglia, altezza), come in heightSum (vedi Alberi binariAlbero binario e albero binario proprio; interfaccia; relazioni tra nodi, foglie e altezza (m = n-m+1, h+1 <= m <= 2^h, 2h+1 <= n <= 2^(h+1)-1) con dimostrazioni; visita inorder; parse tree e valutazione di espressioni; heightSum come esempio di calcolo di un'informazione più ricca.Alberi binari →): conviene calcolare un'informazione più ricca di quella richiesta. È una visita in postorder.

(a) Pseudocodice

Algoritmo deepLeaf(T, v)
Input: albero binario proprio T, nodo v di T
Output: coppia (w, h) con w = una foglia più profonda di T_v e h = altezza di T_v
if T.isExternal(v) then return (v, 0)
(wL, hL) <- deepLeaf(T, T.left(v))
(wR, hR) <- deepLeaf(T, T.right(v))
if hL > hR then return (wL, hL + 1)
else return (wR, hR + 1)

Chiamata: (w, h) <- deepLeaf(T, T.root()); ww è la foglia cercata e hh l'altezza dell'albero.

Correttezza (induzione sull'altezza). Foglia: l'unica foglia di TvT_v è vv stesso, a profondità 00 = altezza. Nodo interno: le foglie di TvT_v sono quelle di TLT_L e TRT_R con profondità aumentata di 11 rispetto ai sottoalberi; per ipotesi wLw_L e wRw_R sono le più profonde nei rispettivi sottoalberi, quindi la più profonda di TvT_v è quella con altezza maggiore, a profondità 1+max⁡(hL,hR)1 + \max(h_L, h_R) in TvT_v, che è l'altezza di vv.

(b) Complessità

L'albero della ricorsione ha esattamente un nodo per ogni nodo di TT; ogni chiamata, escluse le figlie, fa un numero costante di operazioni (un test, un confronto, una coppia restituita). Dunque t(n)∈Θ(n),t(n) \in \Theta(n), come una visita in postorder in cui la visita di un nodo costa Θ(1)\Theta(1).

Esempio

Albero: radice rr con figli xx e yy; xx ha figli (foglie) aa e bb; yy è foglia. deepLeaf(a) =(a,0)= (a, 0), deepLeaf(b) =(b,0)= (b, 0); in xx: hL=0≯hR=0h_L = 0 \not> h_R = 0, quindi si restituisce (b,1)(b, 1) (con la parità si sceglie il destro; si poteva scegliere aa, che è ugualmente profonda). deepLeaf(y) =(y,0)= (y, 0). In rr: hL=1>hR=0h_L = 1 > h_R = 0, quindi (b,2)(b, 2): la foglia più profonda è bb, a profondità 22. (Controllato su 500 alberi casuali: profondità della foglia restituita = massima profondità.)

Alternative (peggiori)

Errori comuni

  • Restituire solo la foglia: senza l'altezza il padre non può confrontare i due figli, e si finisce a ricalcolare le altezze (quadratico).
  • Restituire solo l'altezza: si risponde a un problema diverso.
  • Scrivere hL >= hR e hL > hR indifferentemente ma non indicare cosa succede alla parità: il testo accetta una qualsiasi delle foglie più profonde, va però dichiarato.

Versione ripasso

Testo. Albero binario proprio TT: algoritmo ricorsivo deepLeaf(T, v) che trova la foglia più profonda; specificare input e output; complessità in nn.

Teoria collegata