Sei sulla pagina 1di 9

2

Algoritmi di ordinamento
 Lo scopo è ordinare in senso [de]crescente il
contenuto di un vettore di N elementi senza
Algoritmi utilizzare un secondo vettore
 Esiste molta letteratura scientifica a riguardo
e molti metodi adatti a vari casi, ma qui si
considerano tre semplici algoritmi di esempio
Ver. 2.4 molto per l’ordinamento in senso crescente (o
meglio, non-decrescente):
 Selection sort
 Bubble sort
 Insertion sort
© 2010 - Claudio Fornaro - Corso di programmazione in C

3 4

Selection sort semplificato - I Selection sort semplificato - II


 Si confronta il primo elemento del vettore con  Se si ripete lo stesso identico procedimento
tutti gli altri, man mano che si trova un valore per tutti gli elementi a partire dal secondo, si
minore del primo, lo si scambia con il primo. determina il secondo valore più piccolo e lo si
Dopo questa operazione il valore minimo è colloca al secondo posto
nella prima posizione
(pos. 0) del vettore è il successivo a 0 è il successivo a 1
for (j= 1; j<N; j++) for (j= 2; j<N; j++)
if (v[j] < v[0]) 5 7 5 4 2 6 if (v[j] < v[1]) 2 7 5 5 4 6
{ {
tmp = v[j]; tmp = v[j];
v[j] = v[0]; 4 7 5 5 2 6 v[j] = v[1]; 2 5 7 5 4 6
v[0] = tmp; v[1] = tmp;
} }
2 7 5 5 4 6 2 4 7 5 5 6
5 6

Selection sort semplificato - III Selection sort semplificato -IV


 Se si ripete lo stesso identico procedimento  Se si ripete questo procedimento per tutti i
per tutti gli elementi a partire dall’i-esimo, si valori di i da 0 fino al penultimo (l’ultimo va a
determina l’i-esimo valore più piccolo e lo si posto da sé) si ottiene l’ordinamento in senso
colloca all’i-esimo posto crescente di tutto il vettore
è il successivo a i
for (i=0; i<N-1; i++)
for (j=i+1; j<N; j++) for (j=i+1; j<N; j++)
if (v[j] < v[i]) if (v[j] < v[i])
{ {
tmp = v[j]; tmp = v[j];
v[j] = v[i]; v[j] = v[i];
v[i] = tmp; v[i] = tmp;
} }

7 8

Selection sort - I Selection sort - II


 Il primo passo è quello di individuare il  Se si ripete lo stesso identico procedimento
minimo tra gli elementi del vettore e per tutti gli elementi a partire dal secondo, si
scambiarlo con quello nella prima posizione, determina il secondo valore più piccolo e lo si
il primo valore è ora al posto giusto colloca al secondo posto
è il successivo a 0 è il successivo a 1
jmin = 0; jmin = 1;
for (j= 1; j<N; j++) for (j= 2; j<N; j++)
if (v[j] < v[jmin]) if (v[j] < v[jmin])
jmin = j; jmin = j;
tmp = v[jmin]; 5 7 5 1 4 3 tmp = v[jmin]; 1 7 5 5 4 3
v[jmin] = v[0]; v[jmin] = v[1];
v[0] = tmp; v[1] = tmp;
1 7 5 5 4 3 1 3 5 5 4 7
9 10

Selection sort - III Selection sort - IV


 Se si ripete lo stesso identico procedimento  Se si ripete questo procedimento per tutti i
per tutti gli elementi a partire dall’i-esimo, si valori di i da 0 fino al penultimo (l’ultimo va a
determina l’i-esimo valore più piccolo e lo si posto da sé) si ottiene l’ordinamento in senso
colloca all’i-esimo posto crescente di tutto il vettore
è il successivo a i for (i=0; i<N-1; i++)
jmin = i; { jmin = i;
for (j=i+1; j<N; j++) for (j=i+1; j<N; j++)
if (v[j] < v[jmin]) if (v[j] < v[jmin])
jmin = j; jmin = j;
tmp = v[jmin]; tmp = v[jmin];
v[jmin] = v[i]; v[jmin] = v[i];
v[i] = tmp; v[i] = tmp;
}

11 12

Bubble sort - I Bubble sort - II


 Se si scorrono tutti gli elementi di un vettore  Ripetendo N-1 volte questa operazione, tutti i
e ogni volta che si trovano due valori valori risalgono verso destra fino ad occupare
ADIACENTI non in ordine (il più piccolo dei 2 la posizione corretta e quindi vengono
a destra del più grande) li si scambia: il più ordinati in senso crescente
grande di tutti risale a destra
3 1 5 7 4 3 for (i=0 ; i<N-1; i++)
for (j=0; j<N-1; j++) for (j=0; j<N-1; j++)
if (v[j] > v[j+1]) if (v[j] > v[j+1])
1 3 5 7 4 3
{ {
tmp = v[j]; tmp = v[j];
v[j] = v[j+1]; 1 3 5 4 7 3 v[j] = v[j+1];
v[j+1] = tmp; v[j+1] = tmp;
} 1 3 5 4 3 7 }
13 14

