Ordinamento - Ateneonline

annuncio pubblicitario
Fondamenti di informatica
Oggetti e Java
Luca Cabibbo
Ordinamento
Capitolo 24
marzo 2004
1
Ordinamento
Luca Cabibbo – Fondamenti di informatica: Oggetti e Java
Copyright © 2004 – The McGraw-Hill Companies srl
Ordinamento di un array
Problema dell’ordinamento non decrescente di un array
 sia dati un array di interi
 trasformare l’array dati in modo tale che gli elementi vi
compaiano in ordine non decrescente
10
2
16
0
-1
51
4
23
9
8
10
16
23
51
ordinamento
-1
2
0
2
4
Ordinamento
8
9
Luca Cabibbo – Fondamenti di informatica: Oggetti e Java
Copyright © 2004 – The McGraw-Hill Companies srl
Ordinamento di array e API di Java
Come si ordina un array?
 package java.util
 classe Arrays
 metodi di classe void sort(T[] a)
import java.util.Arrays;
...
int[] dati;
// un array di interi
dati = new int[] { 1, 5, 0, 8, 5 };
/* ora dati vale { 1, 5, 0, 8, 5 } */
/* ordina dati */
Arrays.sort(dati);
/* ora dati vale { 0, 1, 5, 5, 8 } */
3
Ordinamento
Luca Cabibbo – Fondamenti di informatica: Oggetti e Java
Copyright © 2004 – The McGraw-Hill Companies srl
Ordinamento per selezione
L’algoritmo di ordinamento per selezione (selection sort) è
basato sulla seguente strategia iterativa
 finché l’array non è ordinato
 seleziona l’elemento di valore minimo dell’array tra quelli
che non sono stati ancora ordinati
 disponi questo elemento nella sua posizione definitiva
4
Ordinamento
Luca Cabibbo – Fondamenti di informatica: Oggetti e Java
Copyright © 2004 – The McGraw-Hill Companies srl
Strategia dell’ordinamento per selezione
16
2
51
10
0
-1
Per prima cosa, l’ordinamento per selezione
 determina l’elemento di valore minimo dell’array
 l’elemento di valore -1 e indice 5
 tale elemento deve essere collocato nella sua posizione
definitiva (posizione 0)
 va utilizzato uno scambio
5
16
2
51
10
0
-1
-1
2
51
10
0
16
Ordinamento
Luca Cabibbo – Fondamenti di informatica: Oggetti e Java
Copyright © 2004 – The McGraw-Hill Companies srl
Scambio di una coppia di elementi dell’array
/* Scambia gli elementi di indice i e j di dati. */
private static void scambia(int[] dati, int i, int j) {
// pre: dati!=null && 0<= i,j <dati.length
int temp;
// variabile di supporto per lo scambio
/* scambia dati[i] con dati[j] */
temp = dati[i];
dati[i] = dati[j];
dati[j] = temp;
}
2
16
2
51
10
3
0
-1
1
temp
6
Ordinamento
Luca Cabibbo – Fondamenti di informatica: Oggetti e Java
Copyright © 2004 – The McGraw-Hill Companies srl
Strategia dell’ordinamento per selezione
-1
2
51
10
0
16
L’ordinamento per selezione prosegue
 determina il valore minimo tra gli elementi dell’array che non
sono ancora ordinati
 colloca questo elemento nella sua posizione definitiva

7
-1
2
51
10
0
16
-1
0
51
10
2
16
e così via, finché tutti gli elementi non sono stati ordinati
Ordinamento
Luca Cabibbo – Fondamenti di informatica: Oggetti e Java
Copyright © 2004 – The McGraw-Hill Companies srl
Strategia dell’ordinamento per selezione
L’algoritmo di ordinamento per selezione
 procede per fasi, chiamate passate
 gestisce una partizione degli elementi dell’array in due insiemi
 elementi ordinati
 elementi non ordinati
Nell’ordinamento per selezione
 inizialmente, tutti gli elementi sono considerati non ordinati
 dopo la prima passata, il primo elemento viene ordinato
 per ordinare l’array si devono eseguire tante passate fino a
