Didattica della programmazione I
Prof. Giulio Giunta
Algoritmi di ordinamento
Calzetta Emilia
Cervone Vincenzo
ALGORITMI DI ORDINAMENTO
Contenuti:
Algoritmi di ordinamento iterativi e ricorsivi
Ordinamento per inserimento: Insertion-sort
Ordinamento per selezione del min/max: Selection-sort
Ordinamento a bolle: Bubble-sort
Analisi della complessità nel contare gli scambi e i confronti (caso peggiore)
Analisi comparata
Simulazioni in linguaggio VB
Riferimenti:
Cormen, Leiserson, Rivest- Introduzione agli algoritmi -McGrawHill
ALGORITMI DI ORDINAMENTO
Classe: 3^ I.T.I.S.
Prerequisiti:
Conoscenze sull’organizzazione dei dati mediante la struttura vettoriale
Conoscenze della teoria della ricorsione e dell’iterazione
Conoscenze della teoria e implementazione degli algoritmi
Conoscenze del linguaggio Visual Basic e delle Macro di Excel
Obiettivi:
Saper gestire l’organizzazione e ordinamento dei dati in un vettore
Capire l’importanza dell’ordinamento dei dati
Utilizzare le strutture di iterazione e ricorsione
Analizzare le applicazioni relative agli argomenti teorici affrontati
Modalità di lavoro:
lezioni frontali
utilizzo del laboratorio
ALGORITMI DI ORDINAMENTO
Ordinamento di una sequenza
Una sequenza è un insieme di elementi omogenei tra loro.
Ordinare una sequenza di elementi in ordine crescente (non-decrescente)
significa disporre gli elementi in modo da averli in ordinati in base al loro
valore dal più piccolo al più grande da sinistra a destra.
sequenza iniziale
(C,A,D,A,E,G,B,M,C)
sequenza ordinata (A,A,B,C,C,D,E,G,M)
La sequenza ordinata contiene gli stessi elementi della sequenza iniziale e ogni
elemento appare con la stessa molteplicità nelle due sequenze.
Una sequenza (a1,a2,…,an-1,an) è ordinata (sorted) se a1 ≤ a2 ≤ … ≤ an-1 ≤an
se e solo se il valore di ai è minore di quello di ai+1
oppure ai e ai+1 hanno lo stesso valore
4
ALGORITMI DI ORDINAMENTO
Ordinamento di un vettore
Un vettore (array) rappresenta un insieme di elementi dello stesso tipo: gli
elementi si distinguono uno dall’altro mediante un indice. L’insieme dei valori
assumibili dagli indici di un’array dipende dal numero complessivo degli
elementi dell’array (SIZE)
A = 10 2 13 7
1
2
3
4
Dato un vettore A di interi, ordinarlo in modo crescente (non-decrescente)
significa trasformarlo in modo tale che, per ogni indice i, l’elemento A[i] sia
minore o uguale di tutti gli altri elementi di indice j, con i<j
Esempio:
A = 10
2
13
7
Vettore iniziale
2
4
7
13
Vettore ordinato
A=
A[i] ≤ A[j] con i, j=1, …,4 , i<j
5
ALGORITMI DI ORDINAMENTO
Importanza dell’ordinamento (1)
“Un ordine perfetto è il fondamento di tutte le cose”
(Edmund Burke 1729-1797)
L’accesso a collezioni di dati ordinate in modo opportuno è più semplice che
non l’accesso a collezioni non ordinate.
A che servirebbe un elenco telefonico se gli utenti fossero elencati in ordine
sparso?
Anche nei calcolatori, è spesso utile gestire collezioni di dati ordinate
secondo un qualche criterio di ordinamento, questo ad esempio permette di
usare algoritmi di ricerca più efficienti (ricerca binaria)
6
ALGORITMI DI ORDINAMENTO
Importanza dell’ordinamento (2)
La tecnica di ricerca binaria, rispetto alla ricerca esaustiva, consente di
eliminare ad ogni passo metà degli elementi del vettore
2
5
11
primo
15 19 28 35 41 50
ultimo
chiave = 11
primo=1; ultimo=9; trovato=false
primo=3;
trovato
ultimo=4;
= true
trovato=false
primo=1;
ultimo=4;
trovato=false
mediano=(9+1)/2=5;
mediano=(4+1)/2=2;
elenco[5]=19
mediano=(3+4)/2=3;
elenco[2]=5
elenco[3]=11
11<19 ---> primo =1; ultimo=4
11>5 ---> primo= 2+1=3
Elemento è stato trovato nella terza
locazione dell’array: indice=3
Iterazione:2
Iterazione:3
Iterazione:1
ultimo
procedure r_bin(in:n,elenco,chiave;
out:trovato,indice)
var elenco: array(1..n) of character
var chiave: character
var n,indice,mediano,primo,ultimo:
integer
var trovato: logical
begin
primo:=
primo:=1;
1;ultimo:=
ultimo:=n;
n;trovato:=
trovato:=false
false
repeat
mediano
mediano
:=
:=
(primo+ultimo)/2
(primo+ultimo)/2
mediano
:=
(primo+ultimo)/2
chiave == elenco(mediano)
elenco(mediano) then
then
ifif chiave
trovato :=
:= true
true
trovato
else
ififchiave
chiave<<elenco(mediano)
elenco(mediano)then
then
ultimo
ultimo:=:=mediano
mediano- -11
else
primo :=
:= mediano
mediano ++ 11
primo
endif
endif
until trovato or primo = ultimo
indice
indice :=
:= mediano
mediano
end
7
ALGORITMI DI ORDINAMENTO
Chiave di ordinamento
Il valore su cui si effettua l’ordinamento di un insieme di elementi si
definisce chiave (key) di ordinamento. Nel caso si desideri ordinare insiemi
di variabili con differenti tipi di valori (record o strutture) occorre definire
bene la chiave dell’ordinamento.
Esempio:
Ordinamento per cognome e nome
(Es. ordinamento alfabetico del
registro di classe)
Ordinamento per media
(con valori ripetuti)
type studente : record
cognome: character
nome : character
matricola : integer
media : integer
end
var stud1,stud2,stud3,stud4,stud5: studente
8
ALGORITMI DI ORDINAMENTO
Problema: ordinare in ordine crescente un insieme di studenti considerando
le chiavi di ordinamento:
Key1=cognome; Key2=nome; Key3=matricola; Key4=media scolastica;
Key1
Verdi
Bianchi
Russo
Key2
Key3
Mario
00130
Antonio
00134
Carlo
00120
Key4
6
9
1
2
Neri
Bianchi
Gianni
Esposito
Luca
00127
00140
6
8
5
00124
7
3
4
5
6
Marco
Ordinamento crescente per matricola
Key1
Russo
Neri
Verdi
Mario
Bianchi
Antonio
Esposito
Marco
Bianchi
Gianni
Key2
Carlo
Key3
00120
00124
00127
00130
00134
00140
Key4
6
7
8
6
9
5
1
2
3
4
5
6
Luca
9
ALGORITMI DI ORDINAMENTO
Key1
Verdi
Bianchi
Russo
Bianchi
Esposito
Neri
Key2
Mario
Antonio
Carlo
Gianni
Luca
Marco
Key3
00130
00134
00120
00127
00140
00124
Key4
6
9
6
8
5
7
1
2
3
4
5
6
Ordinamento crescente per media scolastica
Key1
Esposito
Verdi
Russo
Neri
Bianchi
Bianchi
Key2
Luca
Mario
Carlo
Marco
Gianni
Antonio
Key3
00140
00130
00120
00124
00127
00134
Key4
5
6
6
7
8
9
1
2
3
4
5
6
Ordinamento crescente per cognome e nome
Key1
Bianchi
Bianchi
Esposito
Neri
Russo
Verdi
Key2
Antonio
Gianni
Luca
Marco
Carlo
Mario
Key3
00134
00127
00140
00124
00120
00130
Key4
9
8
5
7
6
6
1
2
3
4
5
6
10
ALGORITMI DI ORDINAMENTO
Iterazione e ricorsione (1)
Gli algoritmi di ordinamento possono essere iterativi e ricorsivi
Iterazione: ripetere piu’ volte una sequenza di operazioni
Esempio: somma i primi n interi: ( ( ( (1) + 2) +3)+…+ n)
for (i=1, i<=n, i++) somma=somma +i
La caratteristica fondamentale di un algoritmo ITERATIVO è che a ogni passo
è disponibile un risultato parziale: dopo k passi, si ha a disposizione il
risultato parziale relativo al caso k
11
ALGORITMI DI ORDINAMENTO
Iterazione e ricorsione (2)
Gli algoritmi ricorsivi si basano sulla possibilità di definire una funzione in
termini di se stessa.
Una funzione è definita ricorsivamente quando nella sua definizione
compare un riferimento a se stessa.
Esempio: somma i primi n iteri
Sn= n + Sn-1 = n + somma dei primi (n-1) numeri interi
Risolvere un problema con un approccio ricorsivo comporta
• di identificare un “caso base” la cui soluzione sia nota
• di riuscire a esprimere la soluzione al caso generico n in termini dello
stesso problema in uno o più casi più semplici (n-1, n-2, etc).
12
ALGORITMI DI ORDINAMENTO
Esempio di funzione ricorsiva:
Sn= n + Sn-1
somma dei primi n iteri
n + soluzione del problema della somma dei primi (n-1) iteri
“somma dei primi (n-1) interi” è una istanza più semplice del problema
“somma dei primi n interi” e tale istanza può essere scomposta, a sua volta, in
un’istanza ancora più semplice
Sn= n+(n-1)+Sn-2
Procedendo in queste scomposizioni si giunge fino all’istanza banale del
problema S1= 1
Sn= n+(n-1)+(n-2)+(n-3)+…+1
Osserviamo che nella ricorsione, a differenza dell’iterazione, non si dispone
di un risultato parziale finché non si è giunti fino all’istanza elementare
13
ALGORITMI DI ORDINAMENTO
Selection-sort (ordinamento per selezione)
Sia A un array di n elementi da ordinare. L’ algoritmo selection-sort seleziona
l’elemento con valore minore e lo scambia con il primo elemento. Tra gli n-1
elementi rimasti viene poi ricercato quello con valore minore e scambiato con
il secondo e così di seguito fino all’ultimo elemento.
METODO:
Iteriamo i seguenti passi:
•l’array A è diviso in 2 parti
Parte iniziale ordinata | parte da ordinare
•cerchiamo l’elemento minimo nella parte non ordinata e lo scambiamo
con il primo della parte non ordinata
14
ALGORITMI DI ORDINAMENTO
Selection-sort
Parte iniziale ordinata | parte da ordinare
I iterazione:
A[1..n] non ordinato, cerca minimo di
A[1..n] e scambialo con A[1]. Quindi: A[1] | A[2..n]
II iterazione:
A[1] ordinato, A[2..n] non ordinato, cerca minimo di A[2..n] e scambialo con
A[2]. Quindi: A[1]A[2] | A[3..n]
generica iterazione:
A[1..i-1] ordinato, A[i..n] non ordinato,
cerca minimo di A[i..n] e scambialo con A[i].
Quindi: A[1..i-1] A[i]| A[i+1,..n]
Per i=n-1: A[1..n-2] | A[n-1],A[n]
cerca il minimo tra A[n-1] e A[n], scambialo con A[n-1]
ARRAY A ORDINATO!
15
ALGORITMI DI ORDINAMENTO
Esempio selection-sort:
Sia A un array di 6 elementi da ordinare in modo crescente
j=2
11
11
1
5
11
1
7
j=3 j=4
j=3
j=4 j=5
15 15
11
11
7 19
min=1
min=2
min=2min=3
min=3
min=4 min=5
La parte sinistra del
vettore è già ordinata
1
5
15
11
7
temp
j=6
j=6
i=4
i=2
i=5
i=1
i=3
SelectionSort(A, min,
temp)
for i=1 to n-1 do
min
:=
min
:=
iii i i i
min
min
min
min
:=
:=
:=
:=
for j=i+1 to n do
for
for
for
j=i+1
j=i+1
j=i+1
j=i+1
to
to
ton
to
nndo
do
ndodo
forfor
j=i+1
to
n
do
If A(min)>A(j)
If
A(min)>A(j)
IfA(min)>A(j)
A(min)>A(j)
IfIfIfA(min)>A(j)
A(min)>A(j)
then
then
then
thenthen
then
min
min
min
min
:=
:=
:=
jj:=
jj j := j
min
min
:=
endif
endif
endif
endif
endif
endif
endfor
temp
==A[min]
temp
temp
temp
==A[min]
A[min]
A[min]
A[min]
= A[i]
A[min]
A[min]
A[min]
===A[i]
A[i]
A[i]
A[i] A[i]
=A[i]
temp
A[i]
===temp
temp
temp
endfor
16
Problema:
ALGORITMI DI ORDINAMENTO
Sviluppare un algoritmo di selection sort basato sulla selezione del
massimo per ordinare in modo crescente un array A di n elementi
for i=n,2 step=-1 do
determinare l’elemento massimo
della porzione 1..i dell’array
metterlo all’ultimo posto della
porzione
endfor
procedure ord_sel_max(in:n;
inout:a)
var n,indice_max:integer
var a:array(1..n)of character
begin
for i=n,2 step=-1 do
indice_max := 1
for k=2,i do
if a(indice_max)<a(k)then
indice_max := k
endif
endfor
scambiare_c(a(i),a(indice_max))
endfor
end
17
ALGORITMI DI ORDINAMENTO
Analisi del selection-sort (1)
L’operazione dominante per il selection-sort è il confronto tra coppie di
elementi, per n-1 volte bisogna determinare il minimo tra gli elementi non
ordinati e se necessario effettuare uno scambio:
Durante la prima iterazione bisogna effettuare n-1 confronti per determinare
il minimo tra gli n elementi.
Durante
la
seconda
iterazione
bisogna
effettuare
n-2
confronti
per
determinare il minimo tra gli n-1 elementi.
….
18
ALGORITMI DI ORDINAMENTO
Analisi del selection-sort (2)
Durante la n-1 iterazione bisogna effettuare 1 confronti per determinare il
minimo tra 2 elementi.
 n-i = (n-1)+(n-2)+…+2+1 = n(n-1)/2
