Sei sulla pagina 1di 28

Algoritmi di Ordinamento

Prof. Giuseppe Riccardi


Dipartimento Ingegneria e Scienza delle Informazioni
Università degli Studi di Trento

Indice

• Algoritmi di Ordinamento
• Insertion Sort
•  Analisi della Complessità
• Merge Sort
•  Analisi della Complessità

1
Motivazione

• Ordinamento di array servono a


rendere efficienti algoritmi
•  Es. Ricerca Binaria Θ (log(n))
•  Es. Ricerca della Mediana Θ (1)

Ordinamento di un archivio

0 1 2 3 4 5 6 7
12 3 5 6 1 14 5 17
Algoritmo
Ordinamento

1 3 5 5 6 12 14 17 Array
Ordinato

2
Algoritmi di Ordinamento

shellsort quicksort

bubblesort selectionsort mergesort insertsort

Algoritmi di Ordinamento

shellsort quicksort

bubblesort selectionsort mergesort insertsort

3
Algoritmo Insertion Sort
•  Algoritmo efficiente per dimensione piccola
dell’archivio
•  Simile a quello usato da giocatori per ordinare carte
1.  Inizia con mano sinistra vuota
2.  Prendiamo una carta alla volta dal tavolo
3.  Inseriamo carta in posizione corretta mano sinistra
1.  Per inserire correttamente confrontiamo la carta con
quelle già presenti, da destra a sinistra
2.  In qualsiasi momento le carte nella mano sinistra sono
ordinate
4.  Si preleva carta dal tavolo finchè mazzo carte non
vuoto

5 2 8 4 7 1 3 6
5 x 8 4 7 1 3 6 2
x 5 8 4 7 1 3 6
2 5 8 4 7 1 3 6
2 5 x 4 7 1 3 6 8
2 5 x 4 7 1 3 6
2 5 8 4 7 1 3 6
2 5 8 x 7 1 3 6 4
2 x 5 8 7 1 3 6
2 4 5 8 7 1 3 6
2 4 5 8 x 1 3 6 7
2 4 5 x 8 1 3 6

4
InsertionSort (A){!
Sequenza Ordinata A[0..j-1]
n = DimensioneArray(A);!
!
for(j = 1; j<n; j++){ !
!
2 4 5 x 8 1 3 6 /* inserisce A[j] nella sequenza!
ordinata A[0..j-1] */!
2 4 5 7 8 1 3 6 !x = A[j];!
!i = j – 1;!
!while ((i ≥ 0) && !
2 4 5 7 8 x 3 6 1 ! !(x < A[i])){!
! A[i+1] = A[i];!
x 2 4 5 7 8 3 6 ! i = i – 1;!
!}!
1 2 4 5 7 8 3 6 ! A[i+1] = x;!
}!
1 2 4 5 7 8 x 6 3 }!

1 2 x 4 5 7 8 6
1 2 3 4 5 7 8 6
1 2 3 4 5 7 8 x 6
1 2 3 4 5 x 7 8
1 2 3 4 5 6 7 8
9

Algoritmo Insertion Sort


PseudoCodice
InsertionSort (A){!
n = DimensioneArray(A);!
!
for(j = 1; j<n; j++){ !
!
/* inserisce A[j] nella sequenza !ordinata
!A[0..j-1]! ! ! */!
! !x = A[j];!
! !i = j – 1;!
! !while ((i ≥ 0) && (x < A[i])){!
! !A[i+1] = A[i];!
! !i = i – 1;!
! !}!
! A[i+1] = x;!
!}!
}! 10

5
Complessità di un Algoritmo
•  Misura del numero di passi che si
devono eseguire per risolvere il
problema

11

Analisi Complessità
•  Algoritmo efficiente per dimensione piccola
dell’archivio
•  Caso medio O(N2)
•  Caso peggiore O(N2)
•  Intuizione
•  Due cicli che iterano su N-1 ( ciclo esterno ) e j-1
( ciclo interno )

