dispensa 20 algoritmi di ordinamento - dia.uniroma3.it · java/fondinf/ algoritmi di ordinamento 3...

69
http://www.dia.uniroma3.it/~java/fondinf/ Algoritmi di Ordinamento 1 Corso di Laurea Ingegneria Informatica Fondamenti di Informatica Dispensa 20 Algoritmi di ordinamento C. Limongelli Marzo 2012

Upload: dohanh

Post on 17-Feb-2019

221 views

Category:

Documents


0 download

TRANSCRIPT

http://www.dia.uniroma3.it/~java/fondinf/ Algoritmi di Ordinamento 1

Corso di Laurea Ingegneria Informatica

Fondamenti di Informatica

Dispensa 20

Algoritmi di ordinamento

C. Limongelli

Marzo 2012

http://www.dia.uniroma3.it/~java/fondinf/ Algoritmi di Ordinamento 2

Contenuti

Ordinamento di un array

Ordinamento di array e API di Java

Ordinamento per selezione • complessità dell’ordinamento per selezione

Ordinamento a bolle • complessità dell’ordinamento a bolle

Ordinamento per inserzione • complessità dell’ordinamento per inserzione

Ordinamento per fusione • complessità dell’ordinamento per fusione

Ordinamento veloce • complessità dell’ordinamento veloce

Risultati sperimentali

http://www.dia.uniroma3.it/~java/fondinf/ Algoritmi di Ordinamento 3

Proprietà di ordinamento di una sequenza

Sia data una sequenza <a1, a2, ..., an> di n

elementi appartenenti ad un insieme dotato di

una relazione d’ordine (ad esempio < oppure <=)

La sequenza si dice totalmente ordinata rispetto

alla relazione d’ordine (ad esempio in modo non

decrescente) se per ogni i = 1,…,n ai <= aj per

ogni j >= i

Altrimenti la sequenza si dice parzialmente

ordinata

La proprietà ai <= aj vale solo per qualche coppia di

valori

http://www.dia.uniroma3.it/~java/fondinf/ Algoritmi di Ordinamento 4

Problema di ordinamento

Ordinare una sequenza in modo non

decrescente

Data una sequenza di n numeri <a1, a2, ..., an>,

generare una permutazione <a’1, a’2, ...,a’n> di

<a1, a2, ..., an>, di in modo che a’1<= a’2<= ...<= a’n

Uno dei vantaggi nel mantenere una collezione

di dati ordinata è nella possibilità di eseguire

operazioni di ricerca in modo efficiente

Per semplicità faremo riferimento al problema

dell’ordinamento di array di interi

http://www.dia.uniroma3.it/~java/fondinf/ Algoritmi di Ordinamento 5

Ordinamento di un array

Problema dell’ordinamento non decrescente di un array sia a un array di interi

trasformare l’array a in modo tale che gli elementi vi compaiano in ordine non decrescente

• modificare la posizione degli elementi di a in modo tale che, per ogni indice i, l’elemento a[i] sia minore o uguale a tutti gli elementi di a di indice j>i

http://www.dia.uniroma3.it/~java/fondinf/ Algoritmi di Ordinamento 6

Ordinamento di array

Si possono utilizzare diverse strategie per

ordinare un array (o più in generale una

sequenza)

16 2 51 10 0 -1

http://www.dia.uniroma3.it/~java/fondinf/ Algoritmi di Ordinamento 7

Ordinamento per selezione

L’algoritmo di ordinamento per selezione

(selection sort) è basato sulla seguente

strategia

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

http://www.dia.uniroma3.it/~java/fondinf/ Algoritmi di Ordinamento 8

Strategia dell’ordinamento per selezione

-1 0 51 10 2 16

-1 0 51 10 2 16

Supponiamo che i primi due elementi dell’array siano

già ordinati:

L’array viene partizionato in due sottoarray: il primo che

contiene gli elementi già ordinati, il secondo contiene gli