quando tutti gli elementi dell’array non risultano ordinati
8
Ordinamento
Luca Cabibbo – Fondamenti di informatica: Oggetti e Java
Copyright © 2004 – The McGraw-Hill Companies srl
Applicazione dell’ordinamento per selezione
9
16
2
51
10
0
-1
-1
2
51
10
0
16
-1
0
51
10
2
16
-1
0
2
10
51
16
-1
0
2
10
51
16
-1
0
2
10
16
51
Ordinamento
Luca Cabibbo – Fondamenti di informatica: Oggetti e Java
Copyright © 2004 – The McGraw-Hill Companies srl
Implementazione dell’ordinamento per selezione
/* Ordina l'array dati in modo non decrescente.
* Ordinamento per selezione. */
public static void selectionSort(int[] dati) {
// pre: dati!=null
int n;
// lunghezza di dati
int i;
// indice per la scansione di dati
int ordinati;
// numero di elementi ordinati
int imin;
// indice dell'elemento di valore
// minimo tra gli elementi
// non ordinati
... segue ...
10
Ordinamento
Luca Cabibbo – Fondamenti di informatica: Oggetti e Java
Copyright © 2004 – The McGraw-Hill Companies srl
Implementazione dell’ordinamento per selezione
/* ordina dati in modo non decrescente
* (ordinamento per selezione) */
n = dati.length;
/* esegue n-1 passate */
for (ordinati=0; ordinati<n-1; ordinati++) {
/* gli elementi ordinati sono quelli di indice
* tra 0 (compreso) e ordinati (escluso) */
/* cerca il minimo tra i non ordinati */
imin = ordinati;
for (i=ordinati+1; i<n; i++)
if (dati[i]<dati[imin])
imin = i;
/* ordina l'elemento in imin */
scambia(dati, ordinati, imin);
/* ora gli elementi ordinati sono quelli di
* indice compreso tra 0 e ordinati (incluso) */
}
}
11
Ordinamento
Luca Cabibbo – Fondamenti di informatica: Oggetti e Java
Copyright © 2004 – The McGraw-Hill Companies srl
Complessità dell’ordinamento per selezione
Complessità asintotica dell’ordinamento per selezione
 rispetto alla lunghezza N dell’array da ordinare
 operazione dominante
 il confronto dati[i]<dati[imin]
 caso peggiore
 qualunque
 contando il numero complessivo di confronti, si può
concludere che
TselectionSort(N) = N2
12
Ordinamento
Luca Cabibbo – Fondamenti di informatica: Oggetti e Java
Copyright © 2004 – The McGraw-Hill Companies srl
Ordinamento a bolle
Algoritmo di ordinamento a bolle (bubble sort)
 la strategia implementata dall’algoritmo è ancora basata su
passate e su confronti e scambi
 l’ordinamento a bolle confronta, durante ciascuna passata,
