Documenti di Didattica
Documenti di Professioni
Documenti di Cultura
GLI ALBERI
Gli Alberi 3
Definizione 1 Predecessore una relazione d'ordine parziale, cio dati due nodi
dell'albero o uno predecessore dell'altro, in quanto esiste un
Un albero un insieme finito di nodi e archi orientati. Ogni arco percorso di archi dall'uno all'altro, oppure non c' relazione.
collega il nodo padre ad un nodo figlio.
Ogni nodo ha esattamente un padre (grado di ingresso + 1) Si pu anche definire una relazione successore, inversa di
Ogni nodo ha al pi due figli (grado di uscita <= 2). predecessore.
Il nodo radice non ha padre (grado di ingresso = 0)
Il massimo numero di nodi a livello i (i 0) 2i , come si pu
Definizione Alternativa (a carattere ricorsivo) verificare per induzione:
20=1,
Albero binario un insieme finito di nodi e pu essere:
se il massimo numero di nodi a livello i 2i, poich ogni nodo al
1. insieme vuoto oppure
livello i pu avere al pi due figli, al livello i+1 il massimo
2. nodo radice + due alberi binari disgiunti, detti rispettivamente
numero di nodi 2*2i=2i+1.
sottoalbero sinistro e sottoalbero destro
Il massimo numero complessivo di nodi in un albero di
profondit k 20 + 21 + ... + 2k = 2k+1-1.
radice
albero
binario
Gli Alberi 5
Gli Alberi 7
/* IMPLEMENTAZIONE BST */
OPERAZIONE DI INSERIMENTO
/* albero binario di ricerca implem. con
puntatori */
#include "InfoBase.h"
#include "Bst.h"
#include <stdlib.h> j j
int BstStato; b l b l
Posiz BstTrova(Bst B, Atomo A);
void CancellaMin(Atomo *Min, Bst *B); f n f n
/* BstCrea */ d h d h m
void BstCrea(Bst *B){
(*B) = NULL; Inserimento della chiave m
} /* end BstCrea */
Si sfrutta il criterio di ordinamento per cercare il punto in cui
inserire un nuovo elemento con tecnica dicotomica
Il nuovo nodo sar sempre inserito come foglia, quindi con i due
sottoalberi vuoti.
Gli Alberi 11
j j
b l b l
f n
h
g n
d h
d h
g
Gli Alberi 15
CANCELLAZIONE /* BstCancella */
ALGORITMO DI CANCELLAZIONE int BstCancella(Bst *B, Atomo A) {
Posiz Temp;
Richiede: Atomo Min;
BstStato=BstOK;
l'individuazione la cancellazione del nodo con chiave minima di if ((*B)==NULL)
un sottoalbero, per mantenere la propriet di ordinamento, BstStato = BstChiaveAssente;
secondo il seguente algoritmo else
si mostra solo la cancellazione della radice di un albero; la if (Minore(A,(*B)->Dato))
cancellazione di un nodo qualunque dellalbero sar preceduta BstCancella(&(*B)->Sx,A);
else
da una fase di ricerca): if (Minore((*B)->Dato,A))
BstCancella(&(*B)->Dx,A);
- se la radice ha due sottoalberi non vuoti else{ /*B punta al nodo che contiene A */
- cancella il nodo con chiave minima e if (((*B)->Sx!=NULL) && ((*B)-
memorizzane il >Dx!=NULL))
contenuto Min { /* Ci sono entrambi i sottoalberi
- sostituisci al contenuto della radice il */
dato Min CancellaMin(&Min,&(*B)->Dx);
altrimenti (*B)->Dato=Min;
- se c soltanto il sottoalbero sinistro }
- sostituisci alla radice il suo figlio
sinistro
altrimenti
- se c soltanto il sottoalbero destro
- sostituisci alla radice il suo figlio
destro
altrimenti
- cancella la radice, poich una
foglia
Gli Alberi 17
j
j
b l
f l
f n
d h n
d h
Gli Alberi 19
#include <stdio.h>
Programma per la creazione, cancellazione e visualizzazione di un #include "InfoBase.h"
dizionario
informazione costituita da una chiave, in base alla quale si
eseguono ricerche e ordinamenti #define Terminatore "."
e da una stringa associata.
Gli Alberi 23
ESEMPIO DI UTILIZZO
/* infobase.c -- Continua */ Infine, il seguente programma un esempio di utilizzo delle
boolean Minore(Atomo A,Atomo B){ librerie sopra illustrate:
return (strcmp(A.chiave,B.chiave)<0);
/* strcmp presa da #include <stdio.h>
string.h */ #include <stdlib.h>
}
#include "InfoBase.h"
#include "Bst.h"
boolean AtomoNullo(Atomo A){
return !strcmp(A.chiave,Terminatore); int main(void){
} Atomo A;
Bst B;
boolean Uguale(Atomo A,Atomo B){ BstCrea(&B);
return !strcmp(A.chiave,B.chiave); printf("Ciclo di inserimento\n");
} do { /* ripeti finche atomo non nullo */
Acquisisci(&A);
if (!AtomoNullo(A)){
if(BstInserisci(&B,A)) /*lunico err.
possibile
e quello di chiave gia
esistente */
printf("Chiave esistente\n");
} } while (!AtomoNullo(A));
Gli Alberi 25
VisitaOrdinata(B);
printf("Ciclo di ricerca\n"); Complessit delle operazioni su alberi
do { /* ripeti finche atomo non nullo */ Tutte le operazioni su alberi, ad eccezione della creazione, vengono
AcquisisciChiave(&A);
if (!AtomoNullo(A)){ eseguite in tempo O(h), dove h la profondit dell'albero.
if(BstRecupera(B,&A)){/* lunico err.
possibile e quello di chiave assente */
printf("Chiave inesistente\n"); Prova intuitiva: le procedure viste
} non contengono cicli,
else{
Visualizza(A); sono ricorsive ed eseguono sempre una singola navigazione verso
} il basso,
} terminano quando viene incontrata una foglia.
} while (!AtomoNullo(A));
Per effetto del secondo e del terzo punto
printf("Ciclo di cancellazione\n");
do { /* ripeti finche atomo non nullo */ il numero di attivazioni di procedura sempre uguale alla
AcquisisciChiave(&A); profondit di una foglia
if (!AtomoNullo(A)){ lassenza di cicli interni alle procedure rende la complessit di
if(BstCancella(&B,A)){/* lunico err. caso peggiore delle singole chiamate costante rispetto alle
possibile dimensioni del problema. N
e quello di chiave assente */
printf("Chiave inesistente\n");
}
else VisitaOrdinata(B); /* in caso di
successo mostra lalbero dopo la cancell. */
}
} while (!AtomoNullo(A));
printf("Fine Lavoro");
return 0;
}
Gli Alberi 27
Albero bilanciato
Complessit delle operazioni su alberi: Visioni Alternative
Per garantire che le operazioni abbiano una complessit logaritmica
esistono due possibilit:
Sarebbe pi interessante esprimere la complessit delle operazioni fidarsi di un comportamento casuale che genera un albero di
in funzione di una dimensione pi significativa, quale il numero di profondit quasi minima,
nodi n dellalbero, ma il legame fra n e h non noto a priori, poich: intraprendere azioni correttive durante la costruzione dell'albero in
caso di sbilanciamento.
la forma dell'albero dipende dall'ordine degli inserimenti, come
mostrato in figura
Un albero bilanciato se:
j ad ogni nodo la differenza fra le profondit dei suoi due
Albero generato dalla sequenza
sottoalberi al pi 1.
j,d,b,g,n,l,q; b
d l
n
La profondit di un albero bilanciato sempre O(log n).
b h
g l n
q
quali altre sequenze lo generano?
Un albero bilanciato pu essere ottenuto per ridefinizione delle
bj
operazioni su BST: in questo caso si parla di AVL-tree (dai nomi degli
l
d inventori Adel'son-Velskii e Landis, 1962).
Albero generato dalla sequenza g
n gli algoritmi di inserimento e cancellazione sono estesi con
b,d,g,j,l,n,q; operazioni di soccorso, chiamate per ristabilire il bilanciamento in
nj
caso di necessit.
nl
quali altre sequenze generano un le operazioni di soccorso si basano sul concetto di rotazione di
albero di profondit massima? n una porzione di albero, come mostrato in figura
q
n la struttura di un nodo deve venire estesa per contenere l'altezza
del sottoalbero di cui il nodo radice.
In particolare, il massimo valore di h n-1, 10
j 14
l
nel caso peggiore la complessit diventa lineare.
Viceversa b
4 14
l
10 17
n
h minima se tutti i percorsi dalla radice alle foglie hanno
12 17
n
lunghezza h-1 o h. b
4 12
h
22
h
22
Supponendo che tutti i percorsi siano uguali di lunghezza h, vale la
relazione n = 2h+1-1, quindi se h minima h O(log n), e quindi
le operazioni hanno complessit O(log n).
Gli Alberi 29
GLI ALBERI