Scaricare la presentazione
La presentazione è in caricamento. Aspetta per favore
PubblicatoGiuseppina Sanna Modificato 10 anni fa
1
28 ottobre 20031 Mergesort F. Bombi 28 ottobre 2003
2
2Lalgoritmo Lalgoritmo di ordinamento mergesort o per fusione è un algoritmo efficiente in quanto ha una complessità temporale O(nlog(n)) e può essere utilizzato per ordinare un vettore di oggetti Comparable oppure una lista o sequenza Lalgoritmo si basa sullesistenza di un algoritmo efficiente in grado di fondere due vettori (o due liste) ordinate in un vettore (o in una lista) ordinata in un tempo O(n+m) essendo n ed m la lunghezza dei due vettori
3
28 ottobre 20033 Per ordinare un vettore Dividere il vettore s d c 214 7 s1d1s2d2
4
28 ottobre 20034 private void merge (int s1, int d1, int s2, int d2) { int i = s1; int j = s1; while (s1 <= d1 && s2 <= d2) if (v[s1].compareTo(v[s2]) < 0) tmp[i++] = v[s1++]; else tmp[i++] = v[s2++]; while (s1 <= d1) tmp[i++] = v[s1++]; while (s2 <= d2) tmp[i++] = v[s2++]; for (; j <= d2; j++) v[j] = tmp[j]; } Fusione di due array
5
28 ottobre 20035Analisi Ogni operazione elementare richiede un tempo costante, alla fine la lista l avrà una lunghezza pari a n+m e di conseguenza le operazioni necessarie sono n+m e quindi lalgoritmo ha una complessità O(n+m) Il numero di confronti necessari è al minimo pari a n (oppure a m ) se una delle due liste è composta da elementi minori degli elementi dellaltra lista, è invece O(n+m) se gli elementi delle due liste sono intercalati Lalgoritmo può essere usato per fondere due vettori parzialmente riempiti in un vettore ordinato con efficienza analoga, si utilizzeranno tre cursori per tenere traccia della posizione della testa dei due vettori dorigine e della posizione della coda nel vettore risultato
6
28 ottobre 20036 Per ordinare un vettore Fondere due vettori 214 s1 d1 s2 d2 Vettore temporaneo
7
28 ottobre 20037Ordinare Sia v larray da ordinare Siano i e s i cursori che definiscono inizio e fine dellarray se larray ha lunghezza > 1 dividere larray in due metà individuate da i1, s1 e i2, s2 ordinare ricorsivamente da i1 a s1 ordinare ricorsivamente da i2 a s2 fondere le due parti dellarray NB: il caso base si ha quando larray ha lunghezza 0 o 1
8
28 ottobre 20038 private Comparable[] v; Private Comparable[] tmp; private int n; public void ordina () { if (n > 1) { tmp = new Comparable[n]; ms(0, n-1); } private void ms (int s, int d) { int c = (s + d)/2; if (s < c) ms(s, c); if (c+1 < d) ms(c+1, d); merge(s, c, c+1, d); } NB: il codice effettua le chiamate ricorsive solo per array di lunghezze maggiore di 1
9
28 ottobre 20039 8, 7, 6, 5, 4, 3, 2, 1 8, 7, 6, 54, 3, 2, 1 8, 76, 54, 32, 1 87654213 7, 8 5, 6 3, 4 1, 2 5, 6, 7, 81, 2, 3, 4 1, 2, 3, 4, 5, 6, 7, 8 Albero delle chiamate ricorsive per un array di 8 elementi
10
28 ottobre 200310 Analisi di mergesort Vogliamo dimostrare che mergesort ha una complessità temporale O(n log(n)) Supponiamo che ogni operazione sugli array richieda un tempo costante Per semplicità supponiamo anche che la lunghezza n dellarray da ordinare sia una potenza di 2 e quindi si possa dire che n = 2 k Analizziamo il tempo in funzione di k
11
28 ottobre 200311 A meno di costanti (inessenziali nella valutazione del comportamento asintotico dellalgoritmo) possiamo dire che: T(k) = 2 T(k-1) + 2 k T(0) = 1 La ricorrenza ha come soluzione T(k) = (k+1)2 k Infatti questo è vero per k = 0, supponendo che sia vero per un valore qualsiasi di k= k avremo che T(k) = (k+1) 2 k
12
28 ottobre 200312 Dobbiamo dimostrare che è vero T(k+1) = (k+1+1)2 k+1 Infatti dalla ricorrenza iniziale abbiamo: T(k+1) = 2 T(k+1-1) + 2 k+1 Dallipotesi fatta per k = k si ha: T(k+1) = 2(k+1)2 k + 2 k+1 E quindi: T(k+1) = (k+1+1)2 k+1 Che era quanto volevamo dimostrare Ora dato che k=log(n) abbiamo che T(n) = n(log(n)+1) = O(n log(n))
Presentazioni simili
© 2024 SlidePlayer.it Inc.
All rights reserved.