tutte le coppie di elementi adiacenti tra gli elementi non
ordinati dell’array
13
Ordinamento
Luca Cabibbo – Fondamenti di informatica: Oggetti e Java
Copyright © 2004 – The McGraw-Hill Companies srl
Una passata dell’ordinamento a bolle
14
10
2
0
16
51
-1
2
10
0
16
51
-1
2
0
10
16
51
-1
2
0
10
16
51
-1
2
0
10
16
51
-1
2
0
10
16
-1
51
Ordinamento
Luca Cabibbo – Fondamenti di informatica: Oggetti e Java
Copyright © 2004 – The McGraw-Hill Companies srl
Applicazione completa dell’ordinamento a bolle
15
10
2
0
16
51
-1
2
0
10
16
-1
51
0
2
10
-1
16
51
0
2
-1
10
16
51
0
-1
2
10
16
51
-1
0
2
10
16
51
Ordinamento
Luca Cabibbo – Fondamenti di informatica: Oggetti e Java
Copyright © 2004 – The McGraw-Hill Companies srl
Implementazione elementare dell’ordinamento a bolle
/* Ordina l'array dati in modo non decrescente.
* Ordinamento a bolle -- versione elementare. */
public static void simpleBubbleSort(int[] dati) {
// pre: dati!=null
int n;
// lunghezza di dati
int i;
// indice per la scansione di dati
int ordinati;
// numero di elementi ordinati
... segue ...
16
Ordinamento
Luca Cabibbo – Fondamenti di informatica: Oggetti e Java
Copyright © 2004 – The McGraw-Hill Companies srl
Implementazione elementare dell’ordinamento a bolle
/* ordina dati in modo non decrescente
* (ordinamento a bolle -- versione elementare) */
n = dati.length;
/* esegue n-1 passate */
for (ordinati=0; ordinati<n-1; ordinati++) {
/* gli elementi ordinati sono quelli di indice
* tra n-ordinati (compreso) e n (escluso) */
/* confronta ogni elemento non ordinato
* con quello che lo precede
* (ed eventualmente li scambia) */
for (i=1; i<n-ordinati; i++)
if (dati[i]<dati[i-1])
scambia(dati, i, i-1);
/* ora gli elementi ordinati sono quelli di
* indice tra n-ordinati-1 (compreso)
* e n (escluso) */
}
}
17
Ordinamento
Luca Cabibbo – Fondamenti di informatica: Oggetti e Java
Copyright © 2004 – The McGraw-Hill Companies srl
Considerazioni per migliorare l’ordinamento a bolle
Una passata dell’ordinamento a bolle può portare nella posizione
definitiva più di un elemento
18
0
2
16
-1
10
51
0
2
-1
10
16
51
Ordinamento
Luca Cabibbo – Fondamenti di informatica: Oggetti e Java
Copyright © 2004 – The McGraw-Hill Companies srl
Considerazioni per migliorare l’ordinamento a bolle
È possibile che in una passata dell’ordinamento a bolle non
avvengano scambi
19
-1
0
2
10
16
51
-1
0
2
10
16
51
Ordinamento
Luca Cabibbo – Fondamenti di informatica: Oggetti e Java
Copyright © 2004 – The McGraw-Hill Companies srl
Applicazione dell’ordinamento a bolle
20
-1
2
16
0
10
51
-1
2
0
10
16
51
-1
0
2
10
16
51
-1
0
2
10
16
51
Ordinamento
Luca Cabibbo – Fondamenti di informatica: Oggetti e Java
Copyright © 2004 – The McGraw-Hill Companies srl
Implementazione dell’ordinamento a bolle
/* Ordina l'array dati in modo non decrescente.
* Ordinamento a bolle. */
public static void bubbleSort(int[] dati) {
// pre: dati!=null
int n;
// lunghezza di dati
int i;
// indice per la scansione di dati
int ordinati;
// numero di elementi ordinati
int ultimoScambio;
// posizione in cui è avvenuto
// l'ultimo scambio durante la
// passata corrente
/* ultimoScambio vale 0 se non sono stati ancora
* eseguiti scambi durante la passata corrente */
... segue ...
21
Ordinamento
Luca Cabibbo – Fondamenti di informatica: Oggetti e Java
Copyright © 2004 – The McGraw-Hill Companies srl
Implementazione dell’ordinamento a bolle
/* ordina dati in modo non decrescente
* (ordinamento a bolle) */
n = dati.length;
ordinati = 0;
/* esegue passate finché dati non è ordinato */
while (ordinati<n-1) {
/* gli elementi ordinati sono quelli di indice
* tra n-ordinati (compreso) e n (escluso) */
/* confronta ogni elemento non ordinato
* con quello che lo precede */
ultimoScambio = 0;
for (i=1; i<n-ordinati; i++)
if (dati[i]<dati[i-1]) {
scambia(dati, i, i-1);
ultimoScambio = i;
}
/* ora gli elementi ordinati sono quelli di
* indice tra ultimoScambio e n */
ordinati = n-ultimoScambio;
}
22
}
Ordinamento
Luca Cabibbo – Fondamenti di informatica: Oggetti e Java
Copyright © 2004 – The McGraw-Hill Companies srl
Complessità dell’ordinamento a bolle
Complessità asintotica dell’ordinamento a bolle
 rispetto alla lunghezza N dell’array da ordinare
 operazione dominante
 il confronto dati[i]<dati[i-1]
 caso peggiore
 l’array è ordinato in modo decrescente
 il numero complessivo di confronti è quadratico
TbubbleSort(N) = N2
23
Ordinamento
Luca Cabibbo – Fondamenti di informatica: Oggetti e Java
Copyright © 2004 – The McGraw-Hill Companies srl
Ordinamento per inserzione
Algoritmo di ordinamento per inserzione (insertion sort)
 gli elementi sono partizionati in due insiemi
 elementi relativamente ordinati
 elementi non relativamente ordinati
 inizialmente viene considerato relativamente ordinato il primo
elemento dell’array
 ad ogni passata
 colloca il primo tra gli elementi non relativamente ordinati
