Capitolo 18 - Dipartimento di Informatica

Capitolo 18: Strutture di dati avanzate
Capitolo 18
Strutture di dati avanzate
©2002 Apogeo
Horstmann-Concetti di informatica e fondamenti di Java 2
1
Capitolo 18: Strutture di dati avanzate
Figura 1
Un insieme
di stampanti
©2002 Apogeo
Horstmann-Concetti di informatica e fondamenti di Java 2
2
Capitolo 18: Strutture di dati avanzate
Figura 2
Classi
e interfacce
per gli insiemi
nella libreria
standard
©2002 Apogeo
Horstmann-Concetti di informatica e fondamenti di Java 2
3
Capitolo 18: Strutture di dati avanzate
File SetTest.java
import
import
import
import
java.util.HashSet;
java.util.Iterator;
java.util.Set;
javax.swing.JoptionPane;
/**
Programma che illustra il funzionamento di un insieme di
stringhe.
L'utente può inserire e rimuovere stringhe.
*/
public class SetTest
{
public static void main(String[] args)
{
Set names = new HashSet();
boolean done = false;
while (!done)
{
©2002 Apogeo
Horstmann-Concetti di informatica e fondamenti di Java 2
4
Capitolo 18: Strutture di dati avanzate
String input = JoptionPane.showInputDialog(
"Add name, Cancel when done");
if (input == null)
done = true;
else
{
names.add(input);
print(names);
}
}
done = false;
while (!done)
{
String input = JoptionPane.showInputDialog(
"Remove name, Cancel when done");
if (input == null)
done = true;
else
{
names.remove(input);
print(names);
©2002 Apogeo
Horstmann-Concetti di informatica e fondamenti di Java 2
5
Capitolo 18: Strutture di dati avanzate
}
}
System.exit(0);
}
/**
Stampa il contenuto di un insieme.
@param s un insieme
*/
private static void print(Set s)
{
Iterator iter = s.iterator();
System.out.print("{ ");
while (iter.hasNext())
{
System.out.print(iter.next());
System.out.print(" ");
}
System.out.println("}");
}
}
©2002 Apogeo
Horstmann-Concetti di informatica e fondamenti di Java 2
6
Capitolo 18: Strutture di dati avanzate
Figura 3 Una mappa
©2002 Apogeo
Horstmann-Concetti di informatica e fondamenti di Java 2
7
Capitolo 18: Strutture di dati avanzate
Figura 4
Classi
e interfacce
per le mappe
nella libreria
standard
©2002 Apogeo
Horstmann-Concetti di informatica e fondamenti di Java 2
8
Capitolo 18: Strutture di dati avanzate
File MapTest.java
import
import
import
import
import
java.awt.Color;
java.util.HashMap;
java.util.Iterator;
java.util.Map;
java.util.Set;
/**
Questo programma collauda una mappa che associa nomi a colori.
*/
public class MapTest
{
public static void main(String[] args)
{
Map favoriteColors = new HashMap();
favoriteColors.put("Juliet", Color.pink);
favoriteColors.put("Romeo", Color.green);
favoriteColors.put("Adam", Color.blue);
favoriteColors.put("Eve", Color.pink);
print(favoriteColors);
}
©2002 Apogeo
Horstmann-Concetti di informatica e fondamenti di Java 2
9
Capitolo 18: Strutture di dati avanzate
/**
Stampa i contenuti di una mappa.
@param m una mappa
*/
private static void print(Map m)
{
Set keySet = m.keySet();
Iterator iter = keySet.iterator();
while (iter.hasNext())
{
Object key = iter.next();
Object value = m.get(key);
System.out.println(key + "->" + value);
}
}
}
©2002 Apogeo
Horstmann-Concetti di informatica e fondamenti di Java 2
10
Capitolo 18: Strutture di dati avanzate
Figura 5
Una realizzazione molto
semplice di tabella hash
©2002 Apogeo
Horstmann-Concetti di informatica e fondamenti di Java 2
11
Capitolo 18: Strutture di dati avanzate
Figura 6
Una tabella hash con liste concatenate per memorizzare elementi
aventi lo stesso codice hash
©2002 Apogeo
Horstmann-Concetti di informatica e fondamenti di Java 2
12
Capitolo 18: Strutture di dati avanzate
File HashSet.java
import java.util.Iterator;
import java.util.AbstractSet;
/**
Un HashSet memorizza una raccolta non ordinata di oggetti
usando una tabella di hash.
*/
public class HashSet extends AbstractSet
{
/**
Costruisce una tabella di hash.
@param bucketsLength la lunghezza dell’array buckets
*/
public HashSet(int bucketsLength)
{
buckets = new Link[bucketsLength];
size = 0;
}
©2002 Apogeo
Horstmann-Concetti di informatica e fondamenti di Java 2
13
Capitolo 18: Strutture di dati avanzate
/**
Verifica l’appartenenza all’insieme.
@param x un oggetto
@return true se x è un elemento dell’insieme
*/
public boolean contains(Object x)
{
int h = x.hashCode();
if (h < 0) h = -h;
h = h % buckets.length;
Link current = buckets[h];
while (current != null)
{
if (current.data.equals(x)) return true;
current = current.next;
}
return false;
}
©2002 Apogeo
Horstmann-Concetti di informatica e fondamenti di Java 2
14
Capitolo 18: Strutture di dati avanzate
/**
Inserisce un elemento all’insieme.
@param x un oggetto
@return true se x è un oggetto nuovo, false se x era gia'
presente nell'insieme
*/
public boolean add(Object x)
{
int h = x.hashCode();
if (h < 0) h = -h;
h = h % buckets.length;
Link current = buckets[h];
while (current != null)
{
if (current.data.equals(x))
return false; // gia' nell'insieme
current = current.next;
}
©2002 Apogeo
Horstmann-Concetti di informatica e fondamenti di Java 2
15
Capitolo 18: Strutture di dati avanzate
Link newLink
newLink.data
newLink.next
buckets[h] =
size++;
return true;
= new Link();
= x;
= buckets[h];
newLink;
}
/**
Elimina un oggetto dall'insieme.
@param x un oggetto
@return true se x viene eliminato dall’insieme,
false se x non e' presente nell'insieme
*/
public boolean remove(Object x)
{
int h = x.hashCode();
if (h < 0) h = -h;
h = h % buckets.length;
©2002 Apogeo
Horstmann-Concetti di informatica e fondamenti di Java 2
16
Capitolo 18: Strutture di dati avanzate
Link current = buckets[h];
Link previous = null;
while (current != null)
{
if (current.data.equals(x))
{
if (previous == null)
buckets[h] = current.next;
else previous.next = current.next;
size--;
return true;
}
previous = current;
current = current.next;
}
return false;
}
©2002 Apogeo
Horstmann-Concetti di informatica e fondamenti di Java 2
17
Capitolo 18: Strutture di dati avanzate
/**
Restituisce il numero di elementi nell'insieme.
@return il numero di elementi
*/
public int size()
{
return size;
}
private Link[] buckets;
private int size;
private class Link
{
public Object data;
public Link next;
}
private class HashSetIterator implements Iterator
{
©2002 Apogeo
Horstmann-Concetti di informatica e fondamenti di Java 2
18
Capitolo 18: Strutture di dati avanzate
/**
Costruisce un iteratore per insiemi hash che punta
al primo elemento dell'insieme.
*/
public HashSetIterator()
{
bucket = 0;
previous = null;
previousBucket = buckets.length;
// imposta bucket all'indice del primo bucket non
vuoto
while (bucket < buckets.length
&& buckets[bucket] == null)
bucket++;
if (bucket < buckets.length)
current = buckets[bucket];
else current = null;
}
©2002 Apogeo
Horstmann-Concetti di informatica e fondamenti di Java 2
19
Capitolo 18: Strutture di dati avanzate
public Object next()
{
Object r = current.data;
if (current.next == null) // avanza al prossimo bucket
{
previousBucket = bucket;
bucket++;
while (bucket < buckets.length
&& buckets[bucket] == null)
bucket++;
if (bucket < buckets.length)
current = buckets[bucket];
else current = null;
}
else // avanza al prossimo elemento in bucket
{
previous = current;
current = current.next;
}
©2002 Apogeo
Horstmann-Concetti di informatica e fondamenti di Java 2
20
Capitolo 18: Strutture di dati avanzate
return r;
}
public void remove()
{
if (previous != null)
previous.next = previous.next.next;
else if (previousBucket < buckets.length)
buckets[previousBucket] = null;
else
throw new IllegalStateException();
previous = null;
previousBucket = buckets.length;
}
private int bucket;
private Link current;
private int previousBucket;
private Link previous;
}
}
©2002 Apogeo
Horstmann-Concetti di informatica e fondamenti di Java 2
21
Capitolo 18: Strutture di dati avanzate
File SetTest.java
import java.util.Iterator;
import java.util.Set;
/**
Questo programma collauda la classe insieme realizzata con
tabella hash.
*/
public class SetTest
{
public static void main(String[] args)
{
Set names = new HashSet(101); // 101 e' un numero primo
names.add("Sue");
names.add("Harry");
names.add("Nina");
names.add("Susannah");
names.add("Larry");
names.add("Eve");
names.add("Sarah"
©2002 Apogeo
Horstmann-Concetti di informatica e fondamenti di Java 2
22
Capitolo 18: Strutture di dati avanzate
names.add("Adam");
names.add("Tony");
names.add("Katherine");
names.add("Juliet");
names.add("Romeo");
names.remove("Romeo");
names.remove("George");
Iterator iter = names.iterator();
while (iter.hasNext())
System.out.println(iter.next());
}
}
©2002 Apogeo
Horstmann-Concetti di informatica e fondamenti di Java 2
23
Capitolo 18: Strutture di dati avanzate
File Coin.java
/**
Una moneta con un valore monetario.
*/
public class Coin
{
/**
Costruisce una moneta.
@param aValue il valore monetario della moneta
@param aName il nome della moneta
*/
public Coin(double aValue, String aName)
{
value = aValue;
name = aName;
}
/**
Restituisce il valore della moneta.
@return il valore
©2002 Apogeo
Horstmann-Concetti di informatica e fondamenti di Java 2
24
*/
public double getValue()
{
return value;
}
Capitolo 18: Strutture di dati avanzate
/**
Restituisce il nome della moneta.
@return il nome
*/
public String getName()
{
return name;
}
public boolean equals(Object otherObject)
{
if (otherObject == null) return false;
if (getClass() != otherObject.getClass())
return false;
Coin other = (Coin)otherObject;
return (value == other.value
&& name.equals(other.name));
}
©2002 Apogeo
Horstmann-Concetti di informatica e fondamenti di Java 2
25
Capitolo 18: Strutture di dati avanzate
public int hashCode()
{
int h1 = name.hashCode();
int h2 = new Double(value).hashCode();
final int HASH_MULTIPLIER = 29;
int h = HASH_MULTIPLIER * h1 + h2;
return h;
}
public String toString()
{
return "Coin[value=" + value + ",name=" + name + "]";
}
private double value;
private String name;
}
©2002 Apogeo
Horstmann-Concetti di informatica e fondamenti di Java 2
26
File HashCodeTest.java
Capitolo 18: Strutture di dati avanzate
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
/**
Un programma per collaudare i codici di hash delle monete.
*/
public class HashCodeTest
{
public static void main(String[] args)
{
Coin coin1 = new Coin(0.25, "quarter");
Coin coin2 = new Coin(0.25, "quarter");
Coin coin3 = new Coin(0.05, "nickel");
System.out.println("hash code of coin1="
+ coin1.hashCode());
System.out.println("hash code of coin2="
+ coin2.hashCode());
System.out.println("hash code of coin3="
+ coin3.hashCode());
©2002 Apogeo
Horstmann-Concetti di informatica e fondamenti di Java 2
27
Capitolo 18: Strutture di dati avanzate
Set coins = new HashSet();
coins.add(coin1);
coins.add(coin2);
coins.add(coin3);
Iterator iter = coins.iterator();
while (iter.hasNext())
System.out.println(iter.next());
}
}
©2002 Apogeo
Horstmann-Concetti di informatica e fondamenti di Java 2
28
Capitolo 18: Strutture di dati avanzate
Figura 7
Un albero
di ricerca binario
©2002 Apogeo
Horstmann-Concetti di informatica e fondamenti di Java 2
29
Capitolo 18: Strutture di dati avanzate
Figura 8
Un albero binario
che non è un albero
di ricerca binario
©2002 Apogeo
Horstmann-Concetti di informatica e fondamenti di Java 2
30
Capitolo 18: Strutture di dati avanzate
Figura 9
Un albero
di ricerca
binario dopo
quattro
inserimenti
©2002 Apogeo
Horstmann-Concetti di informatica e fondamenti di Java 2
31
Capitolo 18: Strutture di dati avanzate
Figura 10
Un albero
di ricerca
binario
dopo
cinque
inserimenti
©2002 Apogeo
Horstmann-Concetti di informatica e fondamenti di Java 2
32
Capitolo 18: Strutture di dati avanzate
File TreeTest.java
/**
Questo programma collauda una classe che realizza
un albero di ricerca binario.
*/
public class TreeTest
{
public static void main(String[] args)
{
Tree names = new Tree();
names.insert("Romeo");
names.insert("Juliet");
names.insert("Tom");
names.insert("Dick");
names.insert("Harry");
names.print();
}
}
©2002 Apogeo
Horstmann-Concetti di informatica e fondamenti di Java 2
33
Capitolo 18: Strutture di dati avanzate
Figura 11
Un albero di ricerca
binario sbilanciato
©2002 Apogeo
34
Capitolo 18: Strutture di dati avanzate
File Tree.java
/**
Questa classe implementa un albero di ricerca binario i cui
nodi contengono oggetti che implementano l’interfaccia
Comparable.
*/
public class Tree
{
/**
Costruisce un albero vuoto.
*/
public Tree()
{
root = null;
}
/**
Inserisce un nuovo nodo nell’albero.
@param obj l'oggetto da inserire
*/
©2002 Apogeo
Horstmann-Concetti di informatica e fondamenti di Java 2
35
Capitolo 18: Strutture di dati avanzate
public void insert(Comparable obj)
{
Node newNode = new Node();
newNode.data = obj;
newNode.left = null;
newNode.right = null;
if (root == null) root = newNode;
else root.insertNode(newNode);
}
/**
Stampa il contenuto dell’albero in successione ordinata.
*/
public void print()
{
if (root != null)
root.printNodes();
}
©2002 Apogeo
Horstmann-Concetti di informatica e fondamenti di Java 2
36
Capitolo 18: Strutture di dati avanzate
private Node root;
/**
Un nodo di un albero conserva un dato e i riferimenti
ai nodi figlio sinistro e figlio destro.
*/
private class Node
{
/**
Inserisce un nuovo nodo come discendente di questo nodo.
@param newNode il nodo da inserire
*/
public void insertNode(Node newNode)
{
if (newNode.data.compareTo(data) < 0)
{
if (left == null) left = newNode;
else left.insertNode(newNode);
}
©2002 Apogeo
Horstmann-Concetti di informatica e fondamenti di Java 2
37
Capitolo 18: Strutture di dati avanzate
else if (newNode.date.compareTo (data) > 0)
{
if (right == null) right = newNode;
else right.insertNode(newNode);
}
}
/**
Stampa questo nodo e tutti i suoi discendenti
in successione ordinata.
*/
public void printNodes()
{
if (left != null)
left.printNodes();
System.out.println(data);
if (right != null)
right.printNodes();
}
public Comparable data;
public Node left;
public Node right;
}
}
©2002 Apogeo
38
Capitolo 18: Strutture di dati avanzate
File TreeSetTest.java
import
import
import
import
java.util.Comparator;
java.util.Iterator;
java.util.Set;
java.util.TreeSet;
/**
Un programma per collaudare un insieme ad albero.
*/
public class TreeSetTest
{
public static void main(String[] args)
{
Coin coin1 = new Coin(0.25, "quarter");
Coin coin2 = new Coin(0.25, "quarter");
Coin coin3 = new Coin(0.25, "penny");
Coin coin4 = new Coin(0.25, "nickel");
©2002 Apogeo
Horstmann-Concetti di informatica e fondamenti di Java 2
39
Capitolo 18: Strutture di dati avanzate
class CoinComparator implements Comparator
{
public int compare(Object firstObject,
Object secondObject)
{
Coin first = (Coin)firstObject;
Coin second = (Coin)secondObject;
if (first.getValue() < second.getValue())
return –1;
if (first.getValue() == second.getValue())
return 0;
return 1;
}
}
©2002 Apogeo
Horstmann-Concetti di informatica e fondamenti di Java 2
40
Capitolo 18: Strutture di dati avanzate
Comparator comp = new CoinComparator();
Set coins = new TreeSet(comp);
coins.add(coin1);
coins.add(coin2);
coins.add(coin3);
coins.add(coin4);
Iterator iter = coins.iterator();
while (iter.hasNext())
System.out.println(iter.next());
}
}
©2002 Apogeo
Horstmann-Concetti di informatica e fondamenti di Java 2
41