Laboratorio di Algoritmi e Strutture Dati Ingegneria e Scienze

Strutture dati: Alberi
Laboratorio di Algoritmi e Strutture Dati
Ingegneria e Scienze Informatiche - Cesena
A.A. 2014-2015
Pietro Di Lena
[email protected]
Pietro Di Lena
Laboratorio di Algoritmi e Strutture Dati
Strutture dati: Alberi
Definizione
Operazioni basilari su Alberi
Stampa di una struttura Albero in ASCII
Definizione
Definizione di Albero: struttura rappresentata come un grafo completamente connesso in
cui ogni coppia di nodi è connessa da un unico percorso.
Alcuni esempi di applicazione:
Teoria dei giochi: rappresentazione di tutte le possibili partite (o di un sottoinsieme) di
un gioco
Genalogia: alberi genealogici
Biologia: alberi filogenetici (ex. tree of life)
Pietro Di Lena
Laboratorio di Algoritmi e Strutture Dati
Strutture dati: Alberi
Definizione
Operazioni basilari su Alberi
Stampa di una struttura Albero in ASCII
Struttura dati Albero: rappresentazione grafica
A
\
\
A
2
1
3
B
C
B
2
D
C
3
D
1
\
E
1
\
F
2
G
2
\
\
\
\
\
1
2
E
F
2
G
Pietro Di Lena
Laboratorio di Algoritmi e Strutture Dati
Strutture dati: Alberi
Definizione
Operazioni basilari su Alberi
Stampa di una struttura Albero in ASCII
Nota: definizione della struttura dati nodo per un albero in c
# include < stdlib .h >
typedef
char
int
struct
struct
} NODE ;
struct NODE {
name ;
label ;
NODE * brother ;
NODE * children ;
NODE * node_alloc ( char name , int label ) {
NODE * node = ( NODE *) malloc ( sizeof ( NODE ) ) ;
if ( node == NULL ) return NULL ;
node - > name
node - > label
node - > brother
node - > children
return node ;
=
=
=
=
name ;
label ;
NULL ;
NULL ;
}
Pietro Di Lena
Laboratorio di Algoritmi e Strutture Dati
Strutture dati: Alberi
Definizione
Operazioni basilari su Alberi
Stampa di una struttura Albero in ASCII
Nota: generazione di un albero random
# define BASE 65
/*
* Generazione random di un albero random di altezza massima
* height . Ogni nodo ha un numero di figli compreso tra 0 e
* children . I nodi sono marcati con lettere maiuscole A - Z
* ( i nomi sono ripetuti se ci sono p i
di 26 nodi ) .
* I pesi degli archi sono interi random tra 0 e 9.
*/
NODE * randtree ( int height , int children ) {
static int X =0;
if ( height >0) {
int i , n ;
NODE *T , * tmp ;
T = node_alloc ( BASE +X , rand () %10) ;
X =( X +1) %26;
n = rand () %( children +1) ;
for ( i =0; i < n ; i ++)
if (( tmp = randtree ( height -1 , children ) ) != NULL ) {
tmp - > brother =T - > children ;
T - > children = tmp ;
}
return T ;
} else return NULL ;
}
Pietro Di Lena
Laboratorio di Algoritmi e Strutture Dati
Strutture dati: Alberi
Definizione
Operazioni basilari su Alberi
Stampa di una struttura Albero in ASCII
Operazioni basilari su Alberi: altezza e distruzione di un Albero
1: function Height(T )
2:
if T = NULL then
3:
return 0
4:
else
5:
n←0
6:
for c ∈ Children(T ) do
7:
n ← Max(n, Heigth(c))
8:
end for
9:
return n + 1
10:
end if
11: end function
1: function DeleteTree(T )
2:
if T =
6 NULL then
3:
for c ∈ Children(T ) do
4:
DeleteTree(c)
5:
end for
6:
Delete(T)
7:
end if
8: end function
ATTENZIONE: Le istruzioni di visita dei figli di un nodo dipendono dalla struttura utilizzata.
L’implementazione in C potrebbe essere un po’ differente da quella presentata nello
pseudocodice. In particolare, se si decide di utilizzare la struttura NODE suggerita, i cicli for
non sono necessari (tutto può essere calcolato in modo ricorsivo).
Qual è il costo computazionale di queste funzioni?
Pietro Di Lena
Laboratorio di Algoritmi e Strutture Dati
Strutture dati: Alberi
Definizione
Operazioni basilari su Alberi
Stampa di una struttura Albero in ASCII
Operazioni basilari su Alberi: numero di nodi e numero di foglie
1: function CountNodes(T )
2:
if T = NULL then
3:
return 0
4:
else
5:
n←0
6:
for c ∈ Children(T ) do
7:
n ← n + CountNodes(c)
8:
end for
9:
return n + 1
10:
end if
11: end function
1: function CountLeaves(T )
2:
if T = NULL then
3:
return 0
4:
else
5:
n←0
6:
if Children(T ) = ∅ then
7:
n←1
8:
else
9:
for c ∈ Children(T ) do
10:
n ← n + CountLeaves(c)
11:
end for
12:
end if
13:
return n
14:
end if
15: end function
Valgono le stesse considerazioni fatte in precedenza per la visita dei figli.
Qual è il costo computazionale di queste funzioni?
Pietro Di Lena
Laboratorio di Algoritmi e Strutture Dati
Strutture dati: Alberi
Definizione
Operazioni basilari su Alberi
Stampa di una struttura Albero in ASCII
Esempio di stampa in ASCII di un Albero
Come possiamo stampare su terminale ed in modo graficamente chiaro un Albero?
A
\
\
A
2
1
3
B
C
B
2
D
C
3
D
1
\
E
1
\
F
2
G
2
\
\
\
\
\
1
2
E
F
2
G
A
+ - B :2
+ - C :3
| + - E :1
+ - D :1
+ - F :2
+ - G :2
Pietro Di Lena
Laboratorio di Algoritmi e Strutture Dati
Strutture dati: Alberi
Definizione
Operazioni basilari su Alberi
Stampa di una struttura Albero in ASCII
Nota: stampa di un albero in ascii 1/2
Procedura di stampa principale. Richiede l’implementazione della funzione che
calcola l’altezza dell’albero Height(T).
# include < stdio .h >
# include < stdlib .h >
void printtree ( NODE * T ) {
if ( T != NULL ) {
char * indent =( char *) calloc (2* height ( T ) , sizeof ( char ) ) ;
NODE * tmp ;
printf ("% c :% d \ n " ,T - > name ,T - > label ) ;
for ( tmp =T - > children ; tmp != NULL ; tmp = tmp - > brother )
printtree_rec ( tmp , indent ,0) ;
free ( indent ) ;
}
}
Pietro Di Lena
Laboratorio di Algoritmi e Strutture Dati
Strutture dati: Alberi
Definizione
Operazioni basilari su Alberi
Stampa di una struttura Albero in ASCII
Nota: stampa di un albero in ascii 2/2
void printindent ( char * indent , int n ) {
int i ;
for ( i =0; i < n ; i ++)
printf ("% c " , indent [ i ]) ;
}
void printtree_rec ( NODE *T , char * indent , int n ) {
if ( T != NULL ) {
NODE * tmp ;
printindent ( indent , n ) ;
printf ("+ -") ;
if (T - > brother == NULL ) // Last children
indent [ n ++]= ’ ’;
else
// More brothers
indent [ n ++]= ’| ’;
indent [ n ++]= ’ ’;
printf ("% c :% d \ n " ,T - > name ,T - > label ) ;
for ( tmp =T - > children ; tmp != NULL ; tmp = tmp - > brother )
printtree_rec ( tmp , indent , n ) ;
}
}
Pietro Di Lena
Laboratorio di Algoritmi e Strutture Dati