tra quelli relativamente ordinati
24
Ordinamento
Luca Cabibbo – Fondamenti di informatica: Oggetti e Java
Copyright © 2004 – The McGraw-Hill Companies srl
Una passata dell’ordinamento per inserzione
Effetto di una passata dell’ordinamento per inserzione
-1
10
16
0
51
2
-1
0
10
16
51
2
Dinamica dell’inserimento
3
-1
10
4
25
Ordinamento
2
16
0
51
2
1
Luca Cabibbo – Fondamenti di informatica: Oggetti e Java
Copyright © 2004 – The McGraw-Hill Companies srl
Applicazione completa dell’ordinamento per inserzione
26
10
-1
16
0
51
2
-1
10
16
0
51
2
-1
10
16
0
51
2
-1
0
10
16
51
2
-1
0
10
16
51
2
-1
0
2
10
16
51
Ordinamento
Luca Cabibbo – Fondamenti di informatica: Oggetti e Java
Copyright © 2004 – The McGraw-Hill Companies srl
Implementazione dell’ordinamento per inserzione
/* Ordina l'array dati in modo non decrescente.
* Ordinamento per inserzione. */
public static void insertionSort(int[] dati) {
// pre: dati!=null
int n;
// lunghezza di dati
int i;
// indice per la scansione di dati
int ordinati;
// numero di elementi
// "relativamente ordinati"
int corrente;
// elemento da "ordinare"
boolean ins;
// è possibile inserire corrente
// tra gli "relativamente ordinati"
... segue ...
27
Ordinamento
Luca Cabibbo – Fondamenti di informatica: Oggetti e Java
Copyright © 2004 – The McGraw-Hill Companies srl
Implementazione dell’ordinamento per inserzione
/* ordina dati in modo non decrescente
* (ordinamento per inserzione) */
n = dati.length;
/* esegue n-1 passate */
for (ordinati=1; ordinati<n; ordinati++) {
/* gli elementi "relativamente ordinati" sono
* quelli di indice tra 0 e ordinati */
/* viene "ordinato" il primo elemento
* tra i "non relativamente ordinati" */
corrente = dati[ordinati];
ins = false;
i = ordinati;
while (!ins && i>0)
if (corrente<dati[i-1]) { // sposta verso dx
dati[i] = dati[i-1];
i--;
} else
ins = true;
/* inserisce corrente tra i "rel. ordinati" */
dati[i] = corrente;
/* ora gli elementi "rel. ordinati" sono quelli
* di indice compreso tra 0 e ordinati */
}
28
}
Ordinamento
Luca Cabibbo – Fondamenti di informatica: Oggetti e Java
Copyright © 2004 – The McGraw-Hill Companies srl
Complessità dell’ordinamento per inserzione
Complessità asintotica dell’ordinamento per inserzione
 rispetto alla lunghezza N dell’array da ordinare
 operazione dominante
 il confronto corrente<dati[i-1]
 caso peggiore
 l’array è ordinato in modo decrescente
 il numero complessivo di confronti è quadratico
TinsertionSort(N) = N2
29
Ordinamento
Luca Cabibbo – Fondamenti di informatica: Oggetti e Java
Copyright © 2004 – The McGraw-Hill Companies srl
Ordinamento per fusione
Algoritmo di ordinamento per fusione (merge sort) per ordinare
una sequenza
 se la sequenza da ordinare contiene uno o due elementi,
allora la sequenza viene ordinata direttamente
 se invece la sequenza da ordinare contiene più di due
elementi, allora
 gli elementi della sequenza vengono partizionati in due
sotto-sequenze
 le due sotto-sequenze vengono ordinate separatamente
 le due sotto-sequenze ordinate vengono fuse in un’unica
sequenza ordinata
30
Ordinamento
Luca Cabibbo – Fondamenti di informatica: Oggetti e Java
Copyright © 2004 – The McGraw-Hill Companies srl
Strategia dell’ordinamento per fusione
85 24 63 45 17 31 96 50
decomposizione
85 24 63 45
17 31 96 50
24 45 63 85
17 31 50 96
ordinamento
fusione
17 24 31 45 50 63 85 96
31
Ordinamento
Luca Cabibbo – Fondamenti di informatica: Oggetti e Java
Copyright © 2004 – The McGraw-Hill Companies srl
Strategia ricorsiva dell’ordinamento per fusione
85 24 63 45 17 31 96 50
decomposizioni
85 24 63 45
ordinamenti
(semplici)
fusioni
17 31 96 50
85 24
63 45
17 31
96 50
24 85
45 63
17 31
50 96
24 45 63 85
17 31 50 96
17 24 31 45 50 63 85 96
32
Ordinamento
Luca Cabibbo – Fondamenti di informatica: Oggetti e Java
Copyright © 2004 – The McGraw-Hill Companies srl
Implementazione dell’ordinamento per fusione
L’algoritmo di ordinamento per fusione può essere implementato
utilizzando tre metodi
 void mergeSort(int[] dati)
 mergeSortRic
 merge
Considerazioni
 per motivi di efficienza, i tre metodi utilizzano un array di
