La presentazione è in caricamento. Aspetta per favore

La presentazione è in caricamento. Aspetta per favore

Algoritmi di ordinamento

Presentazioni simili


Presentazione sul tema: "Algoritmi di ordinamento"— Transcript della presentazione:

1 Algoritmi di ordinamento
Selection Sort Quick Sort Lower bound alla complessità degli algoritmi di ordinamento

2 Selection Sort L’elemento minimo viene messo in posizione 0
SelectionSort(dati[]) { for (i=0; i<dati.length-1; i++) { min = <Seleziona min. in dati[i], …. , dati[dati.length-1]> <Scambia min con dati[i]; } L’elemento minimo viene messo in posizione 0 Si itera il procedimento sulle posizioni successive

3 Selection Sort/2 Versione ricorsiva SelectionSort(dati[], i) {
min = <Seleziona min. in dati[i], …. , dati[dati.length-1]> <Scambia min con dati[i]; SelectionSort(dati[], i+1) ; } …… SelectionSort(dati[], 0) ; Versione ricorsiva

4 Selection Sort/3 Ordinamento del vettore di interi {5, 2, 3, 8, 1}

5 Come ordinare oggetti diversi da numeri
Ordinare un vettore i cui elementi sono oggetti complessi. Es. oggetti della classe: class Persona { String cognome; String CF; public Persona (String cognome, String CF) { this.cognome = cognome; this.CF = CF; } Come ordinare un array di tali oggetti rispetto al cognome ?

6 Come ordinare oggetti diversi da numeri/2
Occorre: Dichiarare che tra gli oggetti della classe (Persona nell’esempio) è definito un ordinamento Dichiarare rispetto a quale o a quali membri della classe è definito l’ordinamento (il cognome nel nostro caso) Definire la regola che stabilisce l’ordinamento tra due oggetti della classe (nel nostro caso: due oggetti di tipo persona sono ordinati alfabeticamente secondo i rispettivi cognomi) In C++ si possono sovraccaricare gli operatori In Java si può dichiarare che la classe (Persona) implementa l’interfaccia Comparable (non è la sola possibilità)

7 Come ordinare oggetti diversi da numeri/3
Il passo 1 si traduce così: class Persona implements Comparable { …… } I passi 2 e 3 consistono nell’implementare l’unico metodo previsto dall’interfaccia Comparable: int compareTo(Object o) compareTo definisce le regole che stabiliscono l’ordinamento tra oggetti della classe (nel nostro caso, l’ordinamento è quello alfabetico sui cognomi)

8 Come ordinare oggetti diversi da numeri/4
Quindi: class Persona implements Comparable { String cognome; String CF; public Persona (String cognome, String CF) { this.cognome = cognome; this.CF = CF; } public int compareTo (Object pers) { return cognome.compareTo(((Persona)pers).cognome); Nota: occorre fare il cast perché compareTo vuole un Object

9 Selection Sort/4 public void selectionsort(Comparable[] data) {
int i, j, least; for (i = 0; i < data.length-1; i++) { for (j = i+1, least = i; j < data.length; j++) if (data[j].compareTo(data[least]) < 0) least = j; swap(data, least, i); /* Scambia gli oggetti in pos. i e least */ } Es.: versione ricorsiva

10 Selection Sort - Tempo di esecuzione
Supponiamo che l’array contenga n elementi Alla i-esima iterazione occorre trovare il massimo di n-i+1 elementi e sono quindi necessari n-i confronti Vi sono n-1 cicli Costo = Si osservi che tale costo non dipende dall’ eventuale ordinamento parziale dell’array (cfr. Insertion Sort)

11 Quick Sort quicksort(array[]) { if (array.length>1) {
Scegli bound; /* subarray1 e subarray2 */ while (ci sono elementi in array) if (generico elemento < bound) inserisci elemento in subarray1; else inserisci elemento in subarray2; quicksort(subarray1); quicksort(subarray2); }

12 Quick Sort/2 Array subarray1 < bound subarray2 >= bound

13 Partizionamento dell’array [8 5 4 7 6 1 6 3 8 12 10] con quicksort

14 Partizionamento dell’array [8 5 4 7 6 1 6 3 8 12 10] con quicksort

15 Quick Sort/3 void quicksort(Comparable[] data, int first, int last) {
int lower = first + 1, upper = last; swap(data, first, (first+last)/2); /* Questo serve solo perché così, in pratica è spesso più veloce */ Comparable bound = data[first]; while (lower <= upper) { while (data[lower].compareTo(bound) < 0) lower++; while (bound.compareTo(data[upper]) < 0) upper--; if (lower < upper) swap(data, lower++, upper--); else lower++; /* 1 */ } /* End while */ swap(data, upper, first); if (first < upper-1) /* se first == upper-1 il sottoarray ha solo 2 elementi ed è ordinato */ quicksort(data, first, upper-1); if (upper+1 < last) quicksort(data, upper+1, last); }

16 Quick Sort/4 void quicksort(Comparable[] data) {
if (data.length < 2) return; int max = 0; /* Trova max. e mettilo alla fine; serve per evitare che lower cresca oltre la dim. dell’ array (non è detto che accada ma può succedere) */ for (int i = 1; i < data.length; i++) if (data[max].compareTo(data[i]) < 0) max = i; swap(data, data.length-1, max); // largest el is now in its quicksort(data, 0, data.length-2); // final position; }

17 Analisi del Quick Sort Costo = O(No. confronti)
Costo O(n2) nel caso peggiore Costo O(n log n) nel caso migliore e medio In pratica l’algoritmo è efficiente Scelta pivot fondamentale

18 Quick Sort – Caso peggiore
No. confronti per sotto-array Array n-1 n-2 2 1 n-1 volte L’elemento di pivot è sempre il minimo Costo = O(n-1+n ) = O(n2)

19 Quick Sort – Caso migliore
No. confronti per sotto-array n potenza di 2 per semplicità Array n-1 n/2-1 2 1 log n+1 volte n/4-1 Costo =

20 Efficienza algoritmi di ordinamento
Merge Sort (e Heap Sort): O(n log n) Quick Sort, Selection Sort, Insertion Sort: O(n2) Quick Sort: O(n log n) nel caso migliore Selection Sort: O(n2) in tutti i casi Insertion Sort: O(n) nel caso migliore Domanda: qual è l’efficienza massima (complessità minima) ottenibile nel caso peggiore -> Lower bound

21 Ordinamento – limiti inferiori
Osservazione fondamentale: tutti gli algoritmi devono confrontare elementi Dati ai, ak, tre casi possibili: ai < ak, ai > ak, oppure ai=ak Si assume per semplicità che tutti gli elementi siano distinti Si assume dunque che tutti i confronti abbiano la forma ai < ak, e il risultato del confronto sia vero o falso Nota: se gli elementi possono avere lo stesso valore allora si considerano solo confronti del tipo ai <= ak

22 Alberi di decisione a1:a2 < > a2:a3 a1:a3 < > > <
Albero di decisione per Insertion Sort sull’insieme {a1, a2, a3} a1:a2 < > a2:a3 a1:a3 < > > < a1,a2,a3 a1:a3 a2,a1,a3 a2:a3 > < > < a1,a3,a2 a3,a1,a2 a2,a3,a1 a3,a2,a1 Un albero di decisione rappresenta i confronti eseguiti da un algoritmo su un dato input Ogni foglia corrisponde ad una delle possibili permutazioni

23 Alberi di decisione/2 a1:a2 < > a2:a3 a1:a3 < > > <
Albero di decisione per Insertion Sort sull’insieme {a1, a2, a3} a1:a2 < > a2:a3 a1:a3 < > > < a1,a2,a3 a1:a3 a2,a1,a3 a2:a3 > < > < a1,a3,a2 a3,a1,a2 a2,a3,a1 a3,a2,a1 Vi sono n! possibili permutazioni -> l’albero deve contenere n! foglie L’esecuzione di un algoritmo corrisponde ad un cammino sull’albero di decisione corrispondente all’input considerato

24 Alberi di decisione/3 Riassumendo:
Albero binario Deve contenere n! foglie Il più lungo cammino dalla radice ad una foglia (altezza) rappresenta il No. confronti che l’algoritmo deve eseguire nel caso peggiore Teorema: qualunque albero di decisione che ordina n elementi ha altezza Ώ(n log n) Corollario: nessun algoritmo di ordinamento ha complessità migliore di Ώ(n log n) Nota: esistono algoritmi di ordinamento con complessità più bassa, ma richiedono informazioni aggiuntive

25 Dimostrazione teorema
Un albero di decisione è binario Albero binario di altezza h non ha più di 2h foglie 1 1=21-1 2 2= 22-1 3 4= 23-1 h 2h-1 Dobbiamo avere: 2h-1 > No. foglie = n! h-1 > log(n!)

26 Dimostrazione teorema/2
n! > (n/e)n (approssimazione di Stirling) h-1 > log(n/e)n = n log(n/e) = n logn – n loge = Ώ(n log n) Corollario: gli algoritmi Merge Sort e Heap Sort hanno complessità asintotica ottima


Scaricare ppt "Algoritmi di ordinamento"

Presentazioni simili


Annunci Google