elementi ancora da ordinare.

Si seleziona il minimo sugli elementi ancora da orinare

e si scambia con il primo elemento della porzione

dell’array ancora da ordinare

-1 0 2 10 51 16

http://www.dia.uniroma3.it/~java/fondinf/ Algoritmi di Ordinamento 9

Scambio di una coppia di elementi

dell’array

Metodo per scambiare una coppia di elementi in un 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;

}

http://www.dia.uniroma3.it/~java/fondinf/ Algoritmi di Ordinamento 10

Strategia dell’ordinamento per selezione...

L’algoritmo di ordinamento per selezione

procede per fasi, chiamate passate

• ciascuna passata garantisce che almeno un elemento venga

“ordinato” – venga posto nella posizione che gli compete

nell’ordinamento definitivo

gestisce una partizione degli elementi dell’array in

due insiemi

• gli elementi ordinati – che sono stati sicuramente collocati

nella loro posizione definitiva – l’algoritmo di ordinamento

non deve più confrontare né scambiare questi elementi

• gli elementi non ordinati – che non sono stati ancora

collocati nella loro posizione definitiva

http://www.dia.uniroma3.it/~java/fondinf/ Algoritmi di Ordinamento 11

...Strategia dell’ordinamento per selezione

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

http://www.dia.uniroma3.it/~java/fondinf/ Algoritmi di Ordinamento 12

Esempio di applicazione

dell’ordinamento per selezione

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

http://www.dia.uniroma3.it/~java/fondinf/ Algoritmi di Ordinamento 13

Implementazione dell’ordinamento per

selezione...

public static void selectionSort(int[] v) {

int n = v.length;

for (int i = 0; i < n-1; i++) {

// trova l’elem. minimo con indice tra i e n-1

int jmin = i;

for (int j = i+1; j < n; j++) {

if (v[j] < v[jmin])

jmin = j;

}

// scambia gli elementi con indice i e jmin

if (i!=jmin)

scambia(v,i,jmin);

}

}

Si può scrivere meglio?

http://www.dia.uniroma3.it/~java/fondinf/ Algoritmi di Ordinamento 14

...Implementazione dell’ordinamento per

selezione...

Si può definire un metodo per il calcolo

dell’indice corrispondente all’elemento di

valore minimo/* calcola la posizione in cui si trova il minimo in

* una porzione dell'array a compresa tra inf e sup */

public static int min(int[] a, int inf, int sup){

int i,indmin;

indmin = inf;

for (i = inf+1; i <= sup; i++) {

if (a[i] < a[indmin])

indmin = i;

}

return indmin;

}

http://www.dia.uniroma3.it/~java/fondinf/ Algoritmi di Ordinamento 15

...Implementazione dell’ordinamento per

selezione...

Il metodo selectionSort diventa:

public static void selectionSort(int[] v) {

int n;

n = v.length;

for (int i = 0; i < n-1; i++)

scambia(v,i,min(v,i,n-1));

}

Osservazioni?

Esercizio: scrivere il selectionSort ricorsivo

http://www.dia.uniroma3.it/~java/fondinf/ Algoritmi di Ordinamento 16

Complessità dell’ordinamento per

selezione

Dimensione dell’input:

lunghezza n dell’array da ordinare

Operazione dominante:

il confronto v[j] < v[jmin] durante il calcolo del minimo

Caso peggiore:

qualunque

1. Il confronto v[j] < v[jmin] viene eseguito n-i volte ad ogni passata

2. Lo scambio ha complessità costante

3. 1. e 2. vengono ripetuti n volte (i=0..n-1)

4. Complessivamente

2

1

22

2

2

1 2221

1

1

1