12

6
Analisi Complessità (1)
InsertionSort (A){!
n = DimensioneArray(A);!
!
!for(j = 1; j<n; j++){ ! c1n
! !x = A[j];! c2 ( n !1)
!
! !i = j – 1;! c3 (n − 1)
! !while ((i ≥ 0) &&! n
! ! ! (x < A[i])){! c4 ! t
j=2 j
!
! !A[i+1] = A[i];! n
!
c5 " (t j !1)
j=2
!
! !i = i – 1;! n
! !}! c6 " (t j !1)
j=2
!
! !A[i+1] = x;! c7 ( n !1)
!}!
}! 13

Analisi Complessità (2)


T (n) = c1n +
c2 (n !1) +
c3 (n !1) +
n
c4 " t j +
j=2
n
c5 " (t j !1) +
j=2
n
c6 " (t j !1) +
j=2

c7 (n !1)
14

7
Analisi Complessità (1)
Caso migliore
tj=1
Array è ordinato in partenza

1 2 3 4 5 6 7 8

15

Analisi Complessità (1)


Caso migliore, tj=1
InsertionSort (A){!
n = DimensioneArray(A);!
!
!for(j = 1; j<n; j++){ ! c1n
! !x = A[j];! c2 ( n !1)
!
! !i = j – 1;! c3 (n − 1)
! !while ((i ≥ 0) &&!
! ! ! (x < A[i])){! c4 (n !1)
!
! !A[i+1] = A[i];!
! 0
!
! !i = i – 1;! 0
! !}!
!
! !A[i+1] = x;! c7 ( n !1)
!}!
}! 16
16

8
Analisi Complessità (2)
Caso migliore, tj=1

T (n) = (c1 + c2 + c3 + c4 + c7 )n
!c2 ! c3 ! c4 ! c7
= bn + a
" #(n)

17

Analisi Complessità (1)


Caso Peggiore, tj=j

T (n) = c1n +
c2 (n !1) +
c3 (n !1) +
n
c4 " j+
j=2
n
c5 " ( j !1) +
j=2
n
c6 " ( j !1) +
j=2

c7 (n !1)
18

9
Analisi Complessità (2)
Caso Peggiore, tj=j

