strutture dati elementari - eziobartocci.com · strutture dati e algoritmi ... strutture dati...

36
Strutture dati elementari Dott. Ezio Bartocci, Dott. Francesco De Angelis Laboratorio di Algoritmi e strutture Dati - AA 2006/2007 Dip. di Matematica e Informatica Università di Camerino [email protected], [email protected] 24 novembre 2006

Upload: lamngoc

Post on 15-Feb-2019

228 views

Category:

Documents


1 download

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

IntroduzioneCostrutti di base

ArrayListe concatenate

Riferimenti

[Sed03] §3 - Strutture Dati Elementari

36 / 36