Scaricare la presentazione
La presentazione è in caricamento. Aspetta per favore
PubblicatoBenedetto Zanella Modificato 10 anni fa
1
30 ottobre 20021 Mergesort F. Bombi 30 ottobre 2002
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 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
30 ottobre 20023 Fusione di due liste ordinate Due liste l1 e l2 ordinate di lunghezza n e m possono essere fuse in ununica lista ordinata con il seguente algoritmo Sia l una nuova lista vuota mentre le due liste l1 e l2 non sono vuote se testa(l1) < testa(l2) accoda(testa(l1)) a l; l1 = resto(l1) altrimenti accoda(testa(l2)) a l; l2 = resto(l2) se l1 non è vuota accoda l1 a l altrimenti accoda l2 a l
4
30 ottobre 20024Analisi 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 (o 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
5
30 ottobre 20025 private void merge (Lista l, Lista l1, Lista l2) { Iteratore i1 = new Iteratore(l1); Iteratore i2 = new Iteratore(l2); while (i1.hasNext() && i2.hasNext()) { if (((Comparable)i1.get()).compareTo(i2.get()) < 0) l.addLast(l1.removeFirst()); else l.addLast(l2.removeFirst()); } while (i1.hasNext()) l.addLast(l1.removeFirst()); while (i2.hasNext()) l.addLast(l2.removeFirst()); } Fusione di due liste
6
30 ottobre 20026Ordinare Sia l la lista da ordinare se la lista ha lunghezza > 1 copiare la lista l in due liste l1 e l2 (alternando un elemento per lista) ordinare ricorsivamente l1 ordinare ricorsivamente l2 fondere l1 e l2 in l NB: il caso base si ha quando la lista ha lunghezza 0 o 1
7
30 ottobre 20027 private void ms (Lista l) { Lista l1 = new Lista(); Lista l2 = new Lista(); while (l.size() > 0) { l1.addLast(l.removeFirst()); if (l.size() > 0) l2.addLast(l.removeFirst()); } if (l1.size() > 1) ms(l1); if (l2.size() > 1) ms(l2); merge(l, l1, l2); } NB: il codice effettua le chiamate ricorsive solo per liste di lunghezze maggiore di 1
8
30 ottobre 20028 8, 7, 6, 5, 4, 3, 2, 1 8, 6, 4, 27, 5, 3, 1 8, 46, 27, 35, 1 84627513 4, 8 2, 6 3, 7 1, 5 2, 4, 6, 81, 3, 5, 7 1, 2, 3, 4, 5, 6, 7, 8 private void ms (Lista l) { Lista l1 = new Lista(); Lista l2 = new Lista(); while (l.size() > 0) { l1.addLast(l.removeFirst()); if (l.size() > 0) l2.addLast(l.removeFirst()); } if (l1.size() > 1) ms(l1); if (l2.size() > 1) ms(l2); merge(l, l1, l2); } Albero delle chiamate ricorsive per una lista di 8 elementi
9
30 ottobre 20029 import catena.*; public class Fusione { public Fusione (Lista x) { ms(x); } private void ms (Lista l) {…} private void merge (Lista l, Lista l1, Lista l2) {…. } }
10
30 ottobre 200210 import catena.*; import java.io.*; public class Ordina { public static void main (String[] arg) throws IOException { BufferedReader in = new BufferedReader(new FileReader(arg[0])); String str; Lista l = new Lista(); while ((str = in.readLine()) != null) l.addLast(str); System.out.println(l); new Fusione(l); System.out.println(l); } Ordinare le righe di un file
11
30 ottobre 200211 Analisi di mergesort Vogliamo dimostrare che mergesort ha una complessità temporale O(n log(n)) Supponiamo che ogni operazione sulle liste richieda un tempo costante Per semplicità supponiamo anche che la lunghezza n della lista da ordinare sia una potenza di 2 e quindi si possa dire che n = 2 k Analizziamo il tempo in funzione di k
12
30 ottobre 200212 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
13
30 ottobre 200213 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))
14
30 ottobre 200214 Per ordinare un vettore Dividere il vettore s d c 214 7 s1d1s2d2
15
30 ottobre 200215 Per ordinare un vettore Fondere due vettori 214 s1 d1 s2 d2 Vettore temporaneo
Presentazioni simili
© 2024 SlidePlayer.it Inc.
All rights reserved.