Merge-Sort(A,p,r) if p < r q = (p+r)/2 Merge-Sort(A,p,q) Merge-Sort(A,q+1,r) Merge(A,p,q,r)
A[p..q] A[q+1..r] 0 2 4 5 7 8 1 2 3 6 9 L 0 1 2 2 3 4 5 7 8 6 9 0 1 2 2 3 4 5 6 7 8 9 0 1 2 2 3 4 5 7 8 6 9 0 1 2 2 3 4 5 6 7 8 9 0 1 2 2 3 4 5 6 7 8 9 0 1 2 2 3 4 5 6 7 8 9 0 1 2 4 5 7 8 2 3 6 9 0 2 4 5 7 8 1 2 3 6 9 0 1 2 2 3 4 5 7 8 6 9 2 4 5 7 8 1 2 3 6 9 0 1 2 4 5 7 8 2 3 6 9 0 1 2 2 4 5 7 8 3 6 9 R A[p..r]
Merge(A,p,q,r) n1 = q – p + 1 n2 = r – q for i = 1 to n1 L[i] = A[p + i – 1] for j = 1 to n2 R[j] = A[q + j] L[n1 + 1] = R[n2 + 1] = i = j = 1 for k = p to r if L[i] R[j] A[k] = L[i] i = i + 1 else A[k] = R[j] j = j + 1
Analisi di Merge-Sort: correttezza Merge-Sort(A,p,r) if p < r // altrimenti A[p..r] è ordinato q = (p+r)/2 Merge-Sort(A,p,q) Merge-Sort(A,q+1,r) Merge(A,p,q,r) non ordinati 1 p r n A ordinati 1 p r n q A ordinati 1 p r n A
Merge(A,p,q,r) n1 = q – p + 1 n2 = r – q for i = 1 to n1 L[i] = A[p + i – 1] for j = 1 to n2 R[j] = A[q + j] L[n1 + 1] = R[n2 + 1] = i = j = 1 for k = p to r if L[i] R[j] A[k] = L[i] i = i + 1 else A[k] = R[j] j = j + 1 1 p r n q A 1 p r n A L ∞ R n1 n2 1 p r n A L ∞ R n1 n2 k i j 1 p r n A L ∞ R n1 n2 k i j
Merge(A,p,q,r) // complessità // n1 = q – p + 1 // n2 = r – q // for i = 1 to n1 // L[i] = A[p + i – 1] // for j = 1 to n2 // R[j] = A[q + j] // L[n1 + 1] = R[n2 + 1] = // i = j = 1 // for k = p to r // if L[i] R[j] // A[k] = L[i] // i = i + 1 // else A[k] = R[j] // j = j + 1 //
Merge-Sort(A,p,r) //complessità // if p < r // q = (p+r)/2 // Merge-Sort(A,p,q) // Merge-Sort(A,q+1,r) // Merge(A,p,q,r) //
Dunque esiste N tale che per ogni n > N. Qualunque siano i valori delle costanti a', b', c', a", b" e c" l’algoritmo Merge-Sort è superiore a Insertion-Sort per array di dimensione sufficientemente grande.
Possiamo dire che “cresce come” n2 mentre “cresce come” n log2 n. IS n2 ns MS n log2 n ns 10 100 33 0.1s 0.033s 100 10000 664 10s 0.664s 1000 106 9965 1ms 10s 10000 108 132877 0.1s 133s 106 1012 2·107 17m 20ms 109 1018 3·1010 70anni 30s 109 1018 3·1010 30s
dunque esiste N tale che per ogni n > N. Qualunque siano i valori delle costanti a', b', c', a", b" l’algoritmo Insertion-Sort è superiore a Merge-Sort per array (quasi) ordinati e sufficientemente grandi.
Insertion-Sort è anche superiore a Merge-Sort per array piccoli in quanto le costanti a', b', c' in sono generalmente molto maggiori delle costanti a", b" e c" in . Questo suggerisce una modifica di Merge-Sort in cui le porzioni di array di dimensione minore di una certa costante k si ordinano con Insertion-Sort invece di usare ricorsivamente Merge-Sort.
Soluzione3: Algoritmo Merge-Ins-Sort Merge-Ins-Sort(A,p,r) if p < r if r-p+1 < 32 InsertSort(A,p,r) else q = (p+r)/2 Merge-Ins-Sort(A,p,q) Merge-Ins-Sort(A,q+1,r) Merge(A,p,q,r)
Soluzione: Algoritmo Heap-Sort Un array A[1..n] può essere interpretato come un albero binario: A[1] è la radice, A[2i] e A[2i+1] sono i figli di A[i] A[ i / 2 ] è il padre di A[i]
Albero binario quasi completo a1 a2 a12 a3 a4 a5 a6 a7 a8 a9 a10 a11 1 2 3 4 5 6 7 8 9 10 11 12 a1 a2 a12 a3 a4 a5 a6 a7 a8 a9 a10 a11 Albero binario quasi completo a10 a11 a9 a12 a2 a8 a4 a5 a6 a7 a3 a1 12 102 112 1002 1012 1102 1112 10002 10012 10102 10112 11002
Proprietà di un heap (mucchio) Diciamo che A[1..n] è un (è ordinato a) max-heap se ogni elemento A[i] soddisfa la seguente proprietà: “A[i] è maggiore o uguale di ogni suo discendente in A[1..n]” Per brevità indicheremo questa proprietà con H(i)
Un max-heap 1 2 3 4 5 6 7 8 9 10 11 12 9 8 2 7 5 4 3 6 1 6 1 3 2 8 4 5 7 9 1 2 3 4 5 6 7 8 9 10 11 12
Costruzione di un max-heap 1 2 3 4 5 6 7 8 9 10 11 12 6 5 5 6 4 8 9 2 7 3 1 9 5 6 8 5 9 6 9 8 5 8 7 7 6 2 9 2 4 2 5 1 6 2 3 8 9 2 7 4 5 6 7 4 3 7 1 4 8 9 10 11 12