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 → e RicorsioneFunzioni che chiamano se stesse: caso base e passo ricorsivo, stack delle chiamate, esempi su numeri, stringhe e liste, ricorsione multipla e suo costo, divide et impera, confronto con l'iterazione.Ricorsione →), alberi di decisione, codici di Huffman, alberi filogenetici.
Definizione
Definizione (albero radicato). 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 .
Esempio. Un albero con radice , figli e e un nodo figlio di ha nodi; le foglie sono e .
La definizione ricorsiva è la stessa idea della ricorsione sui dati: un albero è una radice più alberi più piccoli, e per questo quasi tutte le dimostrazioni sugli alberi usano l'induzione (Principio di induzionePer dimostrare una proprietà per ogni n basta il passo base e il passo induttivo da n a n+1.Principio di induzione →, Dimostrazioni, induzione e invariantiTecniche di dimostrazione (esempio, controesempio, assurdo), induzione con casi base multipli, invarianti di ciclo (inizializzazione, conservazione, uso alla fine), schema generale per provare la correttezza; esempi svolti su arrayMax, sequenza di bit e numeri di Fibonacci.Dimostrazioni, induzione e invarianti →) e quasi tutti gli algoritmi sono ricorsivi. Un albero è anche un caso particolare di grafo connesso e senza cicli (vedi Grafi - definizioni e proprietàGrafo G=(V,E) diretto e non diretto, grafo semplice e pesato; incidenza, adiacenza, grado; cammini, cicli, sottografi, grafi connessi e componenti connesse; alberi liberi, foreste, spanning tree e spanning forest; proprietà con dimostrazioni (somma dei gradi = 2m, m <= n(n-1)/2, alberi m = n-1, connessi m >= n-1, foreste m <= n-1).Grafi - definizioni e proprietà →); la lista concatenata (Liste concatenateLista concatenata semplice: nodi allocati dinamicamente collegati da puntatori; inserimento e rimozione in testa, scorrimento, ricerca, inserimento ordinato, deallocazione; confronto dei costi con l'array; versione in Python.Liste concatenate →) è l'albero in cui ogni nodo ha al più un figlio.
Albero di riferimento per gli esempi di questa pagina e di 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 →: radice con figli ; ha figli ; ha figlio . Ha nodi, foglie .
Terminologia
Definizione (terminologia degli alberi)
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
Esempio. Nello stesso albero è antenato di , il sottoalbero è , è un nodo interno e , sono foglie.
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
Definizione (profondità, livello e 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: .
Esempio. Nello stesso albero , e .
Sull'albero di riferimento (; figli di ; figli di ; figlio di ):
| nodo | ||||||
|---|---|---|---|---|---|---|
| padre | — | |||||
| profondità | 0 | 1 | 1 | 2 | 2 | 3 |
| altezza | 3 | 2 | 0 | 0 | 1 | 0 |
| figli | 2 | 2 | 0 | 0 | 1 | 0 |
La profondità si ottiene salendo (quanti archi fino alla radice), l'altezza scendendo (quanti archi fino alla foglia più lontana): , , . Livelli: livello , , , . La somma dei figli è .
Proposizione (altezza e profondità delle foglie). Se non è vuoto, .
Esempio. Le foglie e hanno profondità e , quindi . Sull'albero di riferimento le foglie hanno profondità e .
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 →). L'uguaglianza si vede contando gli archi in due modi: ogni arco collega un padre a un figlio, quindi il numero di archi è ; ma ogni nodo tranne la radice ha esattamente un padre, cioè esattamente un arco che lo collega verso l'alto, quindi gli archi sono . Sull'albero di riferimento: chiamate-passi.
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 (per : foglie a profondità , quindi passi contro i di height). Il grafico confronta le due crescite: la prima è quadratica (si veda Notazione asintoticaDefinizioni di O, Omega, Theta e o piccolo con le costanti c ed n0; esempi con costanti esplicite; proprietà (polinomi, esponenziali, logaritmi, somme, implicazioni tra notazioni); sommatorie notevoli; terminologia (logaritmica, lineare, polinomiale, esponenziale).Notazione asintotica →), la seconda lineare.
Grafico interattivo: Costo di heightBad sull'istanza cattiva (almeno n²/4 passi) contro height (2n − 1 passi): a n = 40 sono 400 contro 79, e il rapporto cresce con n
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; risalendo da ogni nodo si arriva a . Definizione ricorsiva: , con .
- Terminologia: antenato di ( oppure antenato del padre di ); discendente; nodo interno (almeno un figlio); foglia (nessun figlio); sottoalbero ; albero ordinato (ordine fisso tra i figli).
- Profondità: , . Livello : nodi a profondità .
- Altezza: se è foglia, altrimenti . Altezza dell'albero: , cioè il numero di archi del cammino più lungo.
- Proposizione: , per induzione sull'altezza.
- Somma dei figli: , perché ogni nodo non radice ha un solo padre.
- Interfaccia:
root,parent,children,isRoot,isInternal,isExternal,size. Struttura collegata: spazio . - Algoritmi (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 →):
depth(T,v): radice , altrimenti ; costo , al caso pessimo ;height(T,v): , per ogni figlio : ; postorder con costo ;heightBad(depthchiamato da ogni foglia): sul cammino di nodi con foglie in fondo; per almeno passi contro .
- Albero di riferimento: radice con figli ; ha figli ; ha figlio . Ha nodi, foglie , altezza ; profondità .
- Somma dei figli sull'albero di riferimento: . Costo di
heightsullo stesso albero: . - Errori tipici: profondità (dalla radice in giù) contro altezza (dalla foglia in su); altezza uguale al numero di nodi o di livelli (è il numero di archi, radice sola ); stimare
heightcome .
Esercizi su questo argomento
- Esercizio - Traduzione da ER a relazionale - dodici casi (esercizi di traduzione del corso)
- Esercizio 6 · preorder e postorder compatibili
- Esercizio 9 · foglia più profonda di un albero binario proprio
- Esercizio 10 · albero binario bilanciato
- Esercizio 11 · massimo beneficio lungo un cammino radice-foglia