Scaricare la presentazione
La presentazione è in caricamento. Aspetta per favore
1
Corso di Informatica 2 a.a. 2003/04 Lezione 6
Alberi binari Corso di Informatica 2 a.a. 2003/04 Lezione 6 Ugo de'Liguoro - Informatica 2 a.a. 03/04 Lez. 6
2
Cosa sono gli alberi? Ugo de'Liguoro - Informatica 2 a.a. 03/04 Lez. 6
3
Strutture gerarchiche di ogni tipo
Generale Colonnello1 Maggiore1,1 Maggiore1,m Colonnellok Maggiorek,1 Maggiorek,n Capitano Ugo de'Liguoro - Informatica 2 a.a. 03/04 Lez. 6
4
Strutture gerarchiche di ogni tipo
Strutture dati Tipi di dato e strutture dati Specifica e realizzazione Rappresentazione in memoria Liste L’ADT delle liste Realizzazione con vettori Realizzazione con puntatori Pile e code L’ADT delle pile … Ugo de'Liguoro - Informatica 2 a.a. 03/04 Lez. 6
5
Definizioni Un albero èun grafo connesso aciclico; nel caso finito può essere definito induttivamente come un insieme tale che: è un albero; se k 0, T1, …, Tk sono alberi, v un vertice, allora {v, T1, …, Tk } è un albero Un insieme di alberi è una foresta. albero grafo ciclico foresta Ugo de'Liguoro - Informatica 2 a.a. 03/04 Lez. 6
6
Struttura induttiva degli alberi
nodo albero albero Ugo de'Liguoro - Informatica 2 a.a. 03/04 Lez. 6
7
Alberi con radice e foglie
La radice è un nodo privilegiato di un albero; se l’albero è un grafo non orientato qualunque nodo può considerarsi radice; se l’albero è orientato allora due casi: la radice ha solo archi in uscita (albero sorgente) la radice ha solo archi in entrata (albero pozzo) Una foglia è un nodo da cui non esce alcun arco Ugo de'Liguoro - Informatica 2 a.a. 03/04 Lez. 6
8
Alberi sorgente, alberi pozzo
Ugo de'Liguoro - Informatica 2 a.a. 03/04 Lez. 6
9
f è un discendente di a; a è un avo di f
Parentele a è padre di b e c a b è figlio di a c b f è un discendente di a; a è un avo di f d e f d è fratello di e Ugo de'Liguoro - Informatica 2 a.a. 03/04 Lez. 6
10
Un cammino dalla radice ad una foglia si dice ramo
Cammini Cammino: sequenza di archi ciascuno incidente sul vertice di quello successivo Un cammino dalla radice ad una foglia si dice ramo Ugo de'Liguoro - Informatica 2 a.a. 03/04 Lez. 6
11
Livelli Livello: insieme di vertici equidistanti dalla radice
L’altezza è la massima distanza dalla radice di un livello non vuoto Ugo de'Liguoro - Informatica 2 a.a. 03/04 Lez. 6
12
Alberi ordinati Un albero è ordinato quando lo sono (linearmente) i suoi livelli Come alberi ordinati siamo diversi a a b c d = c b d Conta solo l’ordine, non sinistra e destra Ugo de'Liguoro - Informatica 2 a.a. 03/04 Lez. 6
13
Alberi k-ari Arietà = massimo num. dei figli di qualche nodo
Io sono un albero ternario Ugo de'Liguoro - Informatica 2 a.a. 03/04 Lez. 6
14
Alberi posizionali Un albero ordinato è posizionale quando nell’ordine dei livelli si tiene conto di (si deve quindi fissare l’arietà) a a b c d b c d Ugo de'Liguoro - Informatica 2 a.a. 03/04 Lez. 6
15
Una specifica Sintassi Tipi: Tree, Node Operatori:
NewTree: void Tree IsEmptyTree: Tree boolean InsAsRoot: Node, Tree Tree Root: Tree Node Parent: Node, Tree Node Leaf: Node, Tree boolean … Ugo de'Liguoro - Informatica 2 a.a. 03/04 Lez. 6
16
Una specifica Sintassi Tipi: Tree, Node Operatori: …
Child: Node, Tree Node HasSibling: Node, Tree Boolean Sibling: Node, Tree Node InsTree: Node, Node, Tree, Tree Tree DelTree: Node, Tree Tree Ugo de'Liguoro - Informatica 2 a.a. 03/04 Lez. 6
17
Semantica degli operatori
Con qualcosa si deve pur cominciare A cosa servono queste banalità? r InsAsRoot(r, ) InsAsRoot(n, T ) = T Pre: T = Post: T è l’albero il cui unico nodo è n Ugo de'Liguoro - Informatica 2 a.a. 03/04 Lez. 6
18
Semantica degli operatori
b c d T r b DelTree(a, T ) DelTree(n, T ) = T Pre: n è un nodo di T Post: T risulta da T eliminando il sottoalbero con radice in n Ugo de'Liguoro - Informatica 2 a.a. 03/04 Lez. 6
19
Semantica degli operatori
b c d z x v InsTree(c, a, T, U ) r a b c d T z x v U InsTree(n, m, T, U ) = T Pre: m, n sono nodi di T, U Post: T risulta da T inserendo U come figlio di m e fratello successivo di n se n m primo figlio di m se n = m Ugo de'Liguoro - Informatica 2 a.a. 03/04 Lez. 6
20
Semantica degli operatori
b c d z x v InsTree(a, a, T, U ) r a b c d T z x v U InsTree(n, m, T, U ) = T Pre: m, n sono nodi di T, U Post: T risulta da T inserendo U come figlio di m e fratello successivo di n se n m primo figlio di m se n = m Ugo de'Liguoro - Informatica 2 a.a. 03/04 Lez. 6
21
Semantica degli operatori
NewTree () = (albero vuoto) Root(T) = la radice di T Parent (n, T) = m Pre: n T Post: m padre di n Child (n, T) = m Pre: n T, Leaf(n, T) = false Post: m è il primo figlio di n Sibling (n, T) = m Pre: n T , HasSibling (n, T) = true Post: m è il fratello successivo di n IsEmptyTree(T) = true se T = , false altr. Leaf(n, T) = b Pre: n T , b = true sse n è una foglia HasSibling(n, T) = b Pre: n T Post: b = true sse n ha un fratello Ugo de'Liguoro - Informatica 2 a.a. 03/04 Lez. 6
22
Realizzazioni: vettore dei padri
Efficiente per rappresentare alberi pozzo di cardinalità (numero dei nodi) fissata c b f d e etichetta del nodo indice del nodo indice del padre a 1 b 2 c 3 d 4 e 5 f 6 Ugo de'Liguoro - Informatica 2 a.a. 03/04 Lez. 6
23
Alberi binari: definizione induttiva
L’insieme degli alberi binari etichettati in A, BT(A), è definito induttivamente: BT(A) (albero vuoto) a A, l BT(A), r BT(A) ConsTree(a, l, r) BT(A) Si introduce la nozione di sottoalbero sinistro e destro a l r Ugo de'Liguoro - Informatica 2 a.a. 03/04 Lez. 6
24
Alberi binari realizzati con puntatori
d T info left right r a b c d T Ugo de'Liguoro - Informatica 2 a.a. 03/04 Lez. 6
25
Codifica binaria di alberi k-ari
g a b c d e f g Nel caso di alberi non ordinati la codifica non è univoca! Ugo de'Liguoro - Informatica 2 a.a. 03/04 Lez. 6
26
Realizzazioni: con puntatori
b c d e f g info child sibling parent a b c d e f g Ugo de'Liguoro - Informatica 2 a.a. 03/04 Lez. 6
27
La cardinalità di un albero binario
Right(B) = r Left(B) = l Cardinalità (B) if B = then return 0 else return 1 + Cardinalità (Left(B)) + Cardinalità (Right(B)) Ugo de'Liguoro - Informatica 2 a.a. 03/04 Lez. 6
28
L’altezza di un albero binario
Si usa una funzione ausiliaria perché il caso di base B = è essenziale alla ricorsione Altezza (B) // Pre: B // Post: ritorna l’altezza di B return Altezza_aux (B) Altezza_aux (B) // Post: ritorna l’altezza di B, 0 se B = if B = then return 0 else return max{Altezza_aux(Left(B), Altezza_aux(Right(B)) + 1 Ugo de'Liguoro - Informatica 2 a.a. 03/04 Lez. 6
29
La ricorsione sugli alberi
ContaFoglie (T) // Post: ritorna il numero delle foglie di T if T = then return 0 due casi di base else if T ha un solo nodo then return 1 else siano T1, …, Tk i sottoalberi con radici nei nodi figli di della radice di T return Questo pseudocodice è lontano dalla realizzazione Ugo de'Liguoro - Informatica 2 a.a. 03/04 Lez. 6
30
La ricorsione sugli alberi
ContaFoglie (T) // Post: ritorna il numero delle foglie di T if IsEmptyTree(T) then return 0 else return Cf_aux(Root(T), T) Cf_aux (n, T) // Pre: n T // Post: ritorna il numero delle foglie del sottoalbero di T con radice in n Ugo de'Liguoro - Informatica 2 a.a. 03/04 Lez. 6
31
La ricorsione sugli alberi
Cf_aux (n, T) // Pre: n T // Post: ritorna il numero delle foglie del sottoalbero di T con radice in n if Leaf(n, T) then return 1 else // n ha almeno un figlio in T m Child(n, T) foglie Cf_aux (m, T) while HasSibling (m, T) do m Sibling (m, T) foglie foglie + Cf_aux (m, T) return foglie Se m aveva un fratello, allora l’attuale valore di m è un nodo di T Ugo de'Liguoro - Informatica 2 a.a. 03/04 Lez. 6
32
Visite: Depth First Search
DFS (T) // Post: visita i nodi di T in profondità if T then visita Root(T) siano T1, …, Tk i sottoalberi con radici nei nodi figli di della radice di T for i 1 to k do DFS (Ti) Ugo de'Liguoro - Informatica 2 a.a. 03/04 Lez. 6
33
Visite: Depth First Search
DFS (T) // Post: visita i nodi di T in profondità if not IsEmtyTree(T ) then DFS_aux (Root(T), T) DFS_aux (n, T) // Post: visita in profondità il sottoalbero di T con radice in n Ugo de'Liguoro - Informatica 2 a.a. 03/04 Lez. 6
34
Visite: Depth First Search
DFS_aux (n, T) // Post: visita in profondità il sottoalbero di T con radice in n cominciando dalla radice visita n if not Leaf (n, T) then m Child (n, T) DFS_aux (m, T) while HasSibling (m, T) do m Sibling(m, T) Ugo de'Liguoro - Informatica 2 a.a. 03/04 Lez. 6
35
Il tipo BinTree typedef struct tnode { T info; // etichetta
struct tnode *left, *right; // puntatori ai figli sinistro e destro } tNode; typedef struct bintreeframe { int card; // numero dei nodi dell’albero tNode* root; // radice dell’albero } BinTreeFrame typedef BinTreeFrame* BinTree; Ugo de'Liguoro - Informatica 2 a.a. 03/04 Lez. 6
36
Costruttori tNode* NewtNode (T etc, tNode* l, tNode* r)
{ tNode* n = new tNode; n->info = etc; n->left = l; n->right = r; return n; } BinTree NewBinTree (void) { BinTree bt = new BinTreeFrame; bt->card = 0; bt->root = NULL; return bt; Ugo de'Liguoro - Informatica 2 a.a. 03/04 Lez. 6
37
Un esempio: la funzione Altezza
int Altezza (tNode* n) // Pre: n != NULL // Post: ritorna l’altezza dell’albero con radice in n { return Altezza_aux(n); } int Altezza_aux (tNode*) // Post: ritorna l’altezza di tNode se != NULL, 0 altr. { int hl = 0, hr = 0; if (n->left == NULL && n->right == NULL) return 0; if (n->left != NULL) hl = Altezza_aux (n->left); if (n->right != NULL) hr = Altezza_aux (n->right); if (hl > hr) return hl + 1; return hr + 1; } Ugo de'Liguoro - Informatica 2 a.a. 03/04 Lez. 6
38
Visite in profondità void preorder (tNode* n) { if (n != NULL)
{ visit(n); preorder(n->left); preorder(n->right); } void inorder (tNode* n) { { inorder(n->left); visit(n); inorder(n->right); Ugo de'Liguoro - Informatica 2 a.a. 03/04 Lez. 6
39
La lista dei vertici in preordine (1)
Ugo de'Liguoro - Informatica 2 a.a. 03/04 Lez. 6
40
La lista dei vertici in preordine (2)
La soluzione ovvia è O(n2): Node* Preorder_List (tNode* n) { if (n == NULL) return NULL; return NewNode(n->info, concat (Preorder_List(n->left), Preorder_List(n->right)); } La complessità quadratica deriva dall’uso di concat nel caso in cui l’albero sia degenere sinistro. Ugo de'Liguoro - Informatica 2 a.a. 03/04 Lez. 6
41
La lista dei vertici in preordine (3)
Esiste una soluzione ottima O(n): Node* Preorder_List2 (tNode* n, Node* l) { if (n == NULL) return l; return NewNode(n->info, Preorder_List2(n->left, Preorder_List2(n->right,l)); } Ugo de'Liguoro - Informatica 2 a.a. 03/04 Lez. 6
Presentazioni simili
© 2024 SlidePlayer.it Inc.
All rights reserved.