Alberi binari

annuncio pubblicitario
Alberi binari
Gli alberi binari rappresentano una delle strutture dati dinamiche più importanti dell'informatica.
Un albero binario consiste di componenti ripetuti (nodi) arrangiati secondo una struttura ad albero
(invertito). L'elemento in cima all'albero è chiamato radice (root). Gli elementi situati
immediatamente al di sotto di un nodo ne sono chiamati figli (children), di rimando, l'elemento
situato direttamente al di sopra di un altro nodo ne è detto il genitore (parent). Infine, un elemento
privo di figli è chiamato foglia (leaf) dell'albero.
In generale, un albero binario rappresenta una struttura dati contenente una sequenza di elementi
registrati secondo l'ordine di inserimento ma riordinati secondo un assegnato criterio di
ordinamento. Tale ordinamento viene espresso a mezzo di una coppia di puntatori detti puntatore
sinistro e puntatore destro (o anche puntatore precedente e puntatore successivo). L'elemento
puntato dal puntatore sinistro precede, secondo la relazione di ordinamento applicata, l'elemento in
esame, viceversa l'elemento puntato dal puntatore destro segue l'elemento in esame. Se ne deduce
che un nodo debba rappresentare una struttura composta dal dato (o dai dati) da gestire e da una
coppia di puntatori a oggetti dello stesso tipo. In un albero binario così definito, ciascun elemento è
maggiore (inteso sempre secondo il criterio di ordinamento prescelto) di tutti gli elementi
appartenenti al sotto-albero ''inferiore'' (o ''sinistro'') e minore di quelli appartenenti al sotto-albero
''superiore'' (o ''destro''). Da tali proprietà discendono in modo naturale gli algoritmi di ricerca,
inserimento e prelievo degli elementi dell'albero. Ciò rende particolarmente efficiente le operazioni
di ricerca attraverso le visite dell'albero e le operazioni di ordinamento.
Naturalmente su una struttura ad albero sarà possibile definire procedure elementari di
inizializzazione dell'albero, inserimento di un nodo, estrazione di un nodo, stampa dell'elenco
completo. Inoltre sarà necessario prevedere la definizione di predicati logici atti a verificare se
l'albero è vuoto (ossia da se è da inizializzare) e se un dato elemento è o meno presente nell'albero.

Quando viene letto il primo valore viene allocata una variabile (il root node) atta ad
ospitarlo e i due puntatori componenti vengono annullati.

Quando viene letto il valore successivo, viene creato un nuovo nodo per poterlo ospitare.

Se il nuovo valore risulta minore del valore del nodo radice, il puntatore sinistro di root è
indirizzato a questo nuovo nodo.

Se, invece, il nuovo valore risulta maggiore del valore del nodo radice, è il puntatore destro
di root ad essere indirizzato a questo nuovo nodo.

Letto un nuovo valore ed allocato memoria per esso, se esso risulta maggiore del valore di
root ma il puntatore destro è già associato, allora esso viene confrontato con il valore
puntato da destro ed il nuovo nodo viene inserito nella posizione appropriata al di sotto di
quel nodo.

Se, invece, il nuovo valore risulta minore del valore di root ma il puntatore sinistro è già
associato, allora esso viene confrontato con il valore puntato da sinistro ed il nuovo nodo
viene inserito nella posizione appropriata al di sopra di quel nodo.
Un albero binario consente, dunque, di ordinare i dati all'interno di una struttura indipendentemente
dall'ordine in cui vengono inseriti e senza operare alcuna permutazione degli elementi inseriti. Il
vantaggio di usare una struttura ad albero cresce enormemente al crescere del numero di elementi.
Infatti un albero perfettamente bilanciato consente di eseguire le operazioni di ricerca con un
numero di visite pari a log2 n essendo n il numero di elementi dell'albero. Si supponga, ad esempio,
di dover inserire all'interno di un database 65535 valori. Nel caso in cui si debba ricercare un valore
all'interno di questo elenco, utilizzando una lista concatenata il numero medio di valori da
processare sarebbe pari a 65535/2=32768. Inserendo, invece, tali valori all'interno di una struttura
ad albero, tutti i valori possono essere agevolmente inseriti in appena 16 ''livelli'' così che il numero
massimo di valori da processare prima di trovare il valore desiderato è appena 16. Questo semplice
esempio fa comprendere l'enorme efficienza associata alle procedure di gestione dati attraverso
strutture binarie. Per tale ragione molti database sono strutturati come alberi binari.
E' da precisare, tuttavia, che non sempre una struttura ad albero è così efficiente. Poiché, infatti,
l'inserimento dei nodi nell'albero dipende dall'ordine in cui i dati vengono letti può accadere che una
parte di albero appaia molto più ''nutrita'' di un altra e l'albero sia fortemente sbilanciato, ciò
aumentando il numero di livelli da processare nella visita all'albero durante le operazioni di ricerca.
In particolare la struttura può degenerare in una lista lineare qualora gli elementi vengano inseriti
proprio secondo l'ordinamento prescelto. In quest'ultimo caso si perderà del tutto il vantaggio di
lavorare con una struttura binaria.
Scarica