Alberi
Alberto Montresor
Università di Trento
2018/10/19
Esempio 1
Esempio 2
Esempio 3
<html>
<head>
<meta http-equiv="Content-Type" content="text/html"/>
<title>simple</title>
</head>
<body>
<h1>A simple web page</h1>
<ul>
<li>List item one</li>
<li>List item two</li>
</ul>
<h2>
<a href="http://www.google.com">Google</a>
</h2>
</body>
</html>
Esempio 3
html
head body
meta title h1 ul h2
li li a
Root
T1 T2 ... Tk
Terminologia
Radice
Sottoalbero B C Sottoalbero
D E F G
H I J K L M
Terminology (English)
Root
Subtree B C Subtree
D E F G
H I J K L M
Terminologia
Livello
Profondità nodi (Depth)
0
La lunghezza del cammino
semplice dalla radice al nodo 1
(misurato in numero di archi)
2
Livello (Level) 3
1 Introduzione
Esempi
Definizioni
2 Alberi binari
Introduzione
Implementazione
Visite
3 Alberi generici
Visite
Implementazione
Alberi binari Introduzione
Albero binario
Albero binario
Un albero binario è un albero radicato in cui ogni nodo ha al mas-
simo due figli, identificati come figlio sinistro e figlio destro.
Nota: Due alberi T e U che hanno gli stessi nodi, gli stessi figli per
ogni nodo e la stessa radice, sono distinti qualora un nodo u sia
designato come figlio sinistro di v in T e come figlio destro di v in U .
T1 T2 T3 Livello
1 1 1 0
2 2 2 1
3 4 3 4 3 4 2
5 5 5 3
Tree
% Costruisce un nuovo nodo, contenente v, senza figli o genitori
Tree(Item v)
% Legge il valore memorizzato nel nodo
Item read()
% Modifica il valore memorizzato nel nodo
write(Item v)
% Restituisce il padre, oppure nil se questo nodo è radice
Tree parent()
Tree
% Restituisce il figlio sinistro (destro) di questo nodo; restituisce nil se
assente
Tree left()
Tree right()
% Inserisce il sottoalbero radicato in t come figlio sinistro (destro) di
questo nodo
insertLeft(Tree t)
insertRight(Tree t)
% Distrugge (ricorsivamente) il figlio sinistro (destro) di questo nodo
deleteLeft()
deleteRight()
P P
L R L R
P P P P
L R L R L R L R
Implementazione
Tree
Tree(Item v) deleteLeft()
Tree t = new Tree if left 6= nil then
t.parent = nil left.deleteLeft()
t.left = t.right = nil left.deleteRight()
t.value = v left = nil
return t
deleteRight()
insertLeft(Tree T ) if right 6= nil then
if left == nil then right.deleteLeft()
T.parent = this right.deleteRight()
left = T right = nil
insertRight(Tree T )
if right == nil then
T.parent = this
right = T
Visite di alberi
Depth-First Search
A
dfs(Tree t)
if t 6= nil then
% pre-order visit of t B E
print t
dfs(t.left())
% in-order visit of t C D F G
print t
dfs(t.right())
% post-order visit of t
print t
dfs(Tree t) A
if t 6= nil then
% pre-order visit of t
print t B E
dfs(t.left())
% in-order visit of t
C D F G
print t
dfs(t.right())
Sequence:
% post-order visit of t Stack: A
print t
dfs(Tree t) A
if t 6= nil then
% pre-order visit of t
print t B E
dfs(t.left())
% in-order visit of t
C D F G
print t
dfs(t.right())
Sequence:
% post-order visit of t Stack: A B
print t
dfs(Tree t) A
if t 6= nil then
% pre-order visit of t
print t B E
dfs(t.left())
% in-order visit of t
C D F G
print t
dfs(t.right())
Sequence: C
% post-order visit of t Stack: A B C
print t
dfs(Tree t) A
if t 6= nil then
% pre-order visit of t
print t B E
dfs(t.left())
% in-order visit of t
C D F G
print t
dfs(t.right())
Sequence: C B
% post-order visit of t Stack: A B
print t
dfs(Tree t) A
if t 6= nil then
% pre-order visit of t
print t B E
dfs(t.left())
% in-order visit of t
C D F G
print t
dfs(t.right())
Sequence: C B D
% post-order visit of t Stack: A B D
print t
dfs(Tree t) A
if t 6= nil then
% pre-order visit of t
print t B E
dfs(t.left())
% in-order visit of t
C D F G
print t
dfs(t.right())
Sequence: C B D
% post-order visit of t Stack: A B
print t
dfs(Tree t) A
if t 6= nil then
% pre-order visit of t
print t B E
dfs(t.left())
% in-order visit of t
C D F G
print t
dfs(t.right())
Sequence: C B D A
% post-order visit of t Stack: A
print t
dfs(Tree t) A
if t 6= nil then
% pre-order visit of t
print t B E
dfs(t.left())
% in-order visit of t
C D F G
print t
dfs(t.right())
Sequence: C B D A
% post-order visit of t Stack: A E
print t
dfs(Tree t) A
if t 6= nil then
% pre-order visit of t
print t B E
dfs(t.left())
% in-order visit of t
C D F G
print t
dfs(t.right())
Sequence: C B D A F
% post-order visit of t Stack: A E F
print t
dfs(Tree t) A
if t 6= nil then
% pre-order visit of t
print t B E
dfs(t.left())
% in-order visit of t
C D F G
print t
dfs(t.right())
Sequence: C B D A F E
% post-order visit of t Stack: A E
print t
dfs(Tree t) A
if t 6= nil then
% pre-order visit of t
print t B E
dfs(t.left())
% in-order visit of t
C D F G
print t
dfs(t.right())
Sequence: C B D A F E G
% post-order visit of t Stack: A E G
print t
dfs(Tree t) A
if t 6= nil then
% pre-order visit of t
print t B E
dfs(t.left())
% in-order visit of t
C D F G
print t
dfs(t.right())
Sequence: C B D A F E G
% post-order visit of t Stack: A E
print t
dfs(Tree t) A
if t 6= nil then
% pre-order visit of t
print t B E
dfs(t.left())
% in-order visit of t
C D F G
print t
dfs(t.right())
Sequence: C B D A F E G
% post-order visit of t Stack: A
print t
dfs(Tree t) A
if t 6= nil then
% pre-order visit of t
print t B E
dfs(t.left())
% in-order visit of t
C D F G
print t
dfs(t.right())
Sequence: C B D A F E G
% post-order visit of t Stack:
print t
dfs(Tree t) A
if t 6= nil then
% pre-order visit of t
print t B E
dfs(t.left())
% in-order visit of t
C D F G
print t
dfs(t.right())
Sequence:
% post-order visit of t Stack: A
print t
dfs(Tree t) A
if t 6= nil then
% pre-order visit of t
print t B E
dfs(t.left())
% in-order visit of t
C D F G
print t
dfs(t.right())
Sequence:
% post-order visit of t Stack: A B
print t
dfs(Tree t) A
if t 6= nil then
% pre-order visit of t
print t B E
dfs(t.left())
% in-order visit of t
C D F G
print t
dfs(t.right())
Sequence: C
% post-order visit of t Stack: A B C
print t
dfs(Tree t) A
if t 6= nil then
% pre-order visit of t
print t B E
dfs(t.left())
% in-order visit of t
C D F G
print t
dfs(t.right())
Sequence: C
% post-order visit of t Stack: A B
print t
dfs(Tree t) A
if t 6= nil then
% pre-order visit of t
print t B E
dfs(t.left())
% in-order visit of t
C D F G
print t
dfs(t.right())
Sequence: C D
% post-order visit of t Stack: A B D
print t
dfs(Tree t) A
if t 6= nil then
% pre-order visit of t
print t B E
dfs(t.left())
% in-order visit of t
C D F G
print t
dfs(t.right())
Sequence: C D B
% post-order visit of t Stack: A B
print t
dfs(Tree t) A
if t 6= nil then
% pre-order visit of t
print t B E
dfs(t.left())
% in-order visit of t
C D F G
print t
dfs(t.right())
Sequence: C D B
% post-order visit of t Stack: A
print t
dfs(Tree t) A
if t 6= nil then
% pre-order visit of t
print t B E
dfs(t.left())
% in-order visit of t
C D F G
print t
dfs(t.right())
Sequence: C D B
% post-order visit of t Stack: A E
print t
dfs(Tree t) A
if t 6= nil then
% pre-order visit of t
print t B E
dfs(t.left())
% in-order visit of t
C D F G
print t
dfs(t.right())
Sequence: C D B F
% post-order visit of t Stack: A E F
print t
dfs(Tree t) A
if t 6= nil then
% pre-order visit of t
print t B E
dfs(t.left())
% in-order visit of t
C D F G
print t
dfs(t.right())
Sequence: C D B F
% post-order visit of t Stack: A E
print t
dfs(Tree t) A
if t 6= nil then
% pre-order visit of t
print t B E
dfs(t.left())
% in-order visit of t
C D F G
print t
dfs(t.right())
Sequence: C D B F G
% post-order visit of t Stack: A E G
print t
dfs(Tree t) A
if t 6= nil then
% pre-order visit of t
print t B E
dfs(t.left())
% in-order visit of t
C D F G
print t
dfs(t.right())
Sequence: C D B F G E
% post-order visit of t Stack: A E
print t
dfs(Tree t) A
if t 6= nil then
% pre-order visit of t
print t B E
dfs(t.left())
% in-order visit of t
C D F G
print t
dfs(t.right())
Sequence: C D B F G E A
% post-order visit of t Stack: A
print t
dfs(Tree t) A
if t 6= nil then
% pre-order visit of t
print t B E
dfs(t.left())
% in-order visit of t
C D F G
print t
dfs(t.right())
Sequence: C D B F G E A
% post-order visit of t Stack:
print t
Esempi di applicazione
int count(Tree T ) 7
if T == nil then
return 0 A
else
C` = count(T.left()) 3 3
Cr = count(T.right()) B E
return C` + Cr + 1
1 1 1 1
C D F G
Esempi di applicazione
int printExp(Tree T )
*
if T.left() == nil and T.right == nil
then
print T.read()
+ +
else
print "("
printExp(T.left())
print T.read() 4 9 3 4
printExp(T.right())
print ")" ((4+9) * (3+4))
Costo computazionale
1 Introduzione
Esempi
Definizioni
2 Alberi binari
Introduzione
Implementazione
Visite
3 Alberi generici
Visite
Implementazione
Alberi generici
Tree
% Costruisce un nuovo nodo, contenente v, senza figli o genitori
Tree(Item v)
% Legge il valore memorizzato nel nodo
Item read()
% Modifica il valore memorizzato nel nodo
write(Item v)
% Restituisce il padre, oppure nil se questo nodo è radice
Tree parent()
/** Inserts the node newChild before the existing child node refChild. */
public Node insertBefore(Node newChild, Node refChild)
/** Adds the node newChild to the end of the list of children of this node. */
public Node appendChild(Node newChild)
/** Removes the child node indicated by oldChild from the list of children. */
public Node removeChild(Node oldChild)
[...]
}
Alberto Montresor (UniTN) ASD - Strutture dati 2018/10/19 25 / 34
Alberi generici Visite
Depth-First Search
dfs(Tree t) A
if t 6= nil then
% pre-order visit of node t
print t B E
Tree u = t.leftmostChild()
while u 6= nil do
C D F G
dfs(u)
u = u.rightSibling()
Breadth-First Search
bfs(Tree t) A
Queue Q = Queue()
Q.enqueue(t)
while not Q.isEmpty() do B E
Tree u = Q.dequeue()
% visita per livelli dal nodo u
print u C D F G
u = u.leftmostChild()
while u 6= nil do Sequence:
Q.enqueue(u) Queue: A
u = u.rightSibling()
Breadth-First Search
bfs(Tree t) A
Queue Q = Queue()
Q.enqueue(t)
while not Q.isEmpty() do B E
Tree u = Q.dequeue()
% visita per livelli dal nodo u
print u C D F G
u = u.leftmostChild()
while u 6= nil do Sequence: A
Q.enqueue(u) Queue: B E
u = u.rightSibling()
Breadth-First Search
bfs(Tree t) A
Queue Q = Queue()
Q.enqueue(t)
while not Q.isEmpty() do B E
Tree u = Q.dequeue()
% visita per livelli dal nodo u
print u C D F G
u = u.leftmostChild()
while u 6= nil do Sequence: A B
Q.enqueue(u) Queue: E C D
u = u.rightSibling()
Breadth-First Search
bfs(Tree t) A
Queue Q = Queue()
Q.enqueue(t)
while not Q.isEmpty() do B E
Tree u = Q.dequeue()
% visita per livelli dal nodo u
print u C D F G
u = u.leftmostChild()
while u 6= nil do Sequence: A B E
Q.enqueue(u) Queue: C D F G
u = u.rightSibling()
Breadth-First Search
bfs(Tree t) A
Queue Q = Queue()
Q.enqueue(t)
while not Q.isEmpty() do B E
Tree u = Q.dequeue()
% visita per livelli dal nodo u
print u C D F G
u = u.leftmostChild()
while u 6= nil do Sequence: A B E C
Q.enqueue(u) Queue: D F G
u = u.rightSibling()
Breadth-First Search
bfs(Tree t) A
Queue Q = Queue()
Q.enqueue(t)
while not Q.isEmpty() do B E
Tree u = Q.dequeue()
% visita per livelli dal nodo u
print u C D F G
u = u.leftmostChild()
while u 6= nil do Sequence: A B E C D
Q.enqueue(u) Queue: F G
u = u.rightSibling()
Breadth-First Search
bfs(Tree t) A
Queue Q = Queue()
Q.enqueue(t)
while not Q.isEmpty() do B E
Tree u = Q.dequeue()
% visita per livelli dal nodo u
print u C D F G
u = u.leftmostChild()
while u 6= nil do Sequence: A B E C D F
Q.enqueue(u) Queue: G
u = u.rightSibling()
Breadth-First Search
bfs(Tree t) A
Queue Q = Queue()
Q.enqueue(t)
while not Q.isEmpty() do B E
Tree u = Q.dequeue()
% visita per livelli dal nodo u
print u C D F G
u = u.leftmostChild()
while u 6= nil do Sequence: A B E C D F G
Q.enqueue(u) Queue:
u = u.rightSibling()
Memorizzazione
P
. . .
P P P
. . . . .
P P P P P
Parent
Child Sibling
Implementazione
Tree
Tree parent % Reference al padre
Tree child % Reference al primo figlio
Tree sibling % Reference al prossimo fratello
Item value % Valore memorizzato nel nodo
Tree(Item v) % Crea un nuovo nodo
Tree t = new Tree
t.value = v
t.parent = t.child = t.sibling = nil
return t
insertChild(Tree t)
t.parent = self
t.sibling = child % Inserisce t prima dell’attuale primo figlio
child = t
insertSibling(Tree t)
t.parent = parent
t.sibling = sibling % Inserisce t prima dell’attuale prossimo fratello
sibling = t
Implementazione
Tree
deleteChild()
Tree newChild = child.rightSibling()
delete(child)
child = newChild
deleteSibling()
Tree newBrother = sibling.rightSibling()
delete(sibling)
sibling = newBrother
delete(Tree t)
Tree u = t.leftmostChild()
while u 6= nil do
Tree next = u.rightSibling()
delete(u)
u = next
1 A 0 A
2 B 1
3 E 1 B E
4 C 2
5 D 2 C D F G
6 F 3
7 G 3
DFS (https://xkcd.com/)