Alberi binari
Un albero binario è un albero in cui ogni nodo ha zero, uno o due figli, i quali vengono identificati come figlio sinistro e figlio destro. I figli sono definiti dalla struttura dell’albero e non possono essere scambiati.

Albero completo Un albero binario è completo se ogni nodo ha zero o due figli, ovvero non esiste nessun nodo con un figlio.
Albero bilanciato Un albero binario è perfettamente bilanciato se le foglie sono tutte allo stesso livello.
title: Proposizione
Un albero binario completo e perfettamente bilanciato di altezza $h \ge 0$ ha esattamente $n=2^{h+1} - 1$ nodi di cui $2^h$ foglie.La dimostrazione si fa per induzione. Caso base: un albero di altezza 0 ha e un solo nodo, quindi , che è anche il numero di foglie. Ipotesi induttiva: Un albero di altezza ha foglie. Passo induttivo: L’albero di altezza contiene un albero di altezza , e quindi le sue foglie sono i nodi del penultimo livello dell’albero. Ogni nodo del penultimo livello ha esattamente due figli, che sono le foglie dell’albero. Il numero di figlie è quindi .
Per ogni , il numero di nodi al livello è uguale al numero di foglie di un albero binario completo perfettamente bilanciato di altezza . Il numero totale di nodi è quindi
title: Corollario
Un albero binario completo e perfettamente bilanciato di $n$ nodi ha altezza $h=\log(n+1) - 1 \in \Theta(\log n)$.Il nodo dell’albero binario è composto da un valore, il puntatore al figlio di sinistra e il puntatore al figlio di destra.

Esiste anche una variante con l’aggiunta di un puntatore al nodo padre.

Visita alberi
Esistono due tipi di visita di un albero binario:
- Visita in profondità (DFS, Depth First Search)
- Visita in ampiezza (BFS, Breadth First Search)
Il costo computazionale delle visite è , dove è il costo della visita del nodo.
Visita in profondità - DFS
Si visitano ricorsivamente i sottoalberi, ed esistono tre varianti:
- pre-order: il nodo viene visitato prima di visitare i sottoalberi dei figli
- in-order: il nodo viene visitato dopo aver visitato il sottoalbero del figlio di sinistra ma prima di visitare il sottoalbero del figlio di destra
- post-order: il nodo viene visitato dopo aver visitato i sottoalberi dei figli
Per questo algoritmo si utilizza la ricorsione, quindi implicitamente uno stack come struttura dati.
DFS_pre_order(L):
if L != nil then
print(L.val)
DFS_pre_order(L.left)
DFS_pre_order(L.right)
DFS_in_order(L):
if L != nil then
DFS_pre_order(L.left)
print(L.val)
DFS_pre_order(L.right)
DFS_in_order(L):
if L != nil then
DFS_pre_order(L.left)
DFS_pre_order(L.right)
print(L.val)
Visita in ampiezza - BFS
Si visita un livello dopo l’altro, partendo dalla radice. In questo caso si utilizza una coda esplicitamente.
BFS(L):
if L != nil then
q := new_queue()
enqueue(q, L)
while !is_empty_queue(q) do
n := dequeue(q)
print(n.val)
if n.left != nil then
enqueue(q, n.left)
if n.right != nil then
enqueue(q, n.right)