n-1
Quindi il numero di confronti è :
i=1
Per cui il tempo di esecuzione dell’algoritmo tende a n2
Il comportamento del selection-sort è indipendente dall’ordine
preesistente nell’array da ordinare: il caso peggiore (array ordinato in
ordine decrescente) e quello migliore coincidono (array ordinato in ordine
crescente)
19
ALGORITMI DI ORDINAMENTO
Insertion-sort (ordinamento per inserimento)
L’insertion-sort è un algoritmo molto semplice che si basa sul metodo usato
per ordinare le carte da gioco: “per ordinare le carte nelle tue mani estrai
una carta, scala le carte rimanenti, e inserisci la carta estratta nel posto
corretto tra quelle già considerate e ordinate”
Analogamente per ordinare un vettore di interi a[1…n] in ordine crescente,
consideriamo il primo elemento come un sottovettore ordinato e inseriamo
gli elementi a[2],…,a[n] uno dopo l’altro nella giusta posizione tra quelli già
considerati e ordinati
20
ALGORITMI DI ORDINAMENTO
Metodo Insertion-sort:
• ordinare i primi 2 elementi (porzione 1..2);
•ordinare i primi 3 elementi (porzione 1..3), inserendo il terzo elemento
nella posizione corretta rispetto ai precedenti;
•ordinare i primi 4 elementi (porzione 1..4), inserendo il quarto elemento
nella posizione corretta rispetto ai precedenti;
•……
•ordinare i gli n elementi (porzione 1..n),inserendo l’ennesimo elemento
nella posizione corretta rispetto ai precedenti
21
ALGORITMI DI ORDINAMENTO
Esempio: Sia A il vettore da ordinare.
Ordiniamo i primi 2 elementi (porzione 1-2); poi ordiniamo gli elementi dalla
terza posizione in poi inserendoli nella posizione corretta rispetto ai precedenti
j=0
j=0 j=1
j=1 j=2
j=2 j=3
j=3 j=4
A
j=5
InsertionSort(A,n, temp)
for i=2 to n do
temp
:=:=a(i)
11
5 11
1
11 11
5
1 11
11
7
15 15
7 19
i=2
i=3
i=4
i=5
i=6
temp
temp
temp
:=
:=
a(i)
a(i)
a(i)
j :=
j j:=
ji-1
:=
:=
i-1
i-1
i-1
while j>=1 and temp<a(j)
i=2
i=3 i=4
i=5 i=6
a(j+1)
:=
a(j)
La
Lacondizione
condizione
condizione
a(j+1)
a(j+1)
a(j+1)
:=
:=:=
a(j)
a(j)
a(j)
La
La condizione
falsa
falsa
j:=
:=
j-1
èèèfalsa
è falsa
jj:=
j:=
j-1
j-1
j-1
end while
19
7
15
5
1
a(j+1) :=
:= temp
temp
a(j+1)
a(j+1)
:=
temp
temp
endfor
endfor
end
L’insertion-sort è un algoritmo di ordinamento stabile
22
ALGORITMI DI ORDINAMENTO
Il metodo di ordinamento ad inserzione si basa sull'idea che un vettore
ordinato si ottiene inserendo le sue componenti una per una "al posto
giusto".
Non si introduce un secondo vettore, ma si "simula" l‘inserzione degli
elementi nel vettore dato (ordinamento in loco).
L’insertion-sort è un algoritmo stabile
23
ALGORITMI DI ORDINAMENTO
Algoritmi di ordinamento stabili
Se nell’array da ordinare ci sono due o più elementi con lo stesso valore,
allora tali elementi compaiono nell’array di output nello stesso ordine in
cui compaiono in quello di input. (Algoritmo Stabile)
Esempio (Alg. Stabile) : ordinare un vettore di voti scolastici
voto Carlo
voto Luca
voto Gina
voto Rita
voto Mario
voto Paolo
a[1]
a[2]
a[3]
a[4]
a[5]
a[6]
5
7
5
voto Carlo
8
5
voto Rita
5
6
6
7
voto Mario voto Luca
7
7
voto Paolo
8
voto Gina
Si conserva l’ordinamento sul nome!
24
ALGORITMI DI ORDINAMENTO
Problema:
Verificare che l’algoritmo di selection sort basato sulla selezione del massimo
per ordinare in modo crescente un array A di n elementi non è stabile
voto Carlo
voto Luca
5
7
voto Gina
8
voto Rita
voto Mario
5
6
voto Paolo
7
for i=n,2 step=-1 do
determinare l’elemento massimo
della porzione 1..i dell’array
metterlo all’ultimo posto della
porzione
endfor
voto Carlo voto
votoMario
Rita
Luca
a[1]
a[2]
voto
votoGina
Paolo
Rita
voto Rita
voto Mario
voto Paolo
a[3]
a[4]
a[5]
a[6]
Si perde l’ordinamento sul nome: algoritmo non-stabile
5
5
voto Rita
75
6
5
8
7
5
6
5
7
voto Carlo voto Mario voto Paolo
6
7
voto Luca
7
8
i=5i=4
i=6 i=3
i=2
voto Gina
25
ALGORITMI DI ORDINAMENTO
Analisi delle prestazioni dell’insertion-sort (1)
L’operazione dominante per l’algoritmo è il confronto tra coppie di elementi.
L'ordinamento per inserimento inserisce gli elementi lavorando meno se essi
sono gia' parzialmente ordinati.
Il caso migliore si ha quando il vettore è già ordinato in modo crescente in tal
caso bastano n-1 confronti.
Il caso peggiore si ottiene invece nel caso in cui la sequenza di elementi si
presenta in ordine inverso, cioè quando l’array è ordinato in modo
decrescente, perchè in questo caso il numero di confronti sarà pari al
numero di elementi già ordinati.
26
ALGORITMI DI ORDINAMENTO
Analisi delle prestazioni dell’insertion-sort(2)
Analizziamo il caso peggiore considerando l’ordinamento delle carte da
gioco:
 l’insertion-sort durante la prima passata esegue un confronto con
