Académique Documents
Professionnel Documents
Culture Documents
l
A.A. 2013/14 07 Gli ordinamenti ricorsivi
q q+1
r
2
Esempio
Ricorsione merge sort su sottovettore DX merge sort su sottovettore SX condizione di terminazione: con 1 (l=r) o 0 (l>r) elementi ordinato Ricombinazione: fondi i due sottovettori ordinati in un vettore ordinato.
Divisione ricorsiva:
12 6 4 5 9 2 3 1 12 6 4 5 12 6 12 6 4 4 5 5 9 2 3 1 9 2 9 2 3 3 1 1
Ricombinazione
void MergeSort(Item A[], int l, int r) { divisione int q = (l + r)/2; if (r <= l) terminazione return; chiamata ricorsiva MergeSort(A, l, q); MergeSort(A, q+1, r); chiamata ricorsiva Merge(A, l, q, r); }
1 2 3 4 5 6 9 12 4 5 6 12 6 12 12 6 4 4 5 5 1 2 3 9 2 9 9 2 3 1 3 1
ricombinazione
A.A. 2013/14 07 Gli ordinamenti ricorsivi 5 A.A. 2013/14 07 Gli ordinamenti ricorsivi 6
Algoritmi e Programmazione
Caratteristiche
void Merge(Item A[], int l, int q, int r) { int i, j, k; Item B[MAX]; i = l; j = q+1; for (k = l; k <= r; k++) if (i > q) B[k] = A[j++]; else if (j > r) B[k] = A[i++]; else if ( less(A[i], A[j]) || eq(A[i], A[j]) B[k] = A[i++]; else B[k] = A[j++]; for ( k = l; k <= r; k++ ) A[k] = B[k]; return; }
A.A. 2013/14 07 Gli ordinamenti ricorsivi
Non in loco (usa un vettore ausiliario) Stabile: in quanto la funzione merge prende dal sottovettore SX in caso di chiavi uguali:
11 12 13 14 4 5 7 9
11 12 13 4
14 5 7 9
A.A. 2013/14
soluzione per sviluppo (unfolding) T(n/2) = 2T(n/4) +n/2 T(n/4) = 2T(n/8) +n/4 etc.
Terminazione: a ogni passo i dati si dimezzano, dopo i passi sono n/2i . Si termina per n/2i = 1, i = log2n T(n) = n + 2*(n/2) + 22 *(n/4) + 23 *T(n/8) = 0 i log2n 2i / 2i * n = n * 0 i log2n 1 = n*(1 + log2n) n log2n + n T(n) = O(n log n)
A.A. 2013/14 07 Gli ordinamenti ricorsivi 10
log2 n
Algoritmi e Programmazione
12
raddoppia la dimensione del vettore ordinato void BottomUpMergeSort(Item A[], int l, int r) { int i, m; for (m = 1; m <= r l; m = m + m) for (i = l; i <= r m; i += m + m) Merge(A, i, i+m-1, r); } fondile
6 12
4 5
2 9
1 3
4 5 6 12
1 2 3 9
1 2 3 4 5 6 9 12
considera le coppie di sottovettori ordinati di dimensione m
A.A. 2013/14 07 Gli ordinamenti ricorsivi 13 A.A. 2013/14 07 Gli ordinamenti ricorsivi 14
Divisione: partiziona il vettore A[p..r] in due sottovettori SX e DX: dato un elemento pivot x = A[q] SX A[p..q-1] contiene tutti elementi x DX A[q+1..r] contiene tutti elementi x A[q] si trova al posto giusto la divisione non necessariamente a met, a differenza del mergesort.
07 Gli ordinamenti ricorsivi 15 A.A. 2013/14
Ricorsione quicksort su sottovettore SX A[p..q-1] quicksort su sottovettore DX A[q+1..r] condizione di terminazione: se il vettore ha 1 elemento ordinato Ricombinazione: nulla.
A.A. 2013/14
16
Partition
Pivot x = A[r] individua A[i] e A[j] elementi fuori posto ciclo discendente j fino a trovare un elemento minore del pivot x ciclo ascendente su i fino a trovare un elemento maggiore del pivot x scambia A[i] e A[j] ripeti fintanto che i < j alla fine scambia A[i] e il pivot x ritorna i T(n) = (n).
Esempio di partition
A i A 25 17 2 6 4 1 0 13 i A j A p r 25 17 2 6 14 1 0 13 j A
x 13
0 1 2 6 4 17 25 13 j i scambio di i e j
return q
0 1 2 6 4 13 25 17 j i
0 17 2 6 4 1 25 13 i j
07 Gli ordinamenti ricorsivi
A.A. 2013/14
18
Algoritmi e Programmazione
Esempio di quicksort
A x 4 x 2 x 1 0 25 17 2 6 4 1 0 13 13 6 17 25 17 25 x 13 x 17
void quicksort (Item A[], int l, int r ){ int q; discesa ricorsiva/terminazione if (r <= l) return; divisione q = partition(A, l, r); quicksort(A, l, q-1); chiamata ricorsiva quicksort(A, q+1, r); return; chiamata ricorsiva } void Swap(Item v[], int n1, int n2) { Item temp; temp = v[n1]; v[n1] = v[n2]; v[n2] = temp; return; }
19 A.A. 2013/14 07 Gli ordinamenti ricorsivi 20
0 1 2 6 4 0 1 2 0 1 1 2 A 4
0 1 2 4 6 13 17 25
A.A. 2013/14
Caratteristiche
int partition (Item A[], int l, int r ){ int i = l-1, j = r; Item x = A[r]; for ( ; ; ) { while(less(A[++i], x)); while(greater(A[--j], x)); if (j == l) break; if (i >= j) break; Swap(A, i, j); } Swap(A, i, r); return i; }
A.A. 2013/14 07 Gli ordinamenti ricorsivi 21
In loco Non stabile: la funzione partition pu provocare uno scambio tra elementi lontani, facendo s che unoccorrenza di una chiave duplicata si sposti a SX di unoccorrenza precedente della stessa chiave scavalcandola.
A.A. 2013/14
22
Caso peggiore
Caso peggiore: pivot = minimo o massimo (vettore gi ordinato) Equazione alle ricorrenze: T(n) = T(n-1) + n n>=2 T(1) = 1 n=1 Risoluzione per sviluppo: T(n) = n + (n-1) + (n-2) + . 3 + 2 + 1 = n/2 * (n+1) T(n) = O(n2)
Algoritmi e Programmazione
Caso migliore
Caso medio
Purch non si ricada nel caso peggiore, anche se il partizionamento molto sbilanciato, caso medio = caso migliore Esempio: ad ogni passo si generano 2 partizioni, la prima con 9/10 n e la seconda con n/10 elementi.
n>=2 n=1
A.A. 2013/14
25
A.A. 2013/14
26
T(n) = O(n lg n)
A.A. 2013/14 07 Gli ordinamenti ricorsivi
Elemento a caso: genera un numero casuale i con l i r, poi scambia A[0] e A[i], usando come pivot A[0] Elemento di mezzo: x A[(l+r)/2] Scegliere il valore medio tra min e max Scegliere la mediana tra 3 elementi presi a caso nel vettore
Quadro riassuntivo
Algoritmo Bubble sort Selection sort Insertion sort Shellsort Mergesort Quicksort Counting sort
A.A. 2013/14
Riferimenti
In loco Stabile Caso peggiore s s O(n2) s s O(n2) s s O(n2) s no dipende no s O(nlog n) s no O(n2) no s O(n)
07 Gli ordinamenti ricorsivi 29
A.A. 2013/14
30