Ricorda che:
n n(n +1)
! j=2
j=
2
"1
n n(n "1)
! j=2 ( j "1) = 2

19

Analisi Complessità (3)


Caso Peggiore, tj=j
InsertionSort (A){!
n = DimensioneArray(A);!
!
!for(j = 1; j<n; j++){ ! c1n
! !x = A[j];! c2 (n !1)
!
! !i = j – 1;! c3 (n !1)
! !while ((i ≥ 0) &&!
! ! ! (x < A[i])){! n(n +1)
c4 ( !1)
! 2
! !A[i+1] = A[i];!
n(n !1)
! c5 ( )
! 2
! !i = i – 1;!
n(n !1)
! !}! c6 ( )
! 2
! !A[i+1] = x;! c7 (n !1)
!}!
}! 20

10
Analisi Complessità (4)
Caso Peggiore, tj=j

T (n) = 1 (c + c + c )n 2
2 4 5 6
+(c1 + c2 + c3 + 1 c4 ! 1 c5 ! 1 c6 + c7 )n
2 2 2
!c2 ! c3 ! c7
= c'n 2 + b'n + a'

! "(n 2 )
21

Analisi Complessità
Caso Medio, tj=(j+1)/2

2
! "(n )

22

11
Algoritmi di Ordinamento

shellsort quicksort

bubblesort selectionsort mergesort insertsort

!(n log n) !(n 2 ) 23

Indice

• Algoritmi di Ordinamento
• Insertion Sort
• Merge Sort
• Equazioni di Ricorrenza ( T(n))

12
Algoritmo di Merge Sort

• Basato su due concetti:


1.  Ricorsione
2.  Divide and Conquer (o Divide
et Impera)

Esempio
5 1
0 2 2
8 2
0 3
4 4
7 5
1 6
9 7
3 8
2 9
6

5 2 4
0 8 5
0 7
4 8
7 1 2
9 3 6
2 9
6

5 5
2 2 8 0 4 7 1 3
9 9
3 2 6

5 5
2 2 8 0 4 7 1 9 3 2 6

5 2 0 4 1 9

26

13
Merge Sort
Tre passi algoritmo

1.  [DIVIDE] Divide la sequenza di n elementi da


ordinare in due sottosequenze di n/2 elementi
2.  [IMPERA] Ordina le due sottosequenze in modo
ricorsivo utilizzando l’algoritmo Merge Sort
3.  [COMBINA] Fonde le due sottosequenze
ordinate per generare la sequenza ordinata.

27

Ordinamento per ricorsione – Merge Sort


Caso Base

28

14
Ordinamento per ricorsione – Merge Sort
Caso Induttivo

29

Ordinamento per ricorsione - Merge Sort

30

15
Algoritmo
Pseudocodice

MergeSort (A,p,r){!
!
if (p < r) {!
!
/*q intero piu’ grande minore di (p+r)/2 */!
! !q = Floor((p+r)/2)); ! ! !
! !MergeSort (A,p,q)!
! !MergeSort (A,q+1,r)!
! !Merge(A,p,q,r)!
!}!
}!
31

Ordinamento per ricorsione - Merge Sort

32

16
Operazione di merge di array
Pseudocodice

Merge (A,p,q,r){!
/* p≤q<r!
Procedura assume A[p..q] e A[q+1..r] ordinati */!
n1 = q – p + 1; /*Lungh. Array Sx*/!
n2 = r – q; ! /*Lungh. Array Dx */!
/*Popola array L (left) e R ( right)*/!
for (i=0;i<n1;i++) /*Copia Array Sx */!
! !L[i]=A[p + i – 1]; !
!for (j=0;j<n2;i++) /*Lungh. Array Dx */!
! !R[j]=A[q + j];!
L[n1]=R[n2]=MAXINT;/*Sentinella fine
! ! ! ! ! !mazzo*/!
/* continua */!
33

Operazione di merge di array


Pseudocodice

Merge (A,p,q,r){!
/* p≤q<r!
Procedura assume A[p..q] e A[q+1..r] ordinati */!
n1 = q – p + 1; /*Lungh. Array Sx*/!
n2 = r – q; ! /*Lungh. Array Dx */!
/*Popola array L (left) e R ( right)*/!
for (i=0;i<n1;i++) /*Copia Array Sx */!
! !L[i]=A[p + i – 1]; !
!for (j=0;j<n2;i++) /*Lungh. Array Dx */!
! !R[j]=A[q + j];!
L[n1]=R[n2]=MAXINT;/*Sentinella fine
! ! ! ! ! !mazzo*/!
/* continua */!
34

17
Operazione di merge di array
Pseudocodice

Merge (A,p,q,r){!
/* p≤q<r!
Procedura assume A[p..q] e A[q+1..r] ordinati */!
n1 = q – p + 1; /*Lungh. Array Sx*/!
n2 = r – q; ! /*Lungh. Array Dx */!
/*Popola array L (left) e R ( right)*/!
for (i=0;i<n1;i++) /*Copia Array Sx */!
! !L[i]=A[p + i – 1]; !
!for (j=0;j<n2;j++) /*Lungh. Array Dx */!
! !R[j]=A[q + j];!
L[n1]=R[n2]=MAXINT;/*Sentinella fine
! ! ! ! ! !mazzo*/!
/* continua */!
35

Operazione di merge di array (cont.)


Pseudocodice

/* continua */!
i=j=0;!
for (k=p;k≤r;k++) /*r-p+1 passi*/!
!if (L[i] ≤ R[j]) {!
! A[k]= L[i];!
i = i + 1; !!
!} else{!
! A[k]=R[j];!
j=j + 1;!
! }!
} /* Fine Merge */!
! 36

18
Operazione di merge di array (cont.)
Pseudocodice

/* continua */!
i=j=0;!
for (k=p;k≤r;k++) /*r-p+1 passi*/!
!if (L[i] ≤ R[j]) {!
! A[k]= L[i];!
i = i + 1; !!
!} else{!
! A[k]=R[j];!
j=j + 1;!
! }!
} /* Fine Merge */!
! 37

Tempo di esecuzione di Merge


•  Il numero di istruzioni è condizionato dal terzo
ciclo for che si estende da p a r!
•  èMerge è Θ(n) dove n=r-p+1

38

19
Esempio
5 1
0 2 2
8 2
0 3
4 4
7 5
1 6
9 7
3 8
2 9
6

5 2 4
0 8 5
0 7
4 8
7 1 2
9 3 6
2 9
6

5 5
2 2 8 0 4 7 1 3
9 9
3 2 6

5 5
2 2 8 0 4 7 1 9 3 2 6

5 2 0 4 1 9

39

Analisi Complessità
Caso Peggiore

T ( n ) ! cn "#log 2 n$% + cn
& '(n log(n))

40

20
Equazioni di Ricorrenza
Algoritmi Divide et Impera

#!(1) se n " c
T (n) = $
% aT (n / b) + D(n) + C(n) altrimenti

c Costante piccola
a Numero di sottoproblemi generati dal passo
di divide
1 / b Dimensione dei sottoproblemi rispetto
a quello originale
D(n) Tempo impiegato per dividere il problema in
sottoproblemi
C(n) Tempo impiegato per ricombinare le sottosoluzioni
relative ai sottoproblemi

41

Merge Sort (1)


Equazione di Ricorrenza
•  Algoritmo funziona per qualsiasi n
•  Per soluzione eq. ricorrenza studieremo caso n=2k
•  Generiamo due sottoproblemi ad ogni passo
•  La dimensione di ogni sottoproblema è la metà del
problema di partenza
•  è a=b=2

#!(1) se n " c
T (n) = $
%2T (n / 2) + D(n) + C(n) altrimenti

42

21
Merge Sort (2)
Equazione di Ricorrenza

•  Contributi che provengono dai passi di


•  Divide:
†  Calcolo del centro del sottoarray
†  à D(n)=Θ(1)
•  Impera:
†  Risoluzione ricorsiva con due sottoproblemi di
dimensione n/2
†  è2T(n/2)
•  Combina:
†  La procedura di Merge con un sottoarray di n elementi
richiede un tempo Θ(n)
†  à C(n)=Θ(n)

43

Merge Sort (3)


Equazione di Ricorrenza

#!(1) se n " c
T (n) = $
%2T (n / 2) + !(n) altrimenti

a=b=2 D(n) e C(n)

44

22
Soluzione Equazione Ricorrenza (1)
#!(1) se n " c
T (n) = $
%2T (n / 2) + !(n) altrimenti

•  Dimostriamo con il metodo dell’albero di


ricorsione
•  Rappresentazione visiva delle chiamate
ricorsive dove ad ogni nodo associamo il
tempo di esecuzione esterno
†  Da dimostrare poi per induzione
45

Soluzione Equazione Ricorrenza (2)


!c se n=1
T (n) = "
#2T (n / 2) + cn se n>1

•  La costante c indica il tempo per risolvere problemi di


dimensione 1 che del tempo elemento dell’array divide
e combina

46

23
Soluzione Equazione Ricorrenza (3)
cn cn

T(n/2) T(n/2) cn/2 cn/2

T(n/4) T(n/4) T(n/4) T(n/4)

47

Soluzione Equazione Ricorrenza (4)


cn cn

cn/2 cn/2 cn

log2 n +1
Livelli
cn/4 cn/4 cn/4 cn/4 cn
.
.
.
.
.
.
c c c c c ….. c c cn
n Totale=cn log n + cn

24
Calcolo T(n)
•  Calcolo costo di ciascun livello
•  Calcolo del numero dei livelli
•  Sommare il costo di ciascun livello
per tutti i livelli per ottenere:
•  àT(n)

49

Costo per Ciascun Livello


•  Il primo livello ha un costo totale cn
•  Il secondo livello ha un costo totale c(n/2)+c(n/2)=cn
•  Il terzo livello ha un costo totale
c(n/4)+c(n/4)+c(n/4)+c(n/4)=cn
…….
•  In generale il livello i sotto il primo ha 2i nodi, ciascuno
dei quali ha un costo c(n/2i)
†  à quindi i-esimo livello ha un costo di 2ic(n/2i)=cn
•  Ultimo livello dell’albero ( in basso ) ha n nodi ciascuno
di costo c
†  à Costo totale livello è cn

50

25
Costo per Ciascun Livello
•  Il primo livello ha un costo totale cn
•  Il secondo livello ha un costo totale c(n/2)+c(n/2)=cn
•  Il terzo livello ha un costo totale
c(n/4)+c(n/4)+c(n/4)+c(n/4)=cn
…….
•  In generale il livello i sotto il primo ha 2i nodi, ciascuno
dei quali ha un costo c(n/2i)
†  à quindi i-esimo livello ha un costo di 2ic(n/2i)=cn
•  Ultimo livello dell’albero ( in basso ) ha n nodi ciascuno
di costo c
†  à Costo totale livello è cn

51

Calcolo del Numero dei Livelli


•  Numero totale di livelli è log2 n +1
•  Dimostrazione per induzione
•  Caso Base n=1
†  log 1=0ànumero di livelli è 0+1=1
•  Induzione caso n=2i
†  Numero di livelli : lg 2i+1=i+1
†  Prossimo n successivo è n=2i+1
†  Per n=2i+1 si ha un livello in più rispetto al
caso n=2i
†  ànumero di livelli è (i+1)+1=lg 2i+1 +1
52

26
Calcolo del Numero dei Livelli
•  Numero totale di livelli è lg n +1
•  Dimostrazione per induzione
•  Caso Base n=1
†  lg 1=0ànumero di livelli è 0+1=1
•  Induzione caso n=2i
†  Numero di livelli : log 2i+1=i+1
†  Prossimo n successivo è n=2i+1
†  Per n=2i+1 si ha un livello in più rispetto al
caso n=2i
†  ànumero di livelli è (i+1)+1=log 2i+1 +1
53

Somma dei Costi


•  Sommare i costi di tutti i livelli
•  Ci sono log n +1 livelli
•  Ciascuno di costo cn
•  Per un costo totale di
•  T(n)=cn(log n +1)=cn log n + cn
àT(n)=Θ(n log n)

54

27
Osservazioni (1)
Praticamente tutti i metodi elementari ordinano una sequenza
di N numeri in O(N2)
•  Bubble Sort : Caso medio (peggiore) O(N2) ( O(N2) )
•  Insertion Sort : Caso medio (peggiore) O(N2) ( O(N2) )
Metodi di ordinamento più efficienti
•  Quick Sort :Caso medio (peggiore) O(N logN) ( O(N2) )
•  Merge Sort: Caso medio (peggiore) O(N logN) (O(N
logN) )

55

Osservazioni (2)

•  Algoritmi ordinamento sono indipendenti


1.  dal tipo di elementi da ordinare;
2.  dal verso di ordinamento: crescente o decrescente
•  Metodi visti si basano su confronti con elementi in
input. Si può dimostrare che tutti i metodi di
ordinamento per confronti hanno un comportamento
ottimale O(N logN) .

56

28

Potrebbero piacerti anche