Argomenti della lezione
 Tipi di dato astratti
 Strutture dati elementari
• Liste
—Implementazione di liste in Java
• Stack
• Code
 Esempi di applicazione
1
Tipo di dato astratto
 Tipo di dato astratto o ADT (Abstract Data Type):
insieme di oggetti e insieme di operazioni definite su
di esso
 Es.: lista con operazioni di inserimento e
cancellazione
 Attenzione: l’ADT specifica cosa fa ogni operazione,
non come
 In Java:
 Rappresentazione con interfaccia
 Implementazione con classe
2
Liste in Java/2
 Interfaccia List
 Rappresenta una collezione ordinata di
elementi
 Ammette duplicati
 Implementazioni: classi LinkedList,
ArrayList e Vector
10
Liste in Java/3
Classe LinkedList
Classe ArrayList
 Realizza una lista
 Realizza lista mediante
doppiamente
concatenata
 Puntatori a inizio e fine
della lista
array
 Dimensione puo’ essere
variata dinamicamente.
11
Classe LinkedList
 LinkedList: realizza una lista come generica lista
doppiamente concatenata.
 Costruttore
•
LinkedList LinkedList(): costruttore
 Metodi principali:
•
•
•
•
•
•
•
•
•
void add(Object o): inserisce alla fine della lista
void addFirst(Object o): inserisce in testa alla lista
Object removeFirst(): elimina all’inizio della lista
Object removeLast(): elimina alla fine della lista
Object remove(int pos): rimuove l’oggetto in posizione pos
Object getFirst(): restituisce il primo oggetto
Object getLast(): restituisce l’ultimo oggetto
Object get(int pos): restituisce l’oggetto in posizione pos
Iterator iterator(): restituisce un Iterator sulla lista
12
Classe ArrayList
 Corrisponde all’implementazione con array
 Costruttore
• ArrayList ArrayList() : costruisce
lista vuota
 Metodi principali:
• Simili a quelli di LinkedList
• Fornisce anche metodi per la modifica
delle dimensioni dell’array
13
Iteratori
 Sono oggetti che implementano l’interfaccia
Iterator
 Servono a scorrere sequenzialmente oggetti
di tipo Collection (quindi anche liste)
 Esempio:
...
LinkedList myList = new LinkedList();
....
Iterator myIterator = myList.iterator();
14
Iteratori/2
 myIterator permette di scorrere gli elementi di
myList
 Metodi:
• Object next(): restituisce l’elemento successivo della
lista
• boolean hasNext(): vero se la lista contiene altri
elementi
• void remove(): elimina dalla lista l’elemento corrente
 E’ solamente un oggetto di ausilio per scorrere la lista
 Si può ovviamente scorrere la lista direttamente
usando gli indici
15
Classe Vector
 E’ simile ad ArrayList
 I metodi sono simili a quelli di
ArrayList
 E’ una classe sincronizzata
• E’ consigliabile usarla quando più thread
che accedono alla stessa struttura dati
16
Classe Vector/2
Array:
Classe Vector
 Possono contenere tipi
 Contiene Object. I tipi di dati
di dati primitivi
 Dimensione fissa
 Pochi metodi ma
maggiore efficienza
primitivi devono essere
convertiti mediante gli
opportuni wrapper.
 Gestione flessibile dello
spazio di memoria.
 Gran numero di metodi a
scapito dell'efficienza
17
Esempi di uso della classe Vector e
dell’interfaccia Iterator
......
Vector v = new Vector();
String st = br.readLine(); // br BufferedReader
while (st != null) {
v.addElement(st);
st = br.readLine();
}
System.out.println();
Iterator it = v.iterator();
while (it.hasNext())
System.out.println(it.next());
......
18
Vector di tipi di dato primitivi
.......
Vector v = new Vector();
String st = br.readLine(); // br BufferedReader
while (st != null) {
int num = Integer.parseInt(st);
v.addElement(new Integer(num));
st = br.readLine();
}
System.out.println();
Iterator it = v.iterator();
while (it.hasNext())
System.out.println(it.next());
........
19
Tipo astratto Pila
 Lista nella quale inserimenti e cancellazioni avvengono solo in testa
(disciplina LIFO).
 Operazioni sempre presenti
•
push(el): inserisce l'elemento specificato da el in cima alla pila
•
pop(): elimina l'elemento in cima alla pila
•
top(): restituisce l'elemento in cima alla pila senza cancellarlo dalla
lista
•
isEmpty(): verifica se la pila è vuota
 Altre operazioni
•
clear(): elimina tutti gli elementi dalla pila
20
Implementazione del tipo Pila
 Realizzazione tramite Array
Ai
top = i
A1
A0
 Liste: realizzazione tramite lista concatenata
top
Start
A0
A1
Ai
AN
21
Implementazione Java con Vector
public Object topEl(){
return
pool.lastElement();
}
public Object pop(){
return
pool.remove(pool.size()-1);
}
public void push(Object el){
pool.addElement(el);
}
public class Stack {
private java.util.Vector
pool=
new java.util.Vector();
public Stack(){
}
public Stack(int n){
pool.ensureCapacity(n)
}
public void clear(){
pool.clear();
}
public boolean isEmpty(){
return pool.isEmpty();
}
}
22
Implementazione tramite LinkedList
public class LLStack {
private list= new
java.util.LinkedList();
public LLStack(){
}
public void clear(){
list.clear();
}
public boolean isEmpty(){
return list.isEmpty();
}
public Object topEl(){
return list.getLast();
}
public Object pop(){
return list.removeLast();
}
public void push(Object el){
list.add(el);
}
public String toString(){
return list.toString();
}
}
Attenzione: java.util.Stack
non realizza una vera pila (ci
sono operazioni in più)
23
Tipo astratto coda
 Lista nella quale gli inserimenti avvengono in coda e
