tipo astratto, implementazione, algoritmi alberi tipo astratto, implementazione, algoritmi
argomenti tipo astratto albero alberi binari definizione implementazione in Java algoritmi di visita alberi binari implementazione di alberi binari in Java ASD - Alberi
tipo di dato astratto albero insieme vuoto di nodi oppure costituito da una radice R e da 0 o più alberi (sottoalberi) la radice di ogni sottoalbero è collegata a R da un arco R es.: radice R con n sottoalberi T1 T2 Tn ASD - Alberi
terminologia genitore, figlio, fratello nodo concetti intuitivi foglia se ha zero figli interno se ha almeno un figlio radice nodo interno foglia ASD - Alberi
terminologia/2 livello di un nodo ramo altezza albero lunghezza (n.ro nodi) percorso radice-nodo ramo percorso radice-foglia altezza albero lunghezza (n.ro nodi) ramo più lungo livello radice = 1 altezza = 3 ASD - Alberi
alberi? ASD - Alberi
esempi di alberi alberi genealogici gerarchie di ereditarietà ad es., in Java classificazioni di specie animali organizzazione del territorio continente, nazione, regione, provincia ecc (alcuni) organigrammi file system domini Internet ASD - Alberi
rappresentazione di alberi con liste collegate livello di C = 3 R A B Primo figlio di R C Fratello di A Elemento Riferimento al prossimo fratello Riferimento al primo figlio ASD - Alberi
operazioni sugli alberi operazioni più importanti element(v): restituisce l’elemento memorizzato nel nodo v root(): restituisce la radice dell’albero parent(v): restituisce il genitore del nodo v children(v): restituisce i figli di v isLeaf(v): restituisce true se v è una foglia isRoot(v): restituisce true se v è la radice ASD - Alberi
operazioni sugli alberi Altre operazioni livello di un nodo altezza dell’albero # nodi # foglie arità max # di figli di un nodo dell’albero isEmpty true se l’albero ha zero nodi ASD - Alberi
rappresentazione dei nodi in Java class TreeNode { Object element; TreeNode firstChild; TreeNode nextSibling; TreeNode parent; } ASD - Alberi
tipo astratto albero in Java public interface Tree { Object element(TreeNode v); TreeNode root(); TreeNode parent(TreeNode v); ListIterator children(TreeNode v); boolean isLeaf(TreeNode v); boolean isRoot(TreeNode v); } ASD - Alberi
algoritmi su alberi livello di un nodo public int level(TreeNode v) { if(this.isRoot(v)) return 1; else return 1 + level(this.parent(v)); } costo proporzionale all’altezza: O(h ) ASD - Alberi
algoritmi su alberi/2 altezza di un (sotto)albero int height(v) { int h=0, hmax=0; if(v == null) return 0; if(isLeaf(v)) return 1; TreeNode w = v.firstChild; hmax = height(w); while(w.nextSibling != null) { w = w.nextSibling; h = height(w); if(h > hmax) hmax = h; } return 1 + hmax; altezza di un (sotto)albero costo proporzionale al numero di nodi: (n ) viene esaminato ogni nodo ciascun nodo viene esaminato una sola volta ASD - Alberi
algoritmi su alberi/3 visita (o attraversamento) di un albero in profondità (depth-first search, a scandaglio): DFS vengono visitati i rami, uno dopo l’altro tre varianti in ampiezza (breadth-first search, a ventaglio): BFS a livelli, partendo dalla radice ASD - Alberi
visite in profondità/preordine in preordine (preorder, o ordine anticipato) dato un nodo v visita v visita i sotto-alberi aventi come radice i figli di v, da sinistra verso destra void treePreorder(root) { if(root == null) return; <visita root> r = root.firstChild while (r != null) { treePreorder(r); r = r.nextSibling; } ASD - Alberi
visite in profondità/inordine in ordine simmetrico (inorder) dato un nodo v con k sotto-alberi visita il primo sotto-albero (radice v.firstChild) visita v visita gli altri k-1 sotto-alberi void treeInorder(root) { if(root == null) return; r = root.firstChild; treeInorder(r); <visita root> r = r.nextSibling; while (r != null) { treeInorder(r); r = r.nextSibling; } ASD - Alberi
visite in profondità/postordine in postordine (postorder, o ordine posticipato) dato un nodo v visita i sotto-alberi aventi come radice i figli di v, da sinistra verso destra visita v void treePostorder(root) { if(root == null) return; r = root.firstChild while (r != null) { treePostorder(r); r = r.nextSibling; } <visita root> ASD - Alberi
visite in profondità preordine inordine postordine 1 2 3 5 4 6 7 2 1 4 ASD - Alberi
visita in ampiezza breadth-first search (BFS), usa una coda dato un nodo v void bfs(v) { if(v == null) return; queue.enqueue(v); while (!queue.isEmpty()) { v = queue.dequeue(); v.visit(); TreeNode w = v.firstChild; while(w != null) { queue.enqueue(w); w = w.nextSibling; } ASD - Alberi
visita in ampiezza 1 2 3 4 5 6 7 BFS ASD - Alberi
alberi binari un albero si dice binario se ogni nodo può avere al più 2 figli la rappresentazione si semplifica public class BinaryNode { protected Object element; protected BinaryNode leftChild; protected BinaryNode rightChild; } implementazione minima ASD - Alberi
ADT albero binario in Java public interface BinaryTree { Object element(BinaryNode v); BinaryNode root(); BinaryNode parent(BinaryNode v); BinaryNode leftChild(BinaryNode v); BinaryNode rightChild(BinaryNode v); boolean isLeaf(BinaryNode v); boolean isRoot(BinaryNode v); } ASD - Alberi
alberi binari/visita in preordine void treePreorder(BinaryNode v) { if(v == null) return; <visita v> treePreorder(leftChild(v)); treePreorder(rightChild(v)); } ASD - Alberi
alberi binari/visita inordine void treeInorder(BinaryNode v) { if(v == null) return; treeInorder(leftChild(v)); <visita v> treeInorder(rightChild(v)); } ASD - Alberi
alberi binari/visita in postordine void treePostorder(BinaryNode v) { if(v == null) return; treePostorder(leftChild(v)); treePostorder(rightChild(v)); <visita v> } ASD - Alberi
alberi binari/visita in ampiezza void bfs(v) { TreeNode p = v; queue.enqueue(p); while (!queue.isEmpty()) { p = (BSTNode) queue.dequeue(); p.visit(); if (p.leftChild != null) queue.enqueue(p.leftChild); if (p.rightChild != null) queue.enqueue(p.rightChild); } ASD - Alberi
strutture dati per alberi binari vettori rappresentazioni collegate esercizi: implementare l’interfaccia BinaryTree usando una rappresentazione collegata scrivere un programma che legga gli elementi (stringhe) di un albero binario e li stampi effettuando una visita in preordine ASD - Alberi
uso di vettori ogni nodo v è memorizzato in posizione p(v) se v è la radice allora p(v)=1 (indice 0 in Java, C, C++) se v è il figlio sinistro di u allora p(v)=2p(u) se v è il figlio destro di u allora p(v)=2p(u)+1 1 2 3 4 - 6 7 1 2 3 4 6 7 ASD - Alberi
uso di vettori/2 implementazione statica: è necessaria una stima del numero massimo di nodi dell’albero può portare a spreco di risorse nel caso peggiore, un albero con n nodi richiede un vettore con 2n-1 elementi (se l’albero degenera in una catena) ASD - Alberi
uso di vettori/3 in Java: si possono usare le classi Vector (sincronizzata) o ArrayList (non sincronizzata) Vector e ArrayList gestiscono anche il ridimensionamento quando il numero di elementi cresce oltre la capacità corrente ciò porta a ritardi (per gestire l’allocazione di nuova memoria) esercizio: scrivere una classe che implementi l’interfaccia BinaryTree usando ArrayList o Vector ASD - Alberi
rappresentazione collegata public class LinkedBinaryTree implements BinaryTree { private BinaryNode root; /* Rif. alla radice*/ private int size; public LinkedBinaryTree() { root = new BinaryTreeNode(null, null, null); size = 0; } /* Metodi */ } /* Fine della classe */ ASD - Alberi