Bubble sort - III Bubble sort - IV


 Inefficienza: gli ultimi valori vengono in ogni  Inefficienza: se pochi valori sono fuori posto e
caso confrontati, anche quando sono già stati l’ordinamento si ottiene prima delle N-1
collocati; per evitare perdita di tempo in passate, i cicli continuano ad essere eseguiti.
questi controlli inutili si ferma prima della fine Lo si fa terminare se non ci sono stati scambi
il ciclo interno, sfruttando il ciclo esterno scambi = SI;
for (i=N-1; i>0 ; i--) for (i=N-1; i>0 && scambi ;i--)
for (j=0; j<i ; j++) { scambi = NO;
if (v[j] > v[j+1]) for (j=0; j<i ; j++)
{ if (v[j] > v[j+1]) continua solo
tmp = v[j]; { scambi = SI; se ci sono
v[j] = v[j+1]; tmp = v[j]; stati scambi
v[j+1] = tmp; v[j] = v[j+1];
} v[j+1] = tmp; }
}

15 16

Insertion sort - I Insertion sort - II


 Per ciascuno degli elementi a partire dal 2o  for (j=1; j<N; j++)
(l’elemento da sistemare si chiama chiave): {
1. si copia il valore della chiave in una variabile (key) key = v[j];
2-3.si scalano a destra di una posizione tutti gli for (i=j-1; i>=0 && v[i]>key; i--)
elementi precedenti alla chiave finché non ne
viene trovato uno con valore inferiore a key v[i+1] = v[i];
4. al posto di quest’ultimo viene messo key v[i+1] = key;
Notare che gli elementi a sinistra della chiave sono }
sempre già ordinati in senso crescente grazie alle
3 2 passate precedenti

1 5 7 3 4 8 1 3 5 7 4 8
key
4 3 1 ordinati
17 18

Esercizi Algoritmi di ricerca


1. Per ciascuno degli algoritmi di ordinamento  Si vuole cercare un dato valore val in un
precedentemente descritti (variazioni incluse), vettore vett di N elementi
si scriva un programma completo che ordini in  Si possono considerare i due casi:
senso crescente (o meglio, non-decrescente)  vettore non ordinato
un vettore di N numeri interi.  vettore ordinato
2. Si misurino i tempi di esecuzione usando la
funzione clock() in <time.h>
3. Per ciascuno degli algoritmi di ordinamento
precedentemente descritti (variazioni incluse),
si scriva un programma completo che ordini in
senso decrescente (o meglio, non-
crescente) un vettore di N numeri interi.

19 20

Ricerca in vettore non ordinato Ricerca in vettore non ordinato


 Si deve scorrere tutto il vettore in quanto val  Il ciclo termina in 2 casi:
può essere in qualsiasi posizione  è stato trovato il valore
for (i=0; i<N && vett[i]!=val; i++)  ha finito di cercare (invano) in tutti gli elementi
;  Deve stabilire per quale motivo il ciclo è finito
if (i == N)  se trova: i < N
printf("Non trovato\n");  se non lo trova: i = N
else  Non si deve controllare se val è stato trovato
printf("Trovato\n"); verificando la condizione vett[i]=val
 Finché non lo trova, continua a cercare perché se non lo trova i vale N e vett[N]
identifica un elemento inesistente
 Al massimo (nel caso peggiore) fa N controlli
Ricerca in vettore ordinato 21
Ricerca in vettore ordinato 22

Ricerca lineare Ricerca dicotomica (o binaria)


 Non serve scorrere tutto il vettore, ci si ferma left=0; right=N-1;
non appena si supera il valore cercato while (right>=left)
for (i=0; i<N && vett[i]<val; i++) { m=(left+right)/2;
; if (val==vett[m])
break;
if (i<N && val == vett[i])
if (val<vett[m])
printf("Trovato\n");
right=m-1;  elimina la metà destra
else else
printf("Non trovato\n"); left=m+1;  elimina la metà sinistra
 Quando vett[i] >= val il ciclo viene }
interrotto e si controlla se val è stato trovato if (val==vett[m])
printf("Trovato\n");
 Al massimo fa N controlli else
printf("Non trovato\n");

Ricerca in vettore ordinato 23 24

Dicotomica (o binaria) Programmazione a stati


 Inizializza due indici left e right al primo e  Per stato si intende la situazione del
