Algoritimi di Ordinamento PDF

Transcript

Algoritimi di Ordinamento PDF
Algoritmi di Ordinamento
Univ. degli Studi di Cagliari
u
Algoritmi di Ordinamento per Strutture Lineari
Una semplice classe di algoritmi e’ quella degli algoritmi di ordinamento per
strutture lineari.
La classe degli algoritmi di ordinamento in strutture lineari ha una
complessita’ che varia tra O(n ⋅ log n) e O n 2 .
( )
Vedremo i seguenti:
Algoritmo
bubble sort
select sort
Complessita’
( )
O(n 2 )
O n2
( )
quicksort
caso migliore e medio: O(n ⋅ log n), caso peggiore: O n 2
mergesort
O(n ⋅ log n)
Docente G. Armano
Algoritmi di Ordinamento
2
Univ. degli Studi di Cagliari
u
Bubble Sort
Strategia:
Durante il ciclo k-esimo, si confrontano l’elemento corrente e il precedente,
scambiandoli se necessario. L’operazione viene ripetuta su ogni elemento
successivo. L’algoritmo termina quando, durante il ciclo appena completato,
non e’ stato effettuato alcuno scambio. Sono sufficienti, al piu’, N cicli per
sistemare al loro posto tutti gli elementi del vettore.
void exchange ( float *x, float *y)
{ float tmp = *x ; *x = *y ; *y = tmp ; }
void bubbleSort ( Item V[], int NMAX ) /* V1 */
{
int i,j ; int bubble ;
do { bubble = 0 ;
for ( j=1; j < NMAX; j++ )
if ( V[j] < V[j-1] )
{ bubble = 1 ; exchange ( &V[j], &V[j-1] ) ; }
} while ( bubble ) ;
}
Una versione alternativa di bubble sort:
void bubbleSort ( Item V[], int NMAX ) /* V2 */
{
int i, j ;
for ( i=NMAX-1; i > 0 ; i-- )
for ( j=1; j <= i; j++ )
if ( V[j-1] > V[j] ) exchange ( &V[j], &V[j-1] ) ;
}
Docente G. Armano
Algoritmi di Ordinamento
3
Univ. degli Studi di Cagliari
u
Algoritmi di Ordinamento Bubble Sort: Analisi di Complessita’
Consideriamo la versione V2 dell’algoritmo. In tal caso, vengono eseguiti
N-1 cicli di lunghezza k decrescente (da N-1 ad 1). Ad ogni ciclo -di
lunghezza k- vengono spostati (al piu’) k elementi. La corrispondente
relazione di ricorrenza e’ la seguente:
C2 = 1
C N = C N−1 + ( N − 1)
ovvero:
C N = C N−1 + ( N − 1) = (C N − 2 + (N − 2)) + ( N −1) =
= C2 +
+ (N − 2) + ( N − 1) = 1 +
+ ( N − 2) + (N − 1) =
N ⋅ ( N − 1)
2
( )
Quindi, la complessita’ di un’ordinamento bubble sort e’ O n 2 .
Docente G. Armano
Algoritmi di Ordinamento
4
Univ. degli Studi di Cagliari
u
Select Sort
Strategia:
Si cerca il piu’ piccolo elemento del vettore e lo si scambia con l’elemento
in prima posizione. Si ripete la stessa operazione sul resto del vettore. Caso
base: un “vettore” di una sola posizione non necessita di essere ordinato.
void selectSort ( Item V[], int NMAX )
{ int i, j; int jmin ;
for ( i=0; i < NMAX-1; i++ )
{ jmin = i ;
for ( j=i+1; j < NMAX; j++ )
if ( V[j] < V[jmin] ) jmin = j ;
exchange ( &V[i], &V[jmin] ) ; } }
Esercizio:
Scrivere la versione ricorsive dell’algoritmo di select sort. Per trovare il
minimo, si utilizzi la funzione (anch’essa ricorsiva):
int trovaMin ( Item V[], int NMAX ) ;
La funzione trovaMin restituisce l’indice dell’elemento minimo.
Docente G. Armano
Algoritmi di Ordinamento
5
Univ. degli Studi di Cagliari
u
Algoritmi di Ordinamento Select Sort: Analisi di Complessita’
Vengono eseguiti N-1 cicli di lunghezza k decrescente (da N-1 ad 1). Ad
ogni ciclo -di lunghezza k- viene spostato (al piu’) un elemento. Poiche’ il
tempo riservato a controlli e/o scambi viene considerato nello stesso modo
(ha complessita’ costante), non c’e’ nessuna differenza sostanziale con la
complessita’ calcolata per l’ordinamento bubble sort. La corrispondente
relazione di ricorrenza e’ quindi la stessa:
C2 = 1
C N = C N−1 + ( N − 1)
( )
Quindi, la complessita’ di un’ordinamento select sort e’ O n 2 .
Esercizio:
Nonostante il fatto che i due algoritmi abbiano la stessa complessita’, ci
aspettiamo che il tempo di calcolo del select sort sia mediamente piu’ basso
di quello del bubble sort. Perche’... ?
Docente G. Armano
Algoritmi di Ordinamento
6
Univ. degli Studi di Cagliari
u
Quick Sort
Strategia:
E’ un algoritmo che applica la strategia “divide-et-impera”. Il vettore viene
suddiviso in due parti (partition), da ordinare separatamente tramite una
chiamata ricorsiva all’algoritmo stesso. Le due parti vengono preparate
(partition) in modo che -successivamente- non sia necessario comporre i
risultati dei due ordinamenti per ottenere il vettore ordinato (e non e’ detto
che le due parti risultino “bilanciate”).
#define when if
#define loop while(1)
#define loop_exit break
void quickSort ( Item V[], int NMAX )
{ quickSortR ( V, 0, NMAX-1 ) ; }
void quickSortR ( Item V[], int left, int right )
{ if ( left < right )
{ int pivot = partition ( V, left, right ) ;
if ( left < pivot ) quickSortR(V,left,pivot-1) ;
if ( pivot < right ) quickSortR(V,pivot+1,right) ; } }
int partition ( Item V[], int left, int right )
{ int p=left+1, q=right ;
loop
{ while ( V[q] > V[left] ) q-- ;
when ( p >= q ) loop_exit ;
while ( ( p < q ) && ( V[p] < V[left] ) ) p++ ;
when ( p >= q ) loop_exit ;
exchange ( &V[p++], &V[q--] ) ; }
exchange ( &V[left], &V[q] ) ;
return q ; }
Docente G. Armano
Algoritmi di Ordinamento
7
Univ. degli Studi di Cagliari
u
Algoritmi di Ordinamento Quick Sort: Analisi di Complessita’
Nel caso migliore, ad ogni passo, si suddivide il vettore in due sottoparti
uguali (bilanciamento perfetto). Nel caso peggiore, invece, si suddivide il
vettore in due sottoparti di lunghezza, rispettivamente, 1 ed N-1.
Nel caso peggiore la complessita’ si riduce a quella degli algoritmi visti in
precedenza, mentre nel caso migliore la relazione di ricorrenza e’:
C1 = 0
CN ≅ 2 ⋅ CN / 2 + N
Esplicitando tale relazione si ottiene:
N
C N ≅ 2 ⋅ CN / 2 + N = 2 ⋅ 2 ⋅ C N / 4 +
+N =
2
k
= 2 CN / 2 k + k ⋅ N
ovvero:
C N = 2 log 2 N ⋅ C1 + N ⋅ log 2 N = N ⋅ log 2 N
( ) nel caso
Quindi, la complessita’ di un’ordinamento quick sort e’ O n 2
peggiore e O(n ⋅ log n) nel caso migliore.
Docente G. Armano
Algoritmi di Ordinamento
8