strutture dati elementari - eziobartocci.com · strutture dati e algoritmi ... strutture dati...
TRANSCRIPT
Strutture dati elementari
Dott. Ezio Bartocci, Dott. Francesco De Angelis
Laboratorio di Algoritmi e strutture Dati - AA 2006/2007
Dip. di Matematica e InformaticaUniversità di Camerino
[email protected], [email protected]
24 novembre 2006
IntroduzioneCostrutti di base
ArrayListe concatenate
Strutture dati e algoritmi
La decisione più importante nella fase di implementazione diun’applicazione è la scelta della struttura più oppurtuna perrappresentare i dati.
Per uno stesso insieme di dati, vi sono strutture dati cherichiedono più spazio di altre.
Per uno stesso insieme di operazioni sui dati, alcune strutturedati portano a implementare algoritmi più efficienti di altri.
2 / 36
IntroduzioneCostrutti di base
ArrayListe concatenate
Costrutti di base
Tutti i dati che vengono elaborati su un calcolatore alla fine sonoscomposti in singoli bit, ma scrivere programmi che elaborinodirettamente questi bit sarebbe quantomeno noioso.
I tipi ci consentono di specificare come andremo a usare unparticolare insieme di bit, mentre i metodi permettono di definirele operazioni che verranno eseguite sui dati.
Usiamo le classi di Java per descrivere le informazioni cheelaboriamo, per definire i metodi che agiscono su questeinformazioni e per costruire oggetti che le memorizzanoeffettivamente.
3 / 36
IntroduzioneCostrutti di base
ArrayListe concatenate
Strutture dati
Le stutture dati che andremo a vedere sono formate da oggetti eda riferimenti a oggetti.
Quando scriviamo programmi, di solito vogliamo elaborareinformazioni derivanti da qualche descrizione formale(matematica) o informale del mondo in cui viviamo.
Gli ambienti di programmazione devono già avere in sè glielementi di base di queste descrizioni, vale a dire numeri ecaratteri.
4 / 36
IntroduzioneCostrutti di base
ArrayListe concatenate
Strutture dati semplici
Tipi di dati primitivi in Java
boolean - valori booleani
char - caratteri
byte - numeri interi a 8 bit
short - numeri interi a 16 bit
int - numeri interi a 32 bit
long - numeri interi a 64 bit
float - numeri in virgola mobile a 32 bit
double - numeri in virgola mobile a 64 bit
5 / 36
IntroduzioneCostrutti di base
ArrayListe concatenate
Tipi di dati standard
DefinitionUn tipo di dato è definito da un insieme di valori e da una collezionedi operazioni su questi valori.
Le operazioni sono associate ai tipi e non viceversa.
Quando eseguiamo un operazione, dobbiamo assicurare chetanto gli operandi quanto il risultato siano del tipo corretto.
In alcuni casi, Java esegue conversioni in modo automatico; inaltri usiamo il cast, cioè l’esplicita conversione di tipo. Adesempio, se x ed N sono interi, questa espressione includeentrambi i tipi di conversione: ((float) x) / N
6 / 36
IntroduzioneCostrutti di base
ArrayListe concatenate
Operazioni sui tipi di dati standard
Molte delle operazioni associate ai tipi di dati standard (i.e. leoperazioni aritmetiche) sono già in effetti incorporate nellinguaggio Java, altre operazioni sono implementate sotto formadi metodi in librerie standard di Java, altre ancora sono costituitedai metodi Java definiti nei programmi che scriviamo.
Spesso abbiamo bisogno di definire i nostri tipi di dati perorganizzare i programmi in maniera efficace.
7 / 36
IntroduzioneCostrutti di base
ArrayListe concatenate
Classi
Esempio di classe
class Studente{private String nome;private String cognome;private int anno;private int matricola;//CostruttoreStudente(String nome,
String cognome,int anno, int matricola){
this.nome = nome;this.cognome = cognome;this.anno = anno;this.matricola = matricola;
}int getMatricola(){ return matricola;}int getAnno(){ return anno; }public String toString(){
return nome + " " + cognome;}
}
Tutti i programmi in Java sono basatisul meccanismo delle classi.
La classe definisce tutte le proprietàdegli oggetti appartenenti a quellaclasse, detti attributi, e le funzioniche verranno usate per agire su diessi, detti metodi.
Le classi sono dei prototipi di oggetti,ovvero sono delle strutture astratteche possono essere instanziatecreando uno o più oggetti.
8 / 36
IntroduzioneCostrutti di base
ArrayListe concatenate
Programmazione object-oriented
Possiamo pensare alle classi come a un meccanismo che ciconsente non solo di aggregare dati, ma anche di definireoperazioni su quei dati.
Anche se ci sono diversi oggetti che appartengono a una classe,tutti questi oggetti sono simili nel senso che i valori assumibili dailoro dati membro sono gli stessi e che l’insieme delle operazioniche possono essere eseguite sui dati membro è lo stesso.
Nella programmazione object-oriented sono gli oggetti cheelaborano i loro dati membro (invece di avere metodi liberi cheagiscono sui dati memorizzati negli oggetti)
9 / 36
IntroduzioneCostrutti di base
ArrayListe concatenate
Classi e metodi
Definizione di un metodo
class LogTable{static int lg (int N){for (int i=0; N > 0; i++){ N/=2;}return i;
}public static void main (String[] args){for (int N=100; N < 10000; N*=10)
Out.println(lg(N) + " " + N);}
}
Programma Java più semplice
class HelloWorld{public static void main (String[] args){System.out.println("Hello World !!"); }
}
In Java, per implementare nuoveoperazioni sui dati, definiamo metodi inclassi.
Il metodo lg nell’esempio implementauna funzione matematica a un soloargomento che corrisponde al logaritmointero in base 2.
In Java, gli argomenti vengono dettiparametri e il valore della funzione èchiamato valore di ritorno.
Ogni programma Java è una classe cheinclude la definizione del metodo main. Ilprogramma Java più semplice che sipossa scrivere è quello formato dal solometodo main.
10 / 36
IntroduzioneCostrutti di base
ArrayListe concatenate
Polimorfismo
Overloading degli operatori
class ValoreAssoluto{
static int abs(int value){return value >= 0 ? value : -value;
}
static double abs(double value){return value >= 0 ? value : -value;
}}
La definizione di un metodo iniziacon la sua segnatura, che definisceil tipo del suo valore di ritorno, il suonome e i tipi dei suoi parametri.
L’uso di nomi identici per metodidifferenti si dice overloading, se ilsistema è in grado di distinguerlitramite le differenze nelle lorosegnature.
I tipi dei parametri e la presenza ol’assenza di un valore di ritornopossono servire a distinguere traloro metodi aventi lo stesso nome.
11 / 36
IntroduzioneCostrutti di base
ArrayListe concatenate
Ereditarietà
Classe Punto
class Point{double x, y;Point {x = Math.random();y = Math.random();
}}
Classe punto etichettato
class LabeledPoint extends Point{String id;void label(String name){id = name;}public String toString(){
return id + "(" + x + ", " + y + ")";}}
Spesso ci troviamo a dover costruire unnuovo tipo di dato arricchendone uno giàesistente.
Per agevolare questo tipico compito Javaoffre la possibilità di definire una classeche ne estende un’altra.
Il tipo di dato definito dalla classe estesaè determinato dai membri della classebase più tutti i membri della classeestesa.
La classe estesa può tanto definire nuovimembri quanto ridefinire membri dellaclasse base.
12 / 36
IntroduzioneCostrutti di base
ArrayListe concatenate
Array
DefinitionUn array è un insieme fissato di elementi dello stesso tipo memorizzatiin modo contiguo e accessibili per mezzo di un indice.
L’Array in Java come nella maggiorparte dei linguaggi diprogrammazione è definito come primitiva di linguaggio.
Denoteremo l’i-esimo elemento di un array a con a[i].
13 / 36
IntroduzioneCostrutti di base
ArrayListe concatenate
Operare su un Array
Crivello di Eratostene
class Primes{public static void main(String[] args){int N = Integer.parseInt(arg[0]);int[] a = new int[N];for (int i=2; i < N; i++) a[i]= 1;for (int i=2; i < N; i++)if (a[i] != false)
for (int j=i; j*i < N; j++)a[i*j] = 0;
for (int i=2; i < N; i++)if (i > N - 100)
if (a[i]) Out.print(" " + i);Out.println();
}}
Examplei 2 3 5 a[i]2 1 13 1 14 1 05 1 16 1 07 1 18 1 09 1 010 1 011 1 112 1 0 0
14 / 36
IntroduzioneCostrutti di base
ArrayListe concatenate
Allocazione affidabile di un array
Example
int[] a;try {
a = new int[N];}catch (OutOfMemoryError e){
Out.println("Out of memory"); return;}}
Se nel programma precedentedigitassimo come argomento sullariga di comando un numeroestremamente grande, siprodurrebbe nel sistemaun’eccezione OutOfMemoryError(mancanza di memoria)
E’ buona pratica di programmazionetenere sotto controllo tutti gli erroriche possono capitare.
Quindi potrebbe essere utilesostituire le righe del codice checreano l’array di interi con il codicequi a fianco.
15 / 36
IntroduzioneCostrutti di base
ArrayListe concatenate
Array di Oggetti
Array di oggetti Points
class ClosePoints{public static void main (String[] args){
int cnt = 0;N = Integer.parseInt(args[0]);double d = Double.parseDouble(args[1]);Point[] a = new Point[N];for (int i = 0; i < N; i++)
a[i] = new Point();for (int i = 0; i < N; j++)
if (a[i].distance(a[j]) < d) cnt++;Out.print(cnt + " pairs " );Out.println(" closer than " + d);
}
012
34
5
6
1.7 1.0
3.5 2.0
2.3 6.7
2.0 6.1
5.0 4.0
6.1 3.9
1.4 3.2
In Java, un array di oggetti è, in realtà, unarray di riferimenti a oggetti, comemostrato dalla figura qui sopra
16 / 36
IntroduzioneCostrutti di base
ArrayListe concatenate
Lista concatenata
Quando abbiamo necessità di scandire una collezione di elementiin modo sequenziale, uno dopo l’altro, una scelta conveniente èquella di organizzare gli elementi in una lista concatenata.
In una lista concatenata, ogni elemento contiene le informazioninecessarie per accedere all’elemento successivo.
Vantaggi rispetto all’Array
Flessibilità di modifica
Svantaggi rispetto all’Array
Onerosità nell’accesso ai suoi elementi: l’unico modo per raggiungere un dato elementodella lista è quello di seguire le connessioni della lista dall’inizio
17 / 36
IntroduzioneCostrutti di base
ArrayListe concatenate
Definizione
DefinitionUna lista concatenata è un insieme di elementi, dove ogni elementoè inserito in un nodo contenente anche un link (cioè una connessioneo riferimento) a un (altro) nodo.
Le liste sono dette a volte strutture autoreferenzianti proprio peraver definito i nodi in termini di riferimenti ad altri nodi.
Sebbene di solito i link di un nodo puntino ad altri nodi, tali linkpotrebbero anche puntare al nodo medesimo, e quindi dar luogoa strutture circolari.
18 / 36
IntroduzioneCostrutti di base
ArrayListe concatenate
Vediamo in Java
Classe Node
class Node{Object item;Node next;Node(Object v) {item = v;next = null;
}}
Instanziare una lista di 2 nodi
//x is an ObjectNode t = new Node(x);
Adotteremo queste convenzioniper il link del nodo finale:
è un link nullo che non porta ad alcunnodo
punta ad un nodo fittizio che noncontiene alcun elemento
punta indietro al primo nodo della lista,creando quindi una lista circolare
punta indietro al primo nodo della lista,creando quindi una lista circolare.
19 / 36
IntroduzioneCostrutti di base
ArrayListe concatenate
Cancellazione e Inserimento in una lista
Cancellazione
t = x.next;x.next = t.next;//oppure x.next = x.next.next;
x
t
x
t
Inserimento
t.next = x.next; x.next = t;
t
x
t
x
t
x
20 / 36
IntroduzioneCostrutti di base
ArrayListe concatenate
Esempio di lista circolare
Problema di Giuseppe Flavio
class Node {int val; Node next;Node (int v){ val = v;}
}class Josephus{public static void main (String args[]){int N = Integer.parseInt(args[0]);int M = Integer.parseInt(args[1]);Node t = new Node(1);Node x = t;for (int i = 2; i <= N; i++){
x = (x.next = new Node(i));x.next = t;while (x != x.next){
for (int i = 1; i < M; i++)x = x.next;
x.next = x.next.next;}Out.println("L’eletto è " + x.val);
}}
Immaginiamo che N persone debbanoeleggere un leader nel modo seguente
le persone si dispongono in cerchio
eliminano una persona ogni M,seguendo l’ordine del cerchio erichiudendo il cerchio ad ognieliminazione.
Il problema è quello di scoprirequale persona rimarrà per ultima.
21 / 36
IntroduzioneCostrutti di base
ArrayListe concatenate
Risultato dell’elezione di Giuseppe Flavio
21
34
5
67 8
9
2
1
34
6
78
9
234
67
8
9
23
4
68
9
2
36
8 9
26
8 9
28
9
28 8
22 / 36
IntroduzioneCostrutti di base
ArrayListe concatenate
Definizione più restrittiva
DefinitionUna lista concatenata consta di un link nullo oppure di un link ad unnodo, che contiene un elemento e un link a una lista concatenata.
Questa definizione è più restrittiva di quella precedente, macorrisponde in modo più preciso all’idea che abbiamo di una listaquando scriviamo codice per elaborarla.
23 / 36
IntroduzioneCostrutti di base
ArrayListe concatenate
Attraversamento di una lista
Codice per attraversare una lista
for (Node t = x; t != null; t = t.next)visit(t.item);
Una delle più comuni operazioni su listeè quella dell’attraversamento: scandiamotutti gli elementi della lista in manierasequenziale, eseguendo una qualcheoperazione su ognuno dei nodi
Ad esempio, se xreferenzia il primo nododi una lista, l’ultimo nodo ha il link aNULLe visitè un metodo che prendeun elemento come parametro, possiamoscrivere il codice riportato qui a fianco
24 / 36
IntroduzioneCostrutti di base
ArrayListe concatenate
Inversione di un lista
Metodo Reverse
Node reverse (Node x){Node t, y = x, r = null;while (y != null){t = y.next;y.next = r;r = y;y = t;
}return r;
}
Questo metodo inverte i link di una lista,restituendo un puntatore al nodo finale il quale a
sua volta punta al penultimo, e così via. Il linkdel primo nodo della lista originale è posto a
NULL. Per effettuare le operazioni è necessariomantenere link a tre nodi consecutivi nella lista.
r
yt
ry
25 / 36
IntroduzioneCostrutti di base
ArrayListe concatenate
Ordinamento per insersione in una lista
Class Node
class Node {int val; Node next;Node(int v, Node t) {val = v;next = t;
}}
Metodo create()
public Node create(){Node a = new Node (0, null);for (In.init(); !In.empty();)a.next= new Node(In.getInt(), a.next);
return a;}
Metodo sort()
Node sort(Node a){Node t, u, x, b = new Node(o, null);while (a.next != null) {t = a.next; u = t.next; a.next = u;for (x = b; x.next != null; x = x.next)if (x.next.val > t.val) break;t.next = x.next; x.next = t;
}return b;
}
26 / 36
IntroduzioneCostrutti di base
ArrayListe concatenate
Risultato dell’ordinamento
a t
627758 113
b
101515 838
a758
113
b758
113
627
838t
x
a758
113
b101
515627
838
Manteniamo un puntatore t al primonodo della lista non ordinata (in alto)
Quindi, scandendo la lista puntatada b, cerchiamo il primo nodo x conx.next.item > t.item (oppure conx.next=null) e inseriamo t nella listaappena dopo x.
Queste operazioni riducono di 1 lalunghezza della lista a e aumentanodi 1 quella della lista b, mantenendoquest’ultima in ordine (in basso).
Ripetendo il procedimento,giungiamo prima o poi a esaurire aed avere in bla lista ordinata deinodi.
27 / 36
IntroduzioneCostrutti di base
ArrayListe concatenate
Convenzioni su testa e coda in liste concatenate
Coda circolare, mai vuota
primo inserimento: head.next = head;inserisci t dopo x: t.next = x.next; x.next = t;cancella dopo x: x.next = x.next.next;
ciclo di attraversamento: t = headdo { · · · t = t.next; } while (t != head);
testa se un solo elemento: if (head.next == head)
28 / 36
IntroduzioneCostrutti di base
ArrayListe concatenate
Convenzioni su testa e coda in liste concatenate
Riferimento in testa, coda a null
inizializza: head = nullinserisci t dopo x: if (x == null) { head = t; head.next = null; }
else { t.next = x.next; x.next = t; }cancella dopo x: t = x.next; x.next = t.next;
ciclo di attraversamento: for (t = head; t != null; t = t.next)testa se vuota: if (head == null)
29 / 36
IntroduzioneCostrutti di base
ArrayListe concatenate
Convenzioni su testa e coda in liste concatenate
Nodo fittizio in testa, coda a null
inizializza: head = new Node();head.next = null;
inserisci t dopo x: t.next = x.next; x.next = t;cancella dopo x: t = x.next; x.next = t.next;
ciclo di attraversamento: for (t = head; t != null; t = t.next)testa se vuota: if (head == null)
30 / 36
IntroduzioneCostrutti di base
ArrayListe concatenate
Convenzioni su testa e coda in liste concatenate
Nodi fittizi in testa e in coda
inizializza: head = new Node();z = new Node();head.next = z; z.next = z;
inserisci t dopo x: t.next = x.next; x.next = t;cancella dopo x: x.next = x.next.next;
ciclo di attraversamento: for (t = head; t != null; t = t.next)testa se vuota: if (head.next == z)
31 / 36
IntroduzioneCostrutti di base
ArrayListe concatenate
Lista doppiamente concatenata
Cancellazione
t.next.prev = t.prev;t.prev.next = t.next;
t
t
Inserimento
t.next = x.next;x.next.prev = t;x.next = t; t.prev = x;
t
x
t
xt
x
32 / 36
IntroduzioneCostrutti di base
ArrayListe concatenate
Ordinamento di stringhe con lista
01234
5
3 n o w 2 i s 3 t h e 4 t i m e 3 f o 3 a lr l
012345
3 n o w 2 i s 3 t h e 4 t i m e 3 f o 3 a lr l
33 / 36
IntroduzioneCostrutti di base
ArrayListe concatenate
Se non basta: Una multilista
a
b
758
838
113
627
101
515
34 / 36
IntroduzioneCostrutti di base
ArrayListe concatenate
Grafi e liste di adiacenza
0
2
71
5
3
4
6
0 1 2 3 4 5 6 7 1 1 1 0 0 1 1 1 1 1 0 0 0 0 0 1 1 0 1 0 0 0 0 1 0 0 1 1 1 0 0 0 0 0 0 1 1 1 1 0 1 0 0 1 1 1 0 0 1 0 0 0 1 0 1 0
012345
1 1 1 0 1 0 0 1 67
Grafo
Rappresentazione delgrafo con una matrice d'adiacenza
0
1
2
3
4
5
6
7
7
7
7
5
6
0
4
1
5 2 1 6
0
0
5 7 3
4 3
0
2 0 4
4
Rappresentazione delgrafo con liste di adiacenza
35 / 36