22 )n(nnnnnn)n(nninin

n

i

n

i

Quindi il selection sort ha complessità quadratica: O(n2)

http://www.dia.uniroma3.it/~java/fondinf/ Algoritmi di Ordinamento 17

Commento

Avendo trovato un algoritmo di complessità quadratica per il problema dell’ordinamento, è possibile concludere che il problema dell’ordinamento ha complessità al piùquadratica esistono algoritmi di ordinamento con complessità

(asintotica, nel caso peggiore) meno che quadratica (ad esempio, lineare) ?

esistono algoritmi di ordinamento che, pur avendo complessità quadratica nel caso peggiore, hanno una complessità migliore nel caso migliore e nel “caso medio” ?

http://www.dia.uniroma3.it/~java/fondinf/ Algoritmi di Ordinamento 18

Esercizi

Mostrare l’applicazione dell’ordinamento per selezione al seguente array

mostrare lo stato dell’array dopo ciascuna passata, indicando anche quali sono gli elementi ordinati e quali i non ordinati

Definire un metodo di ordinamento non crescente (anziché non decrescente) basato sull’algoritmo di ordinamento per selezione

Definisci un metodo basato sull’algoritmo di ordinamento per selezione che ordina un array di stringhe (rispetto all’ordinamento lessicografico)

10 2 16 0 -1 51 4 23 9 8

http://www.dia.uniroma3.it/~java/fondinf/ Algoritmi di Ordinamento 19

Ordinamento a bolle

Algoritmo di ordinamento a bolle (bubble sort)

la strategia implementata dall’algoritmo è ancora

basata su

• passate

• confronti e scambi

in particolare, l’ordinamento a bolle confronta,

durante ciascuna passata, tutte le coppie di elementi

adiacenti tra gli elementi non ordinati dell’array

• ogni volta che una coppia di elementi adiacenti non è

ordinata correttamente, gli elementi vengono scambiati

http://www.dia.uniroma3.it/~java/fondinf/ Algoritmi di Ordinamento 20

Proprietà di ordinamento:

a[0]<a[1]<a[2]<…<a[n-1]

per ogni coppia a[j], a[j+1] se a[j]>a[j+1], scambia

a[j],a[j+1]

30 16 31 9 18 4 j=0

16 30 31 9 18 4 j=1

16 30 31 9 18 4 j=2

16 30 9 31 18 4 j=3

16 30 9 18 31 4 j=4

16 30 9 18 4 31 j=5

passata

for (j=0; j<n-1; j++){

if (a[j]>a[j+1])

scambia(a,j,j+1)

}

int a[6]

Prima passata! (n-1 confronti) il più grande a posto

http://www.dia.uniroma3.it/~java/fondinf/ Algoritmi di Ordinamento 21

Ordinamento a bolle = sequenza di passate

passata

for (j=0; j<n-2; j++){

if (a[j]>a[j+1])

scambia(a[j], a[j+1])

}

16 30 9 18 4 31 j=0

16 30 9 18 4 31 j=1

16 9 30 18 4 31 j=2

16 9 18 30 4 31 j=3

16 9 18 4 30 31 j=4

j=5

Seconda passata (n-2 confronti) il penultimo a posto

http://www.dia.uniroma3.it/~java/fondinf/ Algoritmi di Ordinamento 22

16 9 18 4 30 31 j=0

9 16 18 4 30 31 j=1

9 16 18 4 30 31 j=2

16 9 4 18 30 31

passata

for (j=0; j<n-3; j++){

if (a[j]>a[j+1])

scambia(a[j], a[j+1])

}

Terza passata (n-3 confronti) il terz’ultimo a posto

Quarta passata

(n-4 confronti)

9 4 16 18 30 31for (j=0; j<n-4; j++){...

Quinta passata

cioè (n-1)-esima passata

(n-5 = n-n+1 = 1 confronto)

4 9 16 18 30 31

for (j=0; j<n-5; j++){...

dopo n-1 passate l’array è ordinato 4 9 16 18 30 31

Ordinamento a bolle = sequenza di passate

http://www.dia.uniroma3.it/~java/fondinf/ Algoritmi di Ordinamento 23

In generale

for (j=0; j<n-i; j++){

if (a[j]>a[j+1])

scambia(a[j], a[j+1])

}

i-esima passata

per i che conta da 1 a n-1

esegui la i-esima passata

algoritmo

public static void bubbleSort(int[] v) {

int n = v.length;

int i, j;

boolean ordinato = false;

for (i=1; i<n-1; i++)

for (j=0; j<n-i; j++)

if (v[j]>v[j+1])

scambia(v[j], v[j+1]);

}

http://www.dia.uniroma3.it/~java/fondinf/ Algoritmi di Ordinamento 24

Applicazione sull’array 16 8 2 15 4 9

...8 15 2 4 9 16 j=5

16 8 15 2 4 9 j=0

8 16 15 2 4 9 j=1Prima passata

5 scambi

8 2 4 9 15 16 Seconda passata

n-2 confronti 3 scambi

2 4 8 9 15 16 Terza passata

n-3 confronti e 2 scambi

2 4 8 9 15 16 !!

2 4 8 9 15 16 Quarta passata

0 scambi2 4 8 9 15 16 Quinta passata

0 scambi

http://www.dia.uniroma3.it/~java/fondinf/ Algoritmi di Ordinamento 25

Applicazione sull’array 16 18 20 25 34 39

prima passata n-1 confronti e 0 scambi

seconda n-2 0

terza n-3 0

quarta n-4 0

quinta n-5 0

L’array potrebbe essere già ordinato prima deltermine delle n-1 passate: dipende dallaconfigurazione della sequenza da ordinare

L’algoritmo però esegue sempre n-1 passate

l’i-esima passata esegue sempre n-i confronti (a[i] > a[i+1]) con eventuale scambio

http://www.dia.uniroma3.it/~java/fondinf/ Algoritmi di Ordinamento 26

Miglioramento...

Mentre non abbiamo finito {

esegui una passata;

abbiamo finito

}

while (!finito) {/* mentre non ... finito */

for (j=0; ... )

if (a[j]>a[j+1]) {

scambia(a[j], a[j+1]);

}

se durante la passata non abbiamo eseguito scambi

fattoscambio = false;

fattoscambio = true;

if (fattoscambio==false)

finito = true;

se l’array risulta ordinato

http://www.dia.uniroma3.it/~java/fondinf/ Algoritmi di Ordinamento 27

finito = false;

i=0; /* fatte 0 passate */

while (!finito) {

i=i+1;

fattoscambio = false;

for (j=0; j<n-i; j++ )

if (a[j]>a[j+1]) {

scambia (a[j],a[j+1]);

fattoscambio = true;

}

if ((!fattoscambio)||(i==n-1))

finito = true;

}

... Miglioramento

http://www.dia.uniroma3.it/~java/fondinf/ Algoritmi di Ordinamento 28

Complessità del bubble sort...

Istruzione dominante Confronto tra due elementi adiacenti

if (a[j]>a[j+1])

Caso migliore 16 18 20 25 34 39 Finiamo dopo la prima passata (n-1 confronti e 0 scambi)

Caso medio 9 4 31 30 18 16 Finiamo dopo alcune passate: k < n confronti e s < n2 scambi

Caso peggiore 30 16 31 9 18 4 numero di confronti massimo

Caso PEGGIORE 39 34 25 20 18 16 massimo numero di confronti, ognuno con scambio e

assegnazione

http://www.dia.uniroma3.it/~java/fondinf/ Algoritmi di Ordinamento 29

...Complessità del bubble sort...

Il miglioramento permette di mettere a frutto

eventuali configurazioni favorevoli (ad es. array

parzialmente ordinato)

Nei casi sfavorevoli si comporta come la

versione iniziale

Nei casi favorevoli guadagna.

http://www.dia.uniroma3.it/~java/fondinf/ Algoritmi di Ordinamento 30

...Complessità del bubble sort

unica passata: n-1 confronti O(n)

si presenta solo per il bubble sort migliorato

prima passata n-1 confronti

...

(i-esima passata) n-i confronti

(n-1)-esima passata 1 confronto

Caso peggiore: n-1 passate

Caso migliore: 1 passata

2

1

2

111

1

1

1

1

)()()()()(

nnnnnninnin

n

i

n

i

O(n2)

http://www.dia.uniroma3.it/~java/fondinf/ Algoritmi di Ordinamento 31

Esercizi

Mostrare l’applicazione dell’ordinamento a bolle

(entrambe le versioni) al seguente array

mostra lo stato dell’array dopo ciascuna passata,

indicando anche quali sono gli elementi ordinati e

quali i non ordinati

10 2 16 0 -1 51 4 23 9 8

http://www.dia.uniroma3.it/~java/fondinf/ Algoritmi di Ordinamento 32

Ordinamento per inserzione

Algoritmo di ordinamento per inserzione

(insertion sort)

gli elementi sono partizionati in due insiemi

• elementi relativamente ordinati – elementi ordinati tra di loro,

ma che non sono stati necessariamente collocati nelle loro

posizioni definitive

• 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

http://www.dia.uniroma3.it/~java/fondinf/ Algoritmi di Ordinamento 33

Una passata dell’ordinamento per

inserzione

Effetto di una passata dell’ordinamento per

inserzione

Dinamica dell’inserimento

-1 10 16 0 51 2

-1 0 10 16 51 2

-1 10 16 0 51 2

2

1

3

4 0

http://www.dia.uniroma3.it/~java/fondinf/ Algoritmi di Ordinamento 34

Applicazione completa dell’ordinamento

per inserzione

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

http://www.dia.uniroma3.it/~java/fondinf/ Algoritmi di Ordinamento 35

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 ...

http://www.dia.uniroma3.it/~java/fondinf/ Algoritmi di Ordinamento 36

Implementazione dell’ordinamento per

inserzionen = 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 */

} }

http://www.dia.uniroma3.it/~java/fondinf/ Algoritmi di Ordinamento 37

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

Insertion sort ha complessità O(n2)

Esercizio

cosa succede se la ricerca della posizione corrente in cui

inserire viene effettuata mediante la ricerca binaria?

http://www.dia.uniroma3.it/~java/fondinf/ Algoritmi di Ordinamento 38

Esercizi

Mostrare l’applicazione dell’ordinamento per

inserzione al seguente array

mostra lo stato dell’array dopo ciascuna passata,

indicando anche quali sono gli elementi

relativamente ordinati e quali i non relativamente

ordinati

Definire un metodo di ordinamento non

crescente (anziché non decrescente) basato

sull’algoritmo di ordinamento per inserzione

10 2 16 0 -1 51 4 23 9 8

http://www.dia.uniroma3.it/~java/fondinf/ Algoritmi di Ordinamento 39

Considerazioni...

Per ordinare 1.000 elementi usando un algoritmo di

complessità O(n2) (ordinamento per selezione,

inserzione o a bolle) sono necessarie 1.000.000 di

operazioni. Esistono algoritmi di ordinamento più

efficienti?

SI

Idea: Divido i 1000 elementi in due gruppi da 500

elementi ciascuno:

ordino il primo gruppo in O(n2): 250.000 operazioni

ordino il secondo gruppo in O(n2): 250.000 operazioni

combino (fondo) i due gruppi ordinati: si può fare in O(n), cioè

1.000 operazioni

Totale: 501.000 operazioni (contro 1.000.000)

http://www.dia.uniroma3.it/~java/fondinf/ Algoritmi di Ordinamento 40

...Considerazioni

Il procedimento può essere iterato:

per ordinare le due metà non uso un algoritmo di

complessità O(n2), ma applico lo stesso

procedimento di divisione, ordinamento separato e

fusione.

La suddivisione in due metà si ferma quando si

arriva ad un gruppo costituito da un solo

elemento (che è già ordinato).

http://www.dia.uniroma3.it/~java/fondinf/ Algoritmi di Ordinamento 41

Ordinamento per fusione

Algoritmo di ordinamento per fusione(merge sort)

se la sequenza da ordinare contiene un elemento, allora la sequenza viene ordinata direttamente

se invece la sequenza da ordinare contiene due o piùelementi, allora viene ordinata come segue 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

Strategia alla base dell’ordinamento per fusione:divide et impera l’ordinamento di una sequenza lunga può essere ricondotto

all’ordinamento di due sequenze più corte – seguito da una ricostruzione del risultato

http://www.dia.uniroma3.it/~java/fondinf/ Algoritmi di Ordinamento 42

Algoritmo di ordinamento per fusione

Ordina per fusione gli elementi del vettore a da

inf a sup:

if (inf < sup) se c'è più di un elemento tra inf e

sup, estremi inclusi

med = (inf + sup)/2;

ordina per fusione gli elementi di v da inf a med

ordina per fusione gli elementi di v da med+1 a sup

fondi gli elementi di v da inf a med con gli elementi di

v da med+1 a sup (restituendo il risultato nel

sottovettore di v da inf a sup )

http://www.dia.uniroma3.it/~java/fondinf/ Algoritmi di Ordinamento 43

Applicazione completa dell’ordinamento

per fusione

17 24 31 45 50 63 85 96

85 24 63 45 17 31 96 50

85 24 63 45

85 24 63 45 17 31 96 50

17 31 96 50

24 45 63 85 17 31 50 96

24 85 45 63 17 31 50 96

decomposizioni

ordinamenti

(semplici)

fusioni

http://www.dia.uniroma3.it/~java/fondinf/ Algoritmi di Ordinamento 44

Implementazione del merge sort

public static void mergesort(int v[]) { msort(v,0,v.length-1); }

private static void msort(int[] v, int inf, int sup) {

if (inf < sup) {

int med = (inf+sup)/2;

msort(v,inf,med);

msort(v,med+1,sup);

merge(v,inf,med,sup);

}

}

http://www.dia.uniroma3.it/~java/fondinf/ Algoritmi di Ordinamento 45

Algortimo per la fusione di due array

ordinati...

Per effettuare la fusione di due sottovettori ordinati e contigui ottenendo un unico sottovettore ordinato, si utilizzano un vettore di appoggio e due indici per scandire i due sottovettori, e si procede al seguente modo:

Il più piccolo tra i due elementi indicati dai due indici viene copiato nella prossima posizione del vettore di appoggio, e viene fatto avanzare l'indice corrispondente; si continua così fino a quando uno dei due sottovettori non è terminato;

Quando uno dei due sottovettori è terminato si copiano gli elementi rimanenti dell'altro nel vettore di appoggio;

Alla fine si ricopia il vettore di appoggio nelle posizioni occupate dai due sottovettori.

http://www.dia.uniroma3.it/~java/fondinf/ Algoritmi di Ordinamento 46

...Algortimo per la fusione di due array

ordinati

le due sequenze ordinate sono sottosequenze contigue

dell’array a, delimitate da indici passati come parametri

la sequenza ordinata risultato viene temporaneamente

memorizzata nell’array di appoggio a e poi copiata in v

24 85 45 63 ... ... ... ...v

inf supmed

24 45 63 85a

24 45 63 85 ... ... ... ...v

http://www.dia.uniroma3.it/~java/fondinf/ Algoritmi di Ordinamento 47

Implementazione dell’algortimo di

fusione di due array ordinati...private static void merge(int[] v, int inf, int med,

int sup) {

int[] a = new int[sup-inf+1];

int i1 = inf;

int i2 = med+1;

int i = 0;

while ((i1 <= med) && (i2 <= sup)) {

// entrambi i vettori contengono elementi

if (v[i1] <= v[i2]) {

a[i] = v[i1];

i1++;

i++;

}

else {

a[i] = v[i2];

i2++;

i++;}

} ... segue ...

http://www.dia.uniroma3.it/~java/fondinf/ Algoritmi di Ordinamento 48

...Implementazione dell’algortimo di

fusione di due array ordinati

if (i2 > sup) // e' finito prima il secondo pezzo del vettore

for (int k = i1; k <= med; k++) {

a[i] = v[k];

i++;

}

else // e' finito prima il primo pezzo del vettore

for (int k = i2; k <= sup; k++) {

a[i] = v[k];

i++;

}

// copiamo il vettore ausiliario nel vettore originario

for(int k = 0; k < a.length; k++)

v[inf+k] = a[k];

}

http://www.dia.uniroma3.it/~java/fondinf/ Algoritmi di Ordinamento 49

Complessità asintotica dell’ordinamento

per fusione...

discussa in modo informale

Le equazioni di ricorrenza sono strumenti

metodologici per studiare la complessità di algoritmi

ricorsivi: non verrranno trattate in questo corso

rispetto alla lunghezza n dell’array da ordinare

attività dominante

fusione di sottosequenze ordinate

caso peggiore

qualunque

http://www.dia.uniroma3.it/~java/fondinf/ Algoritmi di Ordinamento 50

...Complessità dell’ordinamento per

fusione

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,

complessivamente, è n

il numero di livelli è log2 n

TmergeSort(n) = n log n

17 24 31 45 50 63 85 96

24 45 63 85 17 31 50 96

24 85 45 63 17 31 50 96

fusioni

http://www.dia.uniroma3.it/~java/fondinf/ Algoritmi di Ordinamento 51

Valutazioni quantitative

Ma il merge sort è veramente più efficiente

dei precedenti algoritmi?

http://www.dia.uniroma3.it/~java/fondinf/ Algoritmi di Ordinamento 52

Esercizio

Mostrare l’applicazione dell’ordinamento per

fusione al seguente array

mostrare le varie sottosequenze che vengono

identificate e fuse

mostrare anche l’ordine in cui vengono svolte le

varie operazioni

10 2 16 0 -1 51 4 23 9 8

http://www.dia.uniroma3.it/~java/fondinf/ Algoritmi di Ordinamento 53

Ordinamento veloce: quick sort

L’algoritmo di ordinamento di array più usato in pratica è l’ordinamento veloce (quick sort) se la sequenza contiene un elemento o è vuota, è già ordinata

(non bisogna fare nulla)

se invece S contiene due o più elementi

Si determina un elemento della sequenza che fungerà da discriminante degli elementi della sequenza: il pivot.

L’array verrà partizionato in due sottosequenze (nonnecessariamente della stessa lunghezza)

• Quella più a sinistra conterrà tutti gli elementi minori o uguali del pivot

• Quella più a destra conterrà tutti gli elementi maggiori o uguali del pivot

• Alle due sottosequenze così ottenute verrà nuovamente applicato il quick sort

http://www.dia.uniroma3.it/~java/fondinf/ Algoritmi di Ordinamento 54

Applicazione dell’ordinamento veloce

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 65 96

16 31 45 50 58 65 67 96

http://www.dia.uniroma3.it/~java/fondinf/ Algoritmi di Ordinamento 55

Complessità dell’ordinamento veloce

È stato dimostrato che l’ordinamento veloce ha complessità asintotica:

O(n2) nel caso peggiore

O(n log n) nel caso medio

O(n log n) nel caso migliore

L’ordinamento veloce viene solitamente preferito all’ordinamento per fusione perché è molto probabile che si verifichi il caso medio

il fattore moltiplicativo del termine n log n per l’ordinamento veloce nel caso medio è minore del fattore moltiplicativo del termine n log nnell’ordinamento per fusione

http://www.dia.uniroma3.it/~java/fondinf/ Algoritmi di Ordinamento 56

Risultati sperimentali

Tempi medi di esecuzione, in secondi

http://www.dia.uniroma3.it/~java/fondinf/ Algoritmi di Ordinamento 57

Generazione di un array casuale di dati

Metodo usato per generare in modo casuale gli

array da ordinare

/* Crea un array di n numeri casuali. */

public static int[] randomIntArray(int n) {

// pre: n>=0

int[] a; // array di numeri casuali

int i; // indice per la scansione di a

/* crea l'array a */

a = new int[n];

/* assegna valori casuali agli elementi di a */

for (i=0; i<n; i++)

/* numeri causali compresi tra 0 e 10*n-1 */

a[i] = (int) (10*n*Math.random());

return a; }

http://www.dia.uniroma3.it/~java/fondinf/ Algoritmi di Ordinamento 58

Esercizi

Scrivere un metodo che, ricevendo come

parametro un array di oggetti Rettangolo,

ordina l’array in modo non decrescente

rispetto all’area dei rettangoli

Scrivere un metodo che, ricevendo come

parametro un array di oggetti Rettangolo,

ordina l’array in modo non decrescente

rispetto alla base dei rettangoli

a parità di base, i rettangoli vanno ordinati per

altezza non decrescente

http://www.dia.uniroma3.it/~java/fondinf/ Algoritmi di Ordinamento 59

Esercizi

Scrivere un metodo void mischia(int[] a) che

modifica, in modo casuale, l’ordine degli

elementi all’interno di a

2 16 9 4 1 10 8 0 23 51

10 2 16 0 1 51 23 4 9 8

mischia

http://www.dia.uniroma3.it/~java/fondinf/ Algoritmi di Ordinamento 60

Esercizio

SORT ? QUIZ

Indovina quale metodo di ordinamento è stato

usato per ordinare in modo crescente un array

di interi di cui si conoscono le diverse

successive configurazioni dopo ogni passata

http://www.dia.uniroma3.it/~java/fondinf/ Algoritmi di Ordinamento 61

Quale metodo di ordinamento è stato

usato ?

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

http://www.dia.uniroma3.it/~java/fondinf/ Algoritmi di Ordinamento 62

Applicazione completa

dell’ordinamento a bolle

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

http://www.dia.uniroma3.it/~java/fondinf/ Algoritmi di Ordinamento 63

Quale metodo di ordinamento è stato

usato ?

17 24 31 45 50 63 85 96

85 24 63 45 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

24 45 63 85 17 31 50 96

http://www.dia.uniroma3.it/~java/fondinf/ Algoritmi di Ordinamento 64

Applicazione completa

dell’ordinamento per fusione

17 24 31 45 50 63 85 96

85 24 63 45 17 31 96 50

85 24 63 45

85 24 63 45 17 31 96 50

17 31 96 50

24 45 63 85 17 31 50 96

24 85 45 63 17 31 50 96

decomposizioni

ordinamenti

(semplici)

fusioni

http://www.dia.uniroma3.it/~java/fondinf/ Algoritmi di Ordinamento 65

Quale metodo di ordinamento è stato

usato ?

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

http://www.dia.uniroma3.it/~java/fondinf/ Algoritmi di Ordinamento 66

Applicazione dell’ordinamento

per selezione

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

http://www.dia.uniroma3.it/~java/fondinf/ Algoritmi di Ordinamento 67

Quale metodo di ordinamento è stato

usato ?

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

http://www.dia.uniroma3.it/~java/fondinf/ Algoritmi di Ordinamento 68

Applicazione completa dell’ordinamento

per inserzione

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

http://www.dia.uniroma3.it/~java/fondinf/ Algoritmi di Ordinamento 69

Riferimenti al libro di testo

Per lo studio di questi argomenti si fa

riferimento al libro di testo, e in particolare al

Capitolo 24