appoggio temp condiviso da tutte le attivazioni
33
Ordinamento
Luca Cabibbo – Fondamenti di informatica: Oggetti e Java
Copyright © 2004 – The McGraw-Hill Companies srl
Implementazione dell’ordinamento per fusione
/* Ordinamento l'array dati in modo non decrescente.
* Ordinamento per fusione. */
public static void mergeSort(int[] dati) {
// pre: dati!=null
int n;
// lunghezza di dati
/* ordina dati in modo non decrescente */
n = dati.length;
/* avvia la ricorsione:
* ordina dati,
* dall'elemento di posizione 0 (compreso)
* a quello di posizione n (escluso)
* usando un array di appoggio di lunghezza n */
mergeSortRic(dati, 0, n, new int[n]);
}
34
Ordinamento
Luca Cabibbo – Fondamenti di informatica: Oggetti e Java
Copyright © 2004 – The McGraw-Hill Companies srl
Implementazione dell’ordinamento per fusione
/* Ordina gli elementi di dati tra sinistra (incluso) e
* destra (escluso) usando l'array di appoggio temp. */
private static void mergeSortRic(int[] dati,
int sinistra, int destra, int[] temp) {
int m;
// numero di elementi da ordinare
int centro;
// indice dell'elemento centrale
// della sottosequenza da ordinare
/* ordina gli elementi di dati tra sinistra
* (incluso) e destra (escluso) */
m = destra-sinistra;
if (m==2) {
// caso base, confronto e scambio
if (dati[sinistra]>dati[destra-1])
scambia(dati, sinistra, destra-1);
} else if (m>2) { // caso ricorsivo
centro = (sinistra+destra)/2;
mergeSortRic(dati, sinistra, centro, temp);
mergeSortRic(dati, centro, destra, temp);
merge(dati, sinistra, centro, destra, temp);
}
/* m<2 è un altro caso base, la sottosequenza è
* già ordinata */
}
35
Ordinamento
Luca Cabibbo – Fondamenti di informatica: Oggetti e Java
Copyright © 2004 – The McGraw-Hill Companies srl
Complessità dell’ordinamento per fusione
Complessità asintotica dell’ordinamento per fusione
 discussa in modo informale
 rispetto alla lunghezza N dell’array da ordinare
 attività dominante
 fusione di sottosequenze ordinate
 caso peggiore
 qualunque
36
Ordinamento
Luca Cabibbo – Fondamenti di informatica: Oggetti e Java
Copyright © 2004 – The McGraw-Hill Companies srl
Complessità dell’ordinamento per fusione
24 85
fusioni
45 63
24 45 63 85
17 31
50 96
17 31 50 96
17 24 31 45 50 63 85 96




un certo numero di livelli di decomposizioni e fusioni
in ciascun livello vengono fusi tutti gli elementi
il costo asintotico di ciascun livello di fusioni è N
il numero di livelli è log2 N
TmergeSort(N) = N log N
37
Ordinamento
Luca Cabibbo – Fondamenti di informatica: Oggetti e Java
Copyright © 2004 – The McGraw-Hill Companies srl
Ordinamento veloce
L’algoritmo di ordinamento di array più usato in pratica è
l’ordinamento veloce (quick sort)
38
58
65
67
45
31
16
96
50
50
16
31
45
58
67
96
65
45
16
31
50
65
67
96
31
16
45
16
31
45
Ordinamento
65
50
58
65
96
67
96
Luca Cabibbo – Fondamenti di informatica: Oggetti e Java
Copyright © 2004 – The McGraw-Hill Companies srl
Complessità dell’ordinamento veloce
È stato dimostrato l’ordinamento veloce ha, nel caso peggiore,
complessità asintotica quadratica rispetto alla lunghezza dell’array
da ordinare
 tuttavia, l’ordinamento veloce viene solitamente preferito
all’ordinamento per fusione
 perché?
39
Ordinamento
Luca Cabibbo – Fondamenti di informatica: Oggetti e Java
Copyright © 2004 – The McGraw-Hill Companies srl
Risultati sperimentali
Tempi medi di esecuzione, in secondi
1 000
10 000
100 000
selection sort
0.02
0.27
24.05
bubble sort
elementare
0.01
0.66
62.35
bubble sort
0.02
0.67
62.20
bubble sort
bidirezionale
0.01
0.47
43.25
insertion sort
0.01
0.23
18.80
merge sort
0.01
0.01
0.05
0.51
quick sort
(API di Java)
0.01
0.02
0.05
0.35
Algoritmo
40
N
Ordinamento
1 000 000
circa 40
minuti
circa 100
minuti
circa 100
minuti
circa 70
minuti
circa 30
minuti
Luca Cabibbo – Fondamenti di informatica: Oggetti e Java
Copyright © 2004 – The McGraw-Hill Companies srl
Scarica