Menu
Coddy logo textTech

Albero binario

Ultimo aggiornamento

Un albero binario è una gerarchia in cui ogni nodo ha al massimo due figli, chiamati figlio sinistro e figlio destro. Il nodo in cima è la radice, i nodi senza figli sono le foglie e il numero di archi dalla radice alla foglia più profonda è l'altezza dell'albero. A differenza di un albero binario di ricerca, un albero binario semplice non ha regole di ordine: è solo la forma. Premi play qui sopra per vedere un albero riempirsi livello per livello e poi essere visitato in ordine (sinistra, nodo, destra).

Gli alberi binari sono alla base di molte strutture: alberi binari di ricerca, heap, alberi delle espressioni e altro. Le visite passano per ogni nodo in un ordine definito: in ordine, in pre-ordine e in post-ordine sono le tre visite in profondità, ognuna utile per compiti diversi.

Terminologia

TermineSignificato
RadiceIl nodo in cima, senza genitore
FogliaUn nodo senza figli
AltezzaIl percorso più lungo dalla radice a una foglia (in archi)
ProfonditàDistanza di un nodo dalla radice
CompletoTutti i livelli pieni tranne forse l'ultimo, riempito da sinistra a destra

Le tre visite in profondità

VisitaOrdineUso comune
In ordineSinistra, nodo, destraOutput ordinato di un BST
Pre-ordineNodo, sinistra, destraCopiare / serializzare un albero
Post-ordineSinistra, destra, nodoEliminare / valutare un albero

Esempio svolto

Visita in ordine dell'albero costruito da [4, 2, 6, 1, 3, 5] (riempito livello per livello):

PassoNel nodoAzione
14Scendi ricorsivamente nel sottoalbero sinistro di 4 prima di visitarlo
22Scendi ricorsivamente nel sottoalbero sinistro di 2 prima di visitarlo
31Foglia, nessun figlio sinistro: visita 1, output [1]
42Sinistra completata: visita 2, output [1, 2], poi scendi a destra
53Foglia: visita 3, output [1, 2, 3]
64Sottoalbero sinistro completato: visita 4, output [1, 2, 3, 4], poi scendi a destra
75Figlio sinistro di 6, una foglia: visita 5, output [1, 2, 3, 4, 5]
86Sinistra completata, nessun figlio destro: visita 6, output [1, 2, 3, 4, 5, 6]

Quando usare un albero binario

Usalo quandoEvitalo quando
Devi modellare dati intrinsecamente gerarchici (file system, alberi delle espressioni, DOM)I dati sono piatti e basterebbe una lista o un array: un albero aggiunge solo overhead
Vuoi operazioni ordinate e puoi mantenerlo bilanciato (un BST o un albero autobilanciato)Ti serve una ricerca per chiave O(1) in media: una tabella hash batte qualsiasi albero
Ti serve elaborare dati strutturati in ordine, in pre-ordine o in post-ordineI nodi vengono inseriti in ordine in un BST non bilanciato: degrada a una lista O(n)
Contano le query su intervalli o l'iterazione ordinata, che le tabelle hash non offronoLa memoria è poca: ogni nodo porta due puntatori ai figli oltre al dato

Codice Binary Tree

Un'implementazione di Binary Tree pulita ed eseguibile in Python, JavaScript, Java, C++, C. Scegli un linguaggio, copia il codice o aprilo già caricato nel Playground di Coddy.

Codice Binary Tree in Python

Python
1from collections import deque2
3
4class Node:5    def __init__(self, value):6        self.value = value7        self.left = None8        self.right = None9
10
11def insert(root, value):12    # Level-order insert: fill the first empty child slot found13    if root is None:14        return Node(value)15    queue = deque([root])16    while queue:17        node = queue.popleft()18        if node.left is None:19            node.left = Node(value)20            return root21        queue.append(node.left)22        if node.right is None:23            node.right = Node(value)24            return root25        queue.append(node.right)26
27
28def inorder(node):29    if node is None:30        return []31    return inorder(node.left) + [node.value] + inorder(node.right)32
33
34root = None35for value in [1, 2, 3, 4, 5, 6, 7]:36    root = insert(root, value)37
38print("Root:   ", root.value)39print("Inorder:", inorder(root))
Esegui questo codice nel playground Python

Domande frequenti sull'albero binario

Qual è la differenza tra un albero binario e un albero binario di ricerca?
Un albero binario limita semplicemente ogni nodo ad avere al massimo due figli, senza ordine. Un albero binario di ricerca aggiunge la regola per cui tutto ciò che sta nel sottoalbero sinistro è più piccolo e tutto ciò che sta nel sottoalbero destro è più grande, ed è questo che rende veloce la ricerca.
Cos'è una visita in ordine?
La visita in ordine visita il sottoalbero sinistro, poi il nodo, poi il sottoalbero destro, in modo ricorsivo. Per un albero binario di ricerca produce i valori in ordine crescente, ed è per questo che è la visita più usata negli esempi.
Cos'è un albero binario completo?
Un albero binario completo ha tutti i livelli pieni tranne forse l'ultimo, che viene riempito da sinistra a destra. Questa forma permette di memorizzare l'albero in modo compatto in un array (senza puntatori ai figli), ed è così che si implementano gli heap binari.
Quando conviene usare un albero binario invece di un array o di una tabella hash?
Scegli un albero quando i tuoi dati sono naturalmente gerarchici o quando ti servono operazioni ordinate come query su intervalli e iterazione ordinata, che le tabelle hash non ti danno. Se ti serve solo una ricerca veloce per chiave senza ordine, l'accesso O(1) in media di una tabella hash batte un albero, e per dati piatti un array è più semplice e sfrutta meglio la cache.
Qual è la differenza tra altezza e profondità di un albero binario?
La profondità si misura dalla radice verso un nodo specifico: è il numero di archi sul percorso dalla radice a quel nodo. L'altezza si misura da un nodo verso la sua foglia più profonda, quindi l'altezza dell'intero albero è la profondità del suo nodo più profondo. Un albero con un solo nodo ha altezza 0 e il suo unico nodo ha anche profondità 0.
Perché un albero binario non bilanciato ha prestazioni così scarse?
Ricerca, inserimento ed eliminazione in un albero binario di ricerca costano O(h), dove h è l'altezza. Quando le chiavi vengono inserite in ordine, l'albero diventa una linea retta, quindi h cresce fino a n e ogni operazione degrada a O(n), non meglio di una lista concatenata. Gli alberi autobilanciati come gli AVL o i rosso-neri mantengono l'altezza a O(log n) per evitarlo.
Illustrazione dei linguaggi di programmazione di Coddy

Padroneggia gli algoritmi con Coddy

INIZIA