Alberi
In questa pagina 6
Un albero è una collezione di nodi con struttura gerarchica padre-figlio, con i collegamenti strettamente necessari a tenerli connessi (una lista è il caso estremo). Applicazioni: dizionari e code con priorità (vedi HeapAlbero binario completo e sua altezza floor(log2 n); heap = albero completo con heap-order property; proprietà (radice minima, cammini non decrescenti); rappresentazione su array con level numbering; insert con up-heap bubbling, removeMin con down-heap bubbling, rimozione di una entry qualsiasi; invarianti e costi Theta(log n); esempio svolto.Heap →, Alberi binari di ricercaAlbero binario di ricerca come albero binario proprio con entry nei nodi interni e foglie vuote; inorder crescente; TreeSearch; get, put e remove (due casi, con predecessore inorder) in Theta(h); altezza fino a n-1; esempi di inserimenti; alberi aumentati con campi size e max e algoritmi di conteggio e interrogazione in O(h).Alberi binari di ricerca →), file system, albero della ricorsione (vedi Algoritmi ricorsiviAlgoritmi ricorsivi come induzione eseguita; albero della ricorsione e record di attivazione nello stack; esempi ReverseArray, LinearSum, Power in tempo logaritmico, Fibonacci ricorsivo (esponenziale) e con memoizzazione; analisi della complessità con l'albero della ricorsione e correttezza per induzione.Algoritmi ricorsivi →), alberi di decisione, codici di Huffman, alberi filogenetici.
Definizione
Un albero radicato è una collezione di nodi che, se non vuota, soddisfa:
- esiste un nodo speciale , la radice;
- ogni ha un unico padre ( è figlio di );
- risalendo di padre in padre da ogni nodo si arriva a .
Definizione ricorsiva: con , dove sono alberi non vuoti le cui radici sono figlie di .
Terminologia
| Termine | Significato |
|---|---|
| antenato di | oppure antenato del padre di |
| discendente di | tale che è antenato di |
| nodo interno | nodo con almeno un figlio |
| nodo esterno o foglia | nodo senza figli |
| sottoalbero | con tutti i suoi discendenti |
| albero ordinato | per ogni nodo interno è fissato un ordine lineare tra i figli |
Dato un albero ordinato, due nodi allo stesso livello: è a sinistra di se precede nella visita in preorder (vedi Visite di alberiVisite in preorder e postorder come schemi generali (template) da adattare; complessità Theta(n + somma dei costi di visita) perché la somma dei figli è n-1; esempi (indice di un libro, spazio occupato in un file system); profondità con il preorder, altezza con il postorder; antenato comune più basso.Visite di alberi →).
Profondità, livello, altezza
- Profondità = numero di antenati di meno 1; ricorsivamente: , altrimenti .
- Livello = insieme dei nodi a profondità .
- Altezza di un nodo: se è foglia, altrimenti . Altezza dell'albero: .
Proposizione. Se non è vuoto, .
Dimostrazione (induzione sull'altezza). Se è la sola radice, l'altezza è e l'unica foglia è , di profondità . Altrimenti : ogni foglia di sta in un e ha profondità in pari a più la profondità in . Per ipotesi induttiva la massima profondità delle foglie di è , quindi la massima profondità delle foglie di è .
Interfaccia e implementazione
Metodi tipici: root(), parent(v), children(v), isRoot(v), isInternal(v), isExternal(v), size(). L'implementazione a struttura collegata dà a ogni nodo un riferimento al padre e alla collezione dei figli; spazio e children(v) in tempo proporzionale al numero di figli.
Algoritmi su profondità e altezza
Profondità (ricorsivo, risalendo):
Algoritmo depth(T, v)
Input: nodo v di T Output: profondità di v
if T.isRoot(v) then return 0
else return 1 + depth(T, T.parent(v))Costo , al caso pessimo (albero ridotto a un cammino). Versione iterativa: si sale con un ciclo contando i passi.
Altezza di un nodo (dal basso, usando le altezze dei figli):
Algoritmo height(T, v)
Input: nodo v di T Output: altezza di v
h <- 0
foreach w in T.children(v) do h <- max(h, 1 + height(T, w))
return hCosto: è chiamato una volta per nodo; la chiamata su costa con numero di figli. Poiché in un albero con nodi (ogni nodo non radice ha un solo padre), il totale è . È una visita in postorder (vedi Visite di alberiVisite in preorder e postorder come schemi generali (template) da adattare; complessità Theta(n + somma dei costi di visita) perché la somma dei figli è n-1; esempi (indice di un libro, spazio occupato in un file system); profondità con il preorder, altezza con il postorder; antenato comune più basso.Visite di alberi →).
Una strategia lenta (). Calcolare l'altezza come massima depth tra le foglie, invocando depth da ciascuna foglia, è corretto per la proposizione ma costa . Istanza cattiva: un cammino di nodi con foglie attaccate al nodo più basso; ognuna delle foglie ha profondità , e ogni chiamata a depth costa almeno questo: operazioni.
Errori comuni
- Confondere profondità e altezza di un nodo: la prima si conta dalla radice in giù, la seconda dalla foglia più lontana in su. In una foglia l'altezza è , la profondità no.
- Dire che l'altezza dell'albero è il numero di nodi o di livelli: è il numero di archi del cammino più lungo (un albero con la sola radice ha altezza ).
- Stimare
heightcome : il costo totale è perché .
Versione ripasso
- Albero radicato: radice ; ogni ha un unico padre; da ogni nodo si risale a . Ricorsivo: .
- Termini: antenato ( o antenato del padre), discendente, nodo interno ( figlio), foglia (nessun figlio), sottoalbero , albero ordinato (figli ordinati).
- depth, ; livello = nodi a profondità ; height(foglia) , .
- Proposizione: .
- Algoritmi:
depthricorsivo ;heightin postorder perché (costo );heightBad(depthda ogni foglia) : cammino di nodi con foglie in fondo. - Implementazione: struttura collegata (riferimento al padre e ai figli), spazio ; metodi
root,parent,children,isRoot,isInternal,isExternal,size. - Algoritmi:
depth(T,v): radice , altrimenti ;height(T,v): , per ogni figlio : . - Errori: profondità vs altezza; altezza = numero di archi (radice sola ); costo di
heightnon . Vedi Visite di alberiVisite in preorder e postorder come schemi generali (template) da adattare; complessità Theta(n + somma dei costi di visita) perché la somma dei figli è n-1; esempi (indice di un libro, spazio occupato in un file system); profondità con il preorder, altezza con il postorder; antenato comune più basso.Visite di alberi →.