con la carta più a sinistra nell’array
 durante la seconda passata esegue due confronti con le due carte
più a sinistra dell’array);
 durante la n-1 esima passata vengono eseguiti al più n-1 confronti
Quindi il numero di confronti totali su di un array di dimensione n è:
n-1
 i = 1 + 2 + 3 + ... + n-1 = n(n-1)/2
i=1
27
ALGORITMI DI ORDINAMENTO
Bubble-sort (ordinamento a bolle)
L’ordinamento a bolle è un algoritmo semplice basato sul metodo degli
scambi.
Si fanno “salire” gli elementi più piccoli verso l’inizio del vettore
scambiandoli con quelli adiacenti.
Si procede confrontando gli elementi a coppie e ogni qualvolta si trova una
coppia non ordinata si scambiano di posto i due elementi.
Dato il vettore A[n], si opera confrontando A[1] con A[2] e se A[1] è maggiore
di A[2], si effettua uno scambio tra i due; vengono poi confrontati A[2] con
A[3], A[3] con A[4], …A[n-1] con A[n] scambiando di posto quegli elementi
che non formano coppie ordinate.
28
ALGORITMI DI ORDINAMENTO
Bubble-sort (ordinamento a bolle)
Alla fine dell’esecuzione del primo ciclo di operazioni l’elemento più grande
si trova automaticamente in ultima posizione in quanto gli elementi più
piccoli sono "risaliti" nel vettore come delle bolle (da qui la definizione di
Bubble-Sort).
Successivamente, al termine del secondo ciclo di operazioni, l’elemento
maggiore tra A[1], A[2],….A[n-1] sarà posizionato alla penultima (n-1)
posizione; si procede in questo modo finchè non ci saranno più valori da
scambiare (array ordinato)
29
ALGORITMI DI ORDINAMENTO
Esempio: Sia A il vettore da ordinare
BubbleSort(A,n,scambio,temp)
i:=1
repeat
La condizione
è falsa
j=2
A
11
5
1
j=3
j=4
j=4 j=5
11
11 11
1
5
1 11
11
7
15
7 15
7 19
15
Scambio=0
j-1=1
j-1=1j-1=2j-1=3
j-1=3
j-1=4
Vettore Ordinato!
5
1
7
7
temp
Scambio=0
Scambio=1
scambio:=
scambio:=00
for j=i+1 to n do
if (A[j] < A[j-1]) then
temp:=A[j]
temp:=A[j]
A[j]:=A[j-1]
A[j-1]:=temp
A[j-1]:=temp
scambio:=1
scambio:=1
endif
endfor
until scambio=0
end
Il bubble-sort è un algoritmo stabile come l’insertion-sort
30
ALGORITMI DI ORDINAMENTO
Analisi delle prestazioni del bubble-sort(1)
Nel bubble sort l’operazione dominante è il confronto tra coppie di
elementi, l’operazione di scambio degli elementi viene eseguita meno
spesso rispetto al confronto degli elementi e ha lo stesso costo.
L’algoritmo BubbleSort esegue un numero di operazioni variabili a seconda
dell’ordinamento già presente nel vettore
Il caso migliore si ha quando l’array è già ordinato ed è sufficiente
effettuare solo un ciclo per verificare che tutti gli elementi sono ordinati,
quindi sono sufficienti n-1 confronti.
Il caso peggiore si ha quando gli elementi nell’array sono ordinati in senso
decrescente.
31
ALGORITMI DI ORDINAMENTO
Analisi delle prestazioni del bubble-sort(1)
Nel caso peggiore il bubble sort effettua i seguenti confronti:
 Durante il primo ciclo vengono eseguiti n-1 confronti e altrettanti