le cancellazioni (estrazioni) in testa (disciplina FIFO)
 Operazioni sempre presenti
• isEmpty(): verifica se la coda è vuota
• enqueue(el): inserisce l'elemento specificato
da el alla fine della coda
• dequeue(): elimina il primo elemento della coda
• firstEl(): restituisce il primo elemento della
coda senza eliminarlo
 Altre operazioni
• clear(): elimina tutti gli elementi dalla coda
25
Implementazione di code con array
A0
A1
A2
AN-3 AN-2 AN-1
testa
coda
Elemento non usato
enqueue -> coda = coda + 1 (mod N)
dequeue -> testa = testa + 1 (mod N)
Se (coda == testa – 1 mod N) coda piena
Se (coda == testa) coda vuota (un solo elemento
presente)
26
Implementazione di coda con
Array circolare
 first:
 last:
 size:
indice del primo elemento - testa
indice dell'ultimo - coda
numero di elementi dell'array
public class ArrayQueue {
private int first, last, size;
private Object[] storage;
private static final int DEFAULTSIZE = 100;
// metodi nella prossima slide
27
Implementazione di coda con
Array circolare/2
public ArrayQueue(){
this(DEFAULTSIZE);
}
public ArrayQueue(int n){
size = n;
storage = new Object[size];
first = last = -1;
}
public boolean isFull(){
return ((first == 0) && (last == size - 1)) ||
(first == last + 1);
}
public boolean isEmpty(){
return first == -1;
}
Algoritmi e strutture dati
28
Implementazione di coda con
Array circolare/3
public void enqueue(Object el){
if(!isFull())
if ((last == size - 1) || (last == -1)) {
storage[0] = el; last = 0;
if (first == -1) //caso coda vuota
first=0;
} else storage[++last] = el;
}
29
Implementazione di coda con
Array circolare/4
public Object dequeue(){
Object tmp = null;
if(!isEmpty()) {
tmp = storage[first];
if (first == last) // caso unico elemento
last = first = -1;
else if (first == size - 1)
first = 0;
else first++;
}
return tmp; // Restituisce null se coda vuota
}
30
Implementazione di coda con
Array circolare/5
public void printAll(){
if(isEmtpy())
System.out.println("Coda vuota.");
else {
int i = first;
do {
System.out.print(storage[i] + " ");
i = (i + 1) % size;
} while(i != ((last + 1) % size));
System.out.println();
}
}
} // fine classe ArrayQueue
31
Implementazione di una coda
con lista concatenata
public class QueueNode {
protected Object info;
protected QueueNode next = null;
public QueueNode(Object el) {
info = el;
}
}
public class Queue {
private QueueNode head, tail;
public Queue() {
head = tail = null;
}
32
Implementazione di una coda
con lista concatenata/2
public boolean isEmpty() {
return head == null;
}
public void clear() {
head = tail = null;
}
public Object firstEl() {
return head.info;
}
33
Implementazione di una coda
con lista concatenata/3
public void enqueue(Object el) {
QueueNode q = new QueueNode(el);
if (!isEmpty()) {
tail.next = q;
tail = tail.next;
} else head = tail = q;
34
Implementazione di una coda
con lista concatenata/4
public Object dequeue() {// cancella il nodo in
// testa e restituisce il campo info
if (!isEmpty()) {
Object el = head.info;
if (head == tail) // un solo nodo?
head = tail = null;
else head = head.next;
return el;
} else return null;
} // fine metodo dequeue
} // fine classe Queue
35
Riconoscimento di stringhe
parenteticamente corrette
 La stringa vuota è parenteticamente corretta
 Se P1, P2 e P3 sono corrette, allora lo è anche
P1(P2)P3, P1[P2]P3 o P1{P2}P3
 Es.:
• ab(ax)[(b)du{(mb)}] è corretta
• a(ax)[c e a){b(e} non sono corrette
36
Algoritmo (solo un tipo di parentesi)
Algorithm stringAnalyzer
balanced = true;
S = <Leggi la stringa>
c = <primo carattere di S>
count = 0;
while ((! <fine di S>) && (count
>= 0)) {
if (c == ‘(’)
count++;
else if (c == ‘)’)
count--;
c = <prossimo carattere di
S>
}
if ((fine di S) && (count != 0))
balanced = false;
Provare a implementare
il riconoscimento con
parentesi di
qualunque tipo.
Es.:
- fg{([{ab(vc)g}kj])} è
corretta
- gh{(df[ghj]}gh)hj non
è corretta
37
Algoritmo (caso generale)
 Usa uno stack
 Se arriva ‘(‘, ‘[‘ o ‘{‘
inseriscila nello stack
 Se arriva ‘)‘, ‘]‘ o ‘}‘
confrontala con l’elemento
affiorante
• Se non corrispondono allora la
)
(
]
[
(
stringa non è bilanciata
 Se si esamina la stringa fino
alla fine e lo stack non è
vuoto la stringa non è
bilanciata. Es.: (((er[])
38
Scarica

ppt