Sei sulla pagina 1di 18

Algoritmi e Strutture Dati

Lezione 9
Gli alberi binari
Oggi parleremo di …

Rappresentazione degli alberi binari


Operazioni sugli alberi binari
 visita in profondità
inorder (o in ordine simmetrico)
preorder (o in ordine anticipato)
postorder (o in ordine posticipato)
inorder iterativa
 visita in ampiezza
Altre operazioni
 creazione
 profondità
 copia
 equivalenza
Rappresentazione degli alberi binari

/ / / / / /

/ / / /

dati
figlio figlio
sinistro destro nodo
Visita in profondità di un albero

Una delle operazione più frequenti riguardanti gli alberi è


la visita dei loro nodi una e una sola volta, detta anche
attraversamento.
Per le visite in profondità consideriamo solo tre tipologie
 visita inorder (SVD)
 visita preorder (VSD)
 visita postorder (SDV)

Esiste una naturale corrispondenza tra queste visite e la


produzione dei formati infisso, prefisso e postfisso di una
espressione rappresentata da un albero binario.
Visita in profondità di un albero

Visita inorder (SVD) Un attraversamento inorder consiste


in
1. uno spostamento verso il basso e a sinistra lungo un
albero finché non viene raggiunto un nodo nullo
2. una “visita” del padre del nodo nullo
3. un attraversamento del nodo che si trova una posizione a
destra; l’attraversamento continua con l’ultimo nodo non
visitato che si trova ad un livello superiore nell’albero.
Visita in profondità di un albero
visita inorder (SVD)
+

- ^

/ * E F

A B C D

albero binario contenente un’espressione aritmetica

A / B - C * D + E ^ F
Visita in profondità di un albero

Visita preorder (VSD) Un attraversamento preorder


consiste in
1. una “visita” del nodo
2. uno spostamento a sinistra, visitando tutti i nodi
incontrati
3. l’attraversamento continua finché non si raggiunge un
nodo nullo; si torna indietro al nodo antenato più vicino
che ha un figlio destro e si prosegue la visita di questo
nodo.
Visita in profondità di un albero
visita preorder (VSD)
+

- ^

/ * E F

A B C D

albero binario contenente un’espressione aritmetica

+ - / A B * C D ^ E F
Visita in profondità di un albero

Visita postorder (SDV) Un attraversamento postorder


consiste in
1. uno spostamento a sinistra, visitando tutti i nodi
incontrati
2. uno spostamento a destra, visitando tutti i nodi
incontrati
3. una “visita” del nodo; si torna indietro al nodo antenato
più vicino che ha un figlio sinistro e si prosegue la visita
di questo nodo.
Visita in profondità di un albero
visita postorder (SDV)
+

- ^

/ * E F

A B C D

albero binario contenente un’espressione aritmetica

A B / C D * - E F ^ +
Visita in profondità di un albero

visita inorder (SVD) visita preorder (VSD)


algoritmo inorder(nodo r) algoritmo preorder(nodo r)
if (r = NULL) then return if (r = NULL) then return
inorder(figlio sinistro di r) visita il nodo r
visita il nodo r preorder(figlio sinistro di r)
inorder(figlio destro di r) preorder(figlio destro di r)

visita postorder (SDV)


algoritmo postorder(nodo r)
if (r = NULL) then return
postorder(figlio sinistro di r)
postorder(figlio destro di r)
visita il nodo r
Visita in profondità di un albero

Visita inorder iterativa algoritmo inorderIter(nodo r)


Si aggiungono e si eliminano nodi // Utilizza uno stack con accesso al top -1
dallo stack nello stesso modo in cui
l’algoritmo ricorsivo gestisce lo stack while (1) do
di sistema while (r ≠ NULL) do
Add(top, r)
 un nodo viene inserito nello stack r  figlio sinistro di r
se ad esso non è associata alcuna r  Delete(top)
azione if (r = NULL) then break
 un nodo viene eliminato dallo visita il nodo r
O(n)
r  figlio destro di r
stack se ad esso è associata
l’azione di visita.
I nodi a sinistra vengono inseriti nello algoritmo inorder(nodo r)
stack finché non viene raggiunto un if (r = NULL) then return
nodo nullo, che viene eliminato. inorder(figlio sinistro di r)
Il figlio a destra viene inserito nello visita il nodo r
stack. inorder(figlio destro di r)
Visita in ampiezza di un albero

Visita in ampiezza (o in ordine di livello)


 Si visita la radice, poi il figlio sinistro della radice, seguito dal figlio destro
della radice
 si continua visitando i nodi ad ogni nuovo livello partendo dal nodo più a
sinistra fino a quello più a destra.
1 +

2 3 - ^

4 5 6 7 / * E F

8 9 10 11 12 13 14 15 A B C D

+ - ^ / * E F A B C D
Visita in ampiezza di un albero

La visita in ampiezza
utilizza una coda
circolare algoritmo level_order(nodo r)
 si inserisce la radice // Utilizza una coda C con accesso agli estremi
nella coda // dietro  0 e davanti  0

 si cancella il nodo in if (r = NULL) then return


testa alla coda e si AddC(C, r)
visualizza il campo dato while (not isEmpty(C)) do
u  DelC(C)
 si inseriscono nella if (u ≠ NULL) then
coda i figli a sinistra e a visita il nodo u
destra del nodo visitato. AddC(C, figlio sinistro di u)
AddC(C, figlio destro di u)
Visita in ampiezza di un albero
visita in ampiezza
+

- ^
+ - ^ / * E F A B C D

/ * E F

A B C D D
B C D
F A B C D
* E F A B C D
^ / * E F A B C D
+ - ^ / * E F A B C D
Altre operazioni …
Creazione di un albero binario
algoritmo crea(nodo r)
dati di r  un valore ai dati del nodo r
if (nodo r ha un figlio sinistro) then
nodo_alloc  allocazione di un nuovo nodo
figlio sinistro di r  nodo_alloc
crea(nodo_ alloc)
else figlio sinistro di r  NULL
if (nodo r ha un figlio destro) then
nodo_alloc  allocazione di un nuovo nodo
figlio destro di r  nodo_ alloc
crea(nodo_ alloc)
else figlio destro di r  NULL

Profondità di un albero binario


algoritmo profondità(nodo r)  intero
if (r = NULL) then return 0
sin  profondità(figlio sinistro di r)
des  profondità(figlio destro di r)
return 1 + max(sin, des)
Altre operazioni …
Copia di un albero binario
algoritmo tree_copy(nodo orig)  nodo
if (orig ≠ NULL) then
temp  allocazione di un nuovo nodo
dati di temp  dati di orig
figlio sinistro di temp  tree_copy(figlio sinistro di orig)
figlio destro di temp  tree_copy(figlio destro di orig)
return temp
else return NULL

Equivalenza di due alberi binari


algoritmo tree_equiv(nodo primo, nodo secondo)  intero
return ((primo = NULL and secondo = NULL) or
(primo ≠ NULL and secondo ≠ NULL and
(dati di primo = dati di secondo) and
tree_equiv(figlio sinistro di primo, figlio sinistro di secondo) and
tree_equiv(figlio destro di primo, figlio destro di secondo)))
Riassumendo …

Operazioni sugli alberi binari


 visita in profondità
inorder, preorder, postorder
 visita in ampiezza.
Altre operazioni
 creazione, calcolo della profondità, copia, equivalenza.

La prossima volta introdurremo la struttura dati


Heap.

18

Potrebbero piacerti anche