all’ultimo indice del vettore (0 e N-1) programma in un dato istante (es. “sta
 Calcola l’indice del valore centrale: m leggendo i caratteri di una parola”)
 Se vett[m] è il valore cercato, termina  Mentre il programma viene eseguito esso
 Altrimenti se val è minore del valore centrale, cambia di stato in seguito al verificarsi di
arretra l’indice destro right al centro m (così eventi (es. lettura di un carattere da
dimezza il numero di valori in cui cercare) analizzare), la transizione può portare allo
 Altrimenti se val è maggiore del valore stesso stato di partenza (anello)
centrale, avanza l’indice sinistro left al centro
 Ripetendo questa operazione, si dimezza ogni
volta il vettore
 Veloce: al massimo fa log2(N+1) controlli
25 26

Programmazione a stati Programmazione a stati


 Graficamente:  Nel codice l’informazione sullo stato viene
 gli stati sono disegnati come cerchi o ovali mantenuta tramite una variabile di stato, in
 le transizioni sono disegnate come archi orientati genere di tipo enum o int
 nei punti di partenza degli archi si indicano gli  Tipicamente i valori che la variabile di stato
eventi che causano le transizioni di stato
può assumere sono definiti da enum o con
 se appropriato (c’è spazio, non sono troppe
informazioni) sugli archi si indicano anche le azioni
#define
da intraprendere nelle transizioni azione
 Se i valori sono costanti e dagli stati partono
diverse possibili transizioni, lo switch è
azione
evento evento spesso il costrutto di elezione
Stato1 Stato2
evento evento
azione
azione

27 28

Programmazione a stati Programmazione a stati


 Esempio (es. 4 sui file)  La variabile di stato indicherà se si stanno
Si scriva un programma che chieda il nome di leggendo i caratteri di una parola (si è “dentro”
un file contenente un testo qualsiasi e di una parola) o no (si è “fuori” da una parola) e
questo conti quante sono le parole che quindi assumerà 2 possibili valori:
iniziano con ciascuna lettera dell’alfabeto.  DENTRO – FUORI
Esempio di output:  L’evento che può causare il cambiamento di
Parole che iniziano con A: 45 stato è la lettura del carattere successivo
Parole che iniziano con B: 12  In questo esempio ci sono solo 4 casi:
Parole che iniziano con C: 27  stato FUORI e si legge un carattere alfabetico
…  stato DENTRO e si legge un carattere alfabetico
Parole che iniziano con Z: 3  stato DENTRO e si legge un carattere non-alfabetico
 stato FUORI e si legge un carattere non-alfabetico
29 30

Programmazione a stati Programmazione a stati


 Più in dettaglio, se:  Rappresentazione grafica corrispondente
1. stato FUORI e si legge un carattere alfabetico: all’esempio (no-op=no operation):
entra DENTRO e incrementa il contatore di quel car.
no-op
2. stato DENTRO e si legge un carattere alfabetico:
resta DENTRO e non fa nulla incrementa
3. stato DENTRO e si legge un carattere non-alfab.: 1.lettera
contatore lettera 2.lettera
va FUORI dalla parola e non fa nulla
FUORI DENTRO
4. stato FUORI e si legge un carattere non-alfabetico:
resta FUORI e non fa nulla 4.non-lettera no-op 3.non-lettera

no-op

31 32

Esercizi Homework 6
3. (Es. 4 sui file) Si scriva un programma che Si scriva un programma che per ciascuno degli
chieda il nome di un file contenente un testo algoritmi di ordinamento visti (bubble semplice e
qualsiasi e di questo conti quante sono le con variazioni, selection semplificato, selection,
parole che iniziano con ciascuna lettera insertion) per M volte (es. 100) riempia un
dell’alfabeto. vettore di N valori interi casuali (es. 1000) e lo
Lo si risolva con una soluzione a stati. riordini. Il programma deve misurare i tempo
Esempio di output: impiegato per gli M ordinamenti per ciascuno
Parole che iniziano con A: 45 degli algoritmi. Impostare M e N in modo da
Parole che iniziano con B: 12 eseguire un numero significativo di prove con
Parole che iniziano con C: 27 vettori di dimensioni grandi (1000-10000), medi
… (100-1000) e piccoli (100). Trarne le conclusioni.
Parole che iniziano con Z: 3
33

Homework 6
Continuazione:
Includendo <time.h> si possono usare le
seguenti funzioni:
 time(NULL)
restituisce un numero intero di tipo time_t che
corrisponde all’istante attuale
 difftime(time_t t2, time_t t1) restituisce
(come valore double) il numero di secondi
intercorsi tra t1 e t2
Nota: il tipo time_t è in genere un sinonimo di long
e si possono definire variabili di tale tipo:
time_t ora, t1, t2;
t1=time(NULL);

Potrebbero piacerti anche