scambi
 Durante il secondo ciclo vengono eseguiti n-2 confronti e altrettanti
scambi
 Durante il terzo ciclo vengono eseguiti n-3 confronti e altrettanti
scambi
 ….
 Durante l’n-esimo ciclo viene eseguito un confronto e uno scambio
Quindi nel caso peggiore il numero di confronti e scambi su di un array di
dimensione n è:
 (n-i) = n  1 -  i = n(n-1)-n(n-1)/2 = n(n-1)/2
n=1
n=1
n=1
i=1
i=1
i=1
32
ALGORITMI DI ORDINAMENTO
Algoritmi di ordinamento ricorsivi
“DIVIDE ET IMPERA”dicevano i latini: sia con il significato che una
volta conquistato un nuovo territorio è meglio tenere diviso il popolo, se è
ostile, per evitare rivolte e sovversioni; sia con il significato di
partizionare il territorio per amministrarlo meglio.
Il motto latino ‘Divide et Impera’ è stato acquisito dall’informatica come
tecnica per risolvere problemi complessi, in pratica si genera una
sequenza di istanze via via più semplici del problema, fino all'istanza che
non è più suddivisibile e che ha soluzione banale
33
ALGORITMI DI ORDINAMENTO
Selection-Sort ricorsivo
Gli algoritmi di ordinamento visti finora possono essere realizzati anche con
metodi ricorsivi. La ricorsione è un metodo molto più elegante
dell’iterazione
La versione ricorsiva del Selection-Sort si basa su di un idea molto semplice:
ordina il vettore = metti il minimo all'inizio + ordina il resto del vettore
Alla prima invocazione bisogna ordinare tutto il vettore, alla seconda tutto
tranne il primo, poi tutto tranne il secondo, ecc.
Useremo un parametro ‘inizio’ per ordinare il vettore a partire dall'indice
‘inizio’ fino alla fine, ordinando la parte di vettore:
A[inizio], A[inizio+1], ... , A[A.length-1]
34
ALGORITMI DI ORDINAMENTO
Algoritmo ricorsivo del Selection-Sort
SelectRic(int A[], int inizio)
Metodo ricorsivo Selection-Sort:
Metto il minimo in prima posizione, poi
ordino quello che resta del vettore.
{
int i, minpos; minpos=inizio;
Cerco il minimo fra A[inizio],
A[inizio+1], ... , A[A.length-1]
for(i=inizio; i<A.length; i++)
{
if(A[i]<A[minpos])
Lo metto in A[inizio] (faccio lo
scambio)
Faccio la chiamata
passando inizio+1
minpos=i;
int temp=A[inizio];
ricorsiva
A[inizio]=A[minpos];
A[minpos]=temp;
}
Manca ancora
ricorsione!
il
caso
base
della
SelectRic(A, inizio+1);
}
35
ALGORITMI DI ORDINAMENTO
Selection-Sort caso base:
Ogni volta che viene richiamata la funzione
SelectRic (invocazione del metodo), la parte
di vettore da ordinare ha un elemento in
meno.
Alla fine si arriva al vettore di un elemento,
questo succede quando inizio è l'ultimo
elemento del vettore.
SelectRic(int A[], int inizio)
{
int i, minpos;
if(inizio>=A.length-1) return;
minpos=inizio;
for(i=inizio; i<A.length; i++)
if(A[i]<A[minpos])
minpos=i;
int temp=A[inizio];
In pratica: inizio aumenta di uno a ogni
invocazione ricorsiva e quando arriva alla
fine si deve ordinare la parte di vettore con
un elemento solo (che è già banalmente
ordinato!)
A[inizio]=A[minpos];
A[minpos]=temp;
SelectRic(A, inizio+1);
}
36
ALGORITMI DI ORDINAMENTO
Bubble-Sort ricorsivo
Nell’ordinamento a bolle dobbiamo far risalire gli
elementi più leggeri (più piccoli) fino alla cima
del vettore.
Il ciclo for mette il massimo alla fine, dopo aver
fatto questo, resta da ordinare il resto del
vettore (tutto tranne l'ultimo elemento).
Nella chiamata ricorsiva viene specificato dove il
vettore termina (cioè dove finisce la parte di
vettore da ordinare)
Faccio il ciclo di confronti, che mette il
massimo alla fine.
Faccio l’ invocazione ricorsiva su tutto il
vettore tranne l’ultimo elemento.
BubbleRic(int A[], int fine)
{
int i, temp;
for(i=0; i<=fine-1; i++)
if(A[i]>A[i+1]) {
temp=A[i]; A[i]=A[i+1];
A[i+1]=temp;
}
BubbleRic(A, fine-1);
}
Manca il caso base!
37
ALGORITMI DI ORDINAMENTO
Bubble-Sort: caso base
BubbleRic(A[], fine) {
int i, temp;
La parte di vettore da ordinare diventa
sempre più piccola a ogni invocazione
ricorsiva.
if(fine==0) return;
// CASO BASE
for(i=0; i<=fine-1; i++)
if(A[i]>A[i+1]) {
Alla prima invocazione fine vale A.length-1
poi diminusce di uno, poi ancora di uno,
ecc.
Quando fine==0 la parte di vettore da
ordinare è il solo primo elemento (che è
già ordinato!)
temp=A[i];
A[i]=A[i+1];
A[i+1]=temp;
}
BubbleRic(A, fine-1);
}
38
ALGORITMI DI ORDINAMENTO
Insertion-Sort ricorsivo
L’idea di ordinamento è simile al modo che, durante una partita a carte,
si usa per ordinare le carte nella propria mano.
 Si inizia con la mano vuota e le carte capovolte sul tavolo
 Poi si prende una carta alla volta dal tavolo e si inserisce nella
giusta posizione
 Per trovare la giusta posizione per una carta, la confrontiamo con
le altre carte nella mano, da destra verso sinistra. Ogni carta più
grande verrà spostata verso destra in modo da fare posto alla carta
da inserire.
L’insertion-Sort è uno algoritmo di ordinamento molto efficiente per
ordinare un piccolo numero di elementi
39
ALGORITMI DI ORDINAMENTO
INSERTION SORT RICORSIVO
start from = 1
insertion_sort( A, from, to)
{
if ( from+1 > to ) { // CASO BASE from > to il vettore è ordinato
temp = A[from+1]);
i = from;
while ( i>0 AND A[i] > temp) { // passo base
A[i+1]=A[i]; i=i-1;
}
A[i+1] = temp;
insertion_sort( A , from+1, to) // RICORSIONE
}
}
40
ALGORITMI DI ORDINAMENTO
Prestazioni degli algoritmi di ordinamento
(risultati sperimentali)
Un altro modo per confrontare le prestazioni degli algoritmi di
ordinamento consiste, semplicemente, nell’eseguire molti test per ogni
algoritmo al crescere della dimensione n dell’input e nel confrontarne i
tempi di esecuzione misurati tenendo conto dei casi in cui il vettore è
ordinato in modo crescente, decrescente e random.
I tempi sono generalmente espressi nella forma minuti secondi.
Questo tipo di misurazione ha lo svantaggio che i tempi di esecuzione degli
algoritmi dipendono dalle prestazioni della macchina su cui sono eseguiti
(velocità del processore, capacità della memoria centrale), per cui il tempo
di esecuzione di un algoritmo può variare notevolemente se eseguito su
macchine differenti.
41
ALGORITMI DI ORDINAMENTO
Questi sono i risultati forniti da un programma (eseguito su un Pentium 3 di
500 MegaHertz) utilizzato per ordinare con gli algoritmi analizzati in questo
corso un vettore di 15.000 elementi. I tempi sono nella forma minuti
secondi.
42
ALGORITMI DI ORDINAMENTO
Implementazione degli algoritmi di sorting
Gli algoritmi di sorting si possono implementare in svariati modi (Java,
linguaggio C, Visual Basic, MATLAB, etc.) in questo corso abbiamo scelto il
metodo più semplice, cioè le macro di Excel. Questa scelta è mirata a
motivare l’interesse di tutti gli alunni, compresi quelli che potrebbero
ritenere ‘difficile’ l’uso di metodi più sofisticati.
Analizziamo delle semplici simulazioni degli algoritmi di sorting che sono
state sviluppate con le macro di Microsoft Excel
43
ALGORITMI DI ORDINAMENTO
BubbleSort 3-D (curiosità)
Al seguente link è disponibile un algoritmo 3-D per ordinare pixel di colori
con il Bubble sort
http://www.magma.ca/~gtaylor/3dBubbleSort.htm
Eseguibile BubbleSort 3-D
ALGORITMI DI ORDINAMENTO
Riferimenti
http://www.cs.oswego.edu/~mohammad/classes/csc241/samples/sort
/Sort2-E.html
http://faculty.harker.org/robbc/Pages/Software/TheSorter/TheSorter.
htm
http://www.magma.ca/~gtaylor/3dBubbleSort.htm
http://math.hws.edu/TMCM/java/xSortLab/
http://www.geocities.com/SiliconValley/Network/1854/Sort1.html
Scarica

Algoritmi di ordinamento