Alberi (GT. 7)

annuncio pubblicitario
Alberi
( GT. 7 )
Albero definizioni
Albero ADT (Abstract Data Type)
Algoritmi di base su alberi
Alberi binari
Strutture dati per rappresentare alberi
Implementazione AlberoBinario
1
Alberi (GT. 7)
In informatica, un albero è un modello astratto con cui viene
rappresentata una struttura gerarchica
Albero:
insieme di nodi (contenenti informazione) che sono in relazione
padre-figlio
un albero non vuoto, contiene un nodo speciale che non ha
padre, detto root
tutti i nodi diversi dalla radice hanno un solo padre
ogni nodo con padre p, è figlio di p
Albero ordinato:
esiste una relazione d’ordine tra i figli di ogni nodo
2
1
Alberi (GT. 7)
Struttura dati non lineare: una relazione tra elementi più ricca
della semplice relazione lineare “prima” e “dopo” o “precede” e
“segue” (stack, coda, lista)
La relazione tra gli elementi di un albero è gerarchica: “padre”,
“figlio”, “ascendenti”, “discendenti”
Computers”R”Us
Sales
US
Manufacturing
International
Europe
Laptops
Asia
R&D
Desktops
Canada
3
Tree - terminologia di base
(1)
Root : nodo senza padre (A)
Internal node:
node nodo con almeno un figlio (A, B, C, F)
External node ( leaf ): nodo senza figli (E, I, J, K, G, H, D)
Ancestors di un nodo : nodo, padre, nonno, bisnonno, etc.
A
B
E
C
F
G
D
H
subtree
I
J
K
4
2
Tree - terminologia di base
(2)
Depth di un nodo: numero di ascendenti (escluso se stesso)
Height di un albero: profondità massima dei nodi esterni
Descendant di un nodo: nodo, figlio, nipote, pronipote, etc.
Subtree:
Subtree un albero formato da un nodo e dai suoi discendenti
A
B
E
C
F
G
D
H
subtree
I
J
K
5
Tree – ADT
(1)
L’ ADT tree memorizza elementi in posizioni, le posizioni in
un albero sono rappresentate da nodi
Metodi generici:
integer size()
boolean isEmpty()
Iterator iterator()
Iterable positions()
Metodi di navigazione:
position root()
position parent (p)
positionIterator children (p)
6
3
Tree – ADT
(2)
Metodi di interrogazione:
boolean isInternal(p)
boolean isExternal(p)
boolean isRoot(p)
Metodi di aggiornamento:
object replace (p, o)
N.B. La specifica in pseudo-codice degli algoritmi sugli alberi
fa riferimento alla definizione di tree ADT
N.B. Metodi di aggiornamento aggiuntivi potranno essere
definiti dalle strutture dati che implementano l’ADT Tree
7
Tree – Interface (§ 7.1.3)
(1)
public interface Tree<E> {
public int size(); /** Returns the number of nodes in the tree. */
public boolean isEmpty(); /** Returns whether the tree is empty. */
public Iterator<E> iterator(); /** Return an iterator of the elements stored in the tree. */
public Iterable<Position<E>> positions(); /** Returns an iterable collection of the
nodes stored in the tree. */
/** Replaces the element stored at a given node. */
public E replace ( Position<E> v, E e) throws InvalidPositionException;
/** Returns the root of the tree. */
public Position<E> root() throws EmptyTreeException;
/** Returns the parent of a given node. */
public Position<E> parent( Position<E> v)
throws InvalidPositionException, BoundaryViolationException;
8
4
Tree – Interface (§ 7.1.3)
(2)
/** Returns an iterable collection of the children of a given node. */
public Iterable<Position<E>> children( Position<E> v )
throws InvalidPositionException;
/** Returns whether a given node is internal. */
public boolean isInternal( Position<E> v) throws InvalidPositionException;
/** Returns whether a given node is external. */
public boolean isExternal( Position<E> v) throws InvalidPositionException;
/** Returns whether a given node is the root of the tree. */
public boolean isRoot( Position<E> v) throws InvalidPositionException;
}
N.B. La specifica in Java degli algoritmi sugli alberi fa
riferimento alla definizione di Tree Interface
9
Linked Structure for General Tree (§ 7.1.3)
Oggetto Posizione
associato ad un nodo
Lista dei figli di un nodo
10
5
Alberi – Algoritmi di base (§ 7.2)
Profondità (depth) di un nodo v è il numero di
Running time
ascendenti di v ( escluso v stesso )
Algoritmo depth(T,v)
O(d v )
if T.isRoot(v) then return 0
else
O(n)
return 1 + depth(T, T.parent(v))
public static <E> int depth( Tree<E> T, Position<E> v) {
if (T.isRoot(v) ) return 0;
else
return 1 + depth(T, T.parent(v) );
}
profondità
massima nel
caso più
sfavorevole è :
n −1
11
Alberi – Algoritmi di base (§ 7.2)
Altezza ( height ) di un nodo v
è zero se v è un nodo esterno
altrimenti, è 1 + l’altezza del più alto dei figli di v
Algoritmo height_1 (T)
In pseudocodice :
h=0
l’altezza è uguale
for ogni v in T do
alla profondità
if T.isExternal(v) then
h = max ( h, depth(T,v ) )
del più profondo
dei nodi esterni
return h
12
6
Alberi – Algoritmi di base (§ 7.2)
Altezza (height) di un nodo v
public static <E> int height_1 (Tree<E> T) {
int h = 0;
Codice Java in base
all’ interface Tree
Iterable pos = T.positions();
for ( Position<E> v : pos ) {
if ( T.isExternal(v) )
Elevata
complessità
h = Math.max( h, depth(T,v) );
}
return h
}
Caso più sfavorevole
O(n + ∑v∈E (1 + d v ))
O(n 2 )
13
Alberi– Algoritmi di base (§ 7.2)
Altezza algoritmo 2
In pseudocodice :
l’algoritmo segue la
Algoritmo height_2 (T, v )
definizione ricorsiva
if T.isExternal(v) then return 0
else
h=0
for ogni w in T.children(v) do
h = max ( h, height_2 (T,w ) )
return 1 + h
14
7
Alberi – Algoritmi di base (§ 7.2)
Codice Java in base
all’ interface Tree
Altezza algoritmo 2
public static <E> int height_2 (Tree<E> T, Position<E> v ) {
if ( T.isExternal(v) )
return 0;
else {
int h = 0;
Iterable ch = T.children(v);
for ( Position<E> w : ch )
h = Math.max( h, heigt_2 ( T, w );
return 1 + h;
}
}
15
Alberi – Algoritmi di base (§ 7.2)
Altezza - algoritmo 2 - analisi complessità :
¾ L’algoritmo è basato sulla def. ricorsiva di altezza :
viene applicato una sola volta su ogni nodo dell’albero T
¾ per ciascun nodo, il calcolo l’iterazione su tutti i children(v)
richiede
O ( cv ) ,
¾ il ciclo while compie
con
cv
cv numero dei figli del nodo v
iterazioni,
percio’ per ogni nodo l’algoritmo spende
¾ poiché è :
∑v∈T cv = n − 1
¾ il costo complessivo è :
O(1 + cv )
Ogni nodo è figlio di un altro nodo
tranne la radice
O(∑v∈T (1 + cv )) = O(n)
16
8
Attraversamento – Preordine (§ 7.2.2)
Un attraversamento di un albero T è un modo sistematico per
accedere, o visitare, tutti i nodi di T
Alla visita di un nodo è associata una specifica azione
dipendente dalla particolare applicazione
Nell’attraversamento in preordine un nodo viene visitato prima
dei suoi discendenti
Algorithm preorder(T, v)
visit(v)
for each child w of v in T do
preorder (T, w)
17
Visita in preordine - esempio
Paper
Title
Abstr
p. 1
1.1
1.2
p. 3
p. 2
2.1
2.2
2.3
3.1
Refer.
3.2
Nel preordine prima viene visitata la radice poi, nell’ordine, i
diversi sottoalberi
18
9
Preodine – analisi complessità
¾ L’algoritmo rappresenta una strategia efficiente per
visitare in modo sistematico tutti i nodi di un albero
¾ Per ciascun nodo v dell’albero, la parte non ricorsiva
dell’algoritmo di attraversamento richiede :
O(1 + cv )
¾ perciò il tempo complessivo risulta essere :
O(∑v∈T (1 + cv )) = O(n)
dato che :
∑
v∈T
cv = n − 1
19
Preordine – esempio in Java
Esempio: metodo in codice Java per la stampa in preordine degli
elementi associati ai nodi di un albero
in Java
public static E String toStringPreorderPrint (Tree<E> T,
Position<E> v ) {
String s = v.element().toString();
Iterable ch_set = T.children(v);
for ( Position<E> w : ch_set )
s = s + toStringPreorderPrint(T, w );
return s
}
20
10
Attraversamento - Postordine
Nell’attraversamento in postordine,
postordine un nodo viene visitato
dopo i suoi discendenti:
Algorithm postOrder( T, v)
for each child w of v do postOrder (T, w)
visit(v)
21
Postordine - esempio
Applicazione: calcolare lo spazio usato dai file in una directory e
dalle sue sotto_directory
Il problema può essere risolto in modo bottom-up con un
attraversamento in postordine:
9
cs16/
3
8
7
homeworks/
todo.txt
1K
programs/
1
2
h1c.doc
3K
h1nc.doc
2K
4
DDR.java
10K
5
Stocks.java
25K
6
Robot.java
20K
22
11
Altri tipi di attraversamento
Postordine e Preordine seguono una strategia di tipo DFS (depthfirst-search ) (prima in profondità)
E’ possibile anche seguire una strategia di tipo BFS (breadthfirst-search) : visita per livelli successivi a partire dalla root
è possibile un algoritmo iterativo che utilizza un ADT Coda
Esercizio: realizzare l’algoritmo in pseudo codice e in Java
1.1
2.1
A
2.3
2.2
B
C
3.1
3.2
E
F
3.4
G
3.5
H
D
3.6
I
23
12
Scarica