Divide et Impera Parte 11 - Risoluzione di problemi per divisione in sottoproblemi “bilanciati” Corso A: Prof. Stefano Berardi http://www.di.unito.it/~stefano.

Slides:



Advertisements
Presentazioni simili
Algoritmi e Strutture Dati
Advertisements

                      Insertion-Sort
Ricorsione Procedure e funzioni ricorsive. Definizioni Un oggetto si dice ricorsivo se è definito totalmente o parzialmente in termini di sé stesso La.
Procedure e funzioni ricorsive
RB-alberi (Red-Black trees)
Alberi binari di ricerca
Code con priorità Ordinamento
Camil Demetrescu, Irene Finocchi, Giuseppe F. ItalianoAlgoritmi e strutture dati Copyright © The McGraw - Hill Companies, srl 1 Usa la tecnica del.
Camil Demetrescu, Irene Finocchi, Giuseppe F. ItalianoAlgoritmi e strutture dati Copyright © The McGraw - Hill Companies, srl 1 Ordinamenti ottimi.
Capitolo 4 Ordinamento Algoritmi e Strutture Dati.
Camil Demetrescu, Irene Finocchi, Giuseppe F. ItalianoAlgoritmi e strutture dati Copyright © The McGraw - Hill Companies, srl 1 Usa la tecnica del.
Camil Demetrescu, Irene Finocchi, Giuseppe F. ItalianoAlgoritmi e strutture dati Copyright © The McGraw - Hill Companies, srl 1 Usa la tecnica del.
Iterazione enumerativa (for)
Algoritmi e Strutture Dati Capitolo 2 Modelli di calcolo e metodologie di analisi.
Camil Demetrescu, Irene Finocchi, Giuseppe F. ItalianoAlgoritmi e strutture dati Copyright © The McGraw - Hill Companies, srl Capitolo 4 Ordinamento:
Algoritmi e strutture Dati - Lezione 7
Camil Demetrescu, Irene Finocchi, Giuseppe F. ItalianoAlgoritmi e strutture dati Copyright © The McGraw - Hill Companies, srl Capitolo 4 Ordinamento:
Camil Demetrescu, Irene Finocchi, Giuseppe F. ItalianoAlgoritmi e strutture dati Capitolo 4 Ordinamento: Heapsort Algoritmi e Strutture Dati.
Algoritmi e Strutture Dati
Capitolo 4 Ordinamento Algoritmi e Strutture Dati.
Camil Demetrescu, Irene Finocchi, Giuseppe F. ItalianoAlgoritmi e strutture dati Copyright © The McGraw - Hill Companies, srl Usa la tecnica del.
Algoritmi e Strutture Dati
Capitolo 4 Ordinamento Algoritmi e Strutture Dati.
CORSO DI PROGRAMMAZIONE II Introduzione alla ricorsione
Algoritmi e Strutture Dati (Mod. A)
Alberi di Ricorrenza Gli alberi di ricorrenza rappresentano un modo conveniente per visualizzare i passi di sostitu- zione necessari per risolvere una.
Algoritmi e Strutture Dati III. Algoritmi di Ordinamento
Progetto di algoritmi: metodologia "Divide et Impera"
Algoritmi di ordinamento
Lalgoritmo MergeSort Applica la strategia del divide et impera Divide: suddivide la sequenza di n elementi data in due sottosequenze di n/2 elementi Impera:
QuickSort Quick-Sort(A,s,d) IF s < d THEN q = Partiziona(A,s,d) Quick-Sort(A,s,q-1) Quick-Sort(A,q + 1,d)
Fondamenti di Informatica1 Ripetizioni di segmenti di codice Spesso è necessario ripetere più volte uno stesso segmento dell'algoritmo (e.g. I/O, elaborazioni.
Elementi di Informatica di base
Radix-Sort(A,d) // A[i] = cd...c2c1
Algoritmi e Strutture Dati
Didattica dei Fondamenti dell’Informatica 2 Seconda giornata: progettare un algoritmo corretto, efficiente, e possibilmente ottimo! Guido Proietti
Per valutare la complessità ammortizzata scomponiamo ogni Union: nelle due FindSet e nella Link che la costituiscono e valuteremo la complessità in funzione.
Algoritmi e Strutture Dati
Heap Ordinamento e code di priorità Ugo de Liguoro.
La complessità media O(n log n) di Quick-Sort vale soltanto se tutte le permutazioni dell’array in ingresso sono ugualmente probabili. In molte applicazioni.
Ugo de'Liguoro - Informatica 2 a.a. 03/04 Lez. 3 Complessità computazionale concreta Corso di Informatica 2 a.a. 2003/04 Lezione 3.
Teoria degli algoritmi e della computabilità Terza giornata: Ricerca e ordinamento ottimi. P vs NP, algoritmi di approssimazione, e il potere della randomizzazione.
Algoritmi CHE COS’è UN ALGORITMO di ORDINAMENTO?
La ricorsione.
GLI ALGORITMI VISIBILE SUL BLOG INFORMATICA ANNO SCOLASTICO 2013 / 2014 GABRIELE SCARICA 2°T.
Soluzione 6: Algoritmo Quicksort
Capitolo 13 Cammini minimi: Algoritmo di Floyd e Warshall Algoritmi e Strutture Dati.
Algoritmi e Strutture Dati
Paola Disisto, Erika Griffini, Yris Noriega.  Insieme ordinato di operazioni non ambigue ed effettivamente computabili che, quando eseguito, produce.
Camil Demetrescu, Irene Finocchi, Giuseppe F. ItalianoAlgoritmi e strutture dati Copyright © The McGraw - Hill Companies, srl Capitolo 4 Ordinamento:
1 Ordinamento (Sorting) INPUT: Sequenza di n numeri OUTPUT: Permutazione π = tale che a 1 ’  a 2 ’  … …  a n ’ Continuiamo a discutere il problema dell’ordinamento:
Algoritmi e strutture Dati - Lezione 7 1 Algoritmi di ordinamento ottimali L’algoritmo Merge-Sort ha complessità O(n log(n))  Algoritmo di ordinamento.
Capitolo 10 Tecniche algoritmiche Algoritmi e Strutture Dati.
Capitolo 10 Tecniche algoritmiche Algoritmi e Strutture Dati.
Camil Demetrescu, Irene Finocchi, Giuseppe F. ItalianoAlgoritmi e strutture dati Copyright © The McGraw - Hill Companies, srl Capitolo 4 Ordinamento:
1 Ordinamento (Sorting) Input: Sequenza di n numeri Output: Permutazione π = tale che: a i 1  a i 2  ……  a i n Continuiamo a discutere il problema dell’ordinamento:
Codici prefissi Un codice prefisso è un codice in cui nessuna parola codice è prefisso (parte iniziale) di un’altra Ogni codice a lunghezza fissa è ovviamente.
Flusso di Costo Minimo Applicazione di algoritmi: Cammini Minimi Successivi (SSP) Esercizio 1 Sia data la seguente rete di flusso, in cui i valori riportati.
Problemi risolvibili con la programmazione dinamica Abbiamo usato la programmazione dinamica per risolvere due problemi. Cerchiamo ora di capire quali.
Complessità Computazionale
Didattica e Fondamenti degli Algoritmi e della Calcolabilità Quinta giornata Risolvere efficientemente un problema in P: ancora sulla sequenza di Fibonacci.
Didattica e Fondamenti degli Algoritmi e della Calcolabilità Sesta giornata Risolvere efficientemente un problema in P: Il problema dell’ordinamento: Insertion.
Problema dell’Ordinamento. Problema dell’ordinamento Formulazione del problema –Si vuole ordinare una lista di elementi secondo una data proprietà P Esempio:
L’ALGORITMO Un algoritmo è un procedimento formale che risolve un determinato problema attraverso un numero finito di passi. Un problema risolvibile mediante.
Capitolo 4 Ordinamento: lower bound Ω(n log n) e MergeSort ((*) l’intera lezione) Algoritmi e Strutture Dati.
Algoritmi e Strutture Dati HeapSort. Select Sort: intuizioni L’algoritmo Select-Sort  scandisce tutti gli elementi dell’array a partire dall’ultimo elemento.
Algoritmi e Strutture Dati Università di Camerino Corso di Laurea in Informatica (12 CFU) I periodo didattico Emanuela Merelli
Algoritmi e Strutture Dati Luciano Gualà
Rudimenti di Complessità Corso di Programmazione II Prof. Dario Catalano.
Lezione n. Parole chiave: Corso di Laurea: Insegnamento: Docente: A.A Salvatore Cuomo La ricorsione 15 Approccio ricorsivo, esercizi sulla.
Transcript della presentazione:

Divide et Impera Parte 11 - Risoluzione di problemi per divisione in sottoproblemi “bilanciati” Corso A: Prof. Stefano Berardi http://www.di.unito.it/~stefano Corso B: Prof. Ugo de’ Liguoro http://www.di.unito.it/~deligu

Divide et Impera

Indice Parte 11 La ricorsione è efficiente? Due algoritmi per il minimo e il massimo. Divide et Impera: l’ordinamento per fusione MergeSort. Un altro esempio di Divide et impera: il Quicksort Divide et Impera

1. La ricorsione è efficiente? Nel caso della ricorsione lineare l’efficienza di una funzione ricorsiva è paragonabile a quella di un’iterazione Negli esempi visti di ricorsione ad albero (fibonacci, coefficiente binomiale) la ricorsione è molto meno efficiente dell’iterazione. Questo è vero in generale? Molto dipende da come progettiamo gli algoritmi ricorsivi. Un metodo di progettazione per ottenere algoritmi ricorsivi ad albero efficienti, come vedremo, è il metodo del “Divide et Impera”. Divide et Im pera

Minimo e Massimo iterativo Come esempio di ricorsione efficiente vediamo una versione iterativa e una ricorsiva dell’algoritmo MinMax, che calcola il minimo ed il massimo tra i valori di un vettore A[]. void MinMax (int A[], int n, int& min, int& max) // pre: n > 0, ossia A[0..n-1] non e' vuoto // post: min e max sono il minimo ed il massimo // in A[0..n-1] rispettivamente { min = max = A[0]; for (int i = 1; i < n; i++) if (A[i] < min) min = A[i]; else if (max < A[i]) max = A[i];} Sia n=lun(A). L’algoritmo iterativo richiede (n-1) confronti per il minimo, (n-1) per il massimo, dunque 2n  2 confronti. Sembra difficile fare di meglio! Divide et Impera

Minimo e Massimo ricorsivo L’algoritmo DI_MinMax calcola il min e max in A[i..j] con un metodo di dimezzamenti analogo alla Ricerca Binaria. Se [i..j] ha al più due punti, calcola il minimo e il massimo direttamente. Altrimenti, divide l’intervallo A[i..j] in due parti il più possibile uguali, A[i..m] e A[m+1..j], dove m è il punto medio di [i..j] Calcola il massimo e il minimo (max1 e min1) di A[i..m], e il massimo e il minimo (max2 e min2) di A[m+1..j]. Il massimo di A[i..j] è il massimo di max1, max2, mentre il minimo di A[i..j] è il minimo di min1, min2. Divide et Impera

Minimo e Massimo ricorsivo void DI_MinMax(int A[], int i, int j, int& min, int& max) // pre: i <= j, ossia A[i..j] non e' vuoto // post: min e max sono il min/max in A[i..j] risp. { if (i == j) min = max = A[i]; else if (i == j-1) if (A[i] < A[j]) { min = A[i]; max = A[j];} else { min = A[j]; max = A[i];} else // i..j ha piu' di 2 elementi { int min1, max1, min2, max2; int m = (i + j)/2; // punto medio in i..j DI_MinMax(A, i, m, min1, max1); DI_MinMax(A, m+1, j, min2, max2); min = Min(min1, min2); max = Max(max1, max2); } Quanti sono i confronti richiesti nel caso ricorsivo? Divide et Impera

Minimo e Massimo: la ricorsione è più efficiente Se n = lun(A[i..j]) = j – i + 1 allora i confronti C (n) richiesti dall’algoritmo ricorsivo sono: 0 se n = 1 C (n) = 1 se n = 2 2C (n/2) + 2 se n > 2 Infatti: quando dividiamo il vettore in due vettori di lunghezza n/2, ognuno di essi ci richiede C(n/2) confronti, poi con un altro confronto calcoliamo il massimo tra i due massimi, con un altro ancora il minimo tra i due minimi. A questo punto, ragionando per induzione su n, è possibile dimostrare che i confronti sono C(n) = (3/2)n – 2. L’algoritmo iterativo è più semplice, ma richiede un numero maggiore di confronti: 2n-2. Divide et Impera

“Per meglio dominare occorre dividere gli avversari” 2. Divide et Impera “Per meglio dominare occorre dividere gli avversari” Ossia: suddividi il problema in sottoproblemi di dimensione circa eguale (“bilanciati”); risolvi i sottoproblemi con la ricorsione, infine combina i risultati MinMax e la Ricerca binaria sono esempi di algoritmi progettati con “Divide et Impera”. Il vantaggio del Divide et Impera è che la dimensione massima del sottoproblema che dobbiamo risolvere decresce esponenzialmente, e quindi scende rapidamente a zero. Per esempio, quando dividiamo in due sottoproblemi di dimensione uguale, la dimensione massima si dimezza ogni volta.

“Per meglio dominare occorre dividere gli avversari” 2. Divide et Impera “Per meglio dominare occorre dividere gli avversari” Ossia: suddividi il problema in sottoproblemi di dimensione circa eguale (“bilanciati”); risolvi i sottoproblemi con la ricorsione, infine combina i risultati Ecco come appare un programma “Divide et Impera” DivideEtImpera (P, n) // Pre: n è la dimensione del problema P if n  k then risolvi direttamente P else dividi P nei sottoproblemi P1,…, Ph di dimensioni n1,…, nh all’incirca uguali for i = 1 to h do Risi = DivideEtImpera (Pi, ni) return combinazione di Ris1, …, Rish uguale al risultato

“Per meglio dominare occorre dividere gli avversari” Divide et Impera “Per meglio dominare occorre dividere gli avversari” Ossia: suddividi il problema in sottoproblemi di dimensione circa eguale (“bilanciati”); risolvi i sottoproblemi con la ricorsione, infine combina i risultati In genere, una stima del tempo necessario si calcola cosí: Tempo per dividere Tempo per combinare Somma dei tempi dei sottoproblemi Divide et Impera

Esempio di “Divide et impera”: Ordinamento per fusione 88 14 98 25 62 52 79 30 23 31 dividi l’insieme da ordinare il più possibile a metà, in modo qualsiasi 14,23,30,62,79 … e l’altra metà da ordinare ad un altro 25,31,52,88,98 Affida una metà da ordinare ad un amico … Divide et Impera

Ordinamento per fusione 25,31,52,88,98 14,23,30,62,79 25,31,52,88,98 14,23,30,62,79 14,23,25,30,31,52,62,79,88,98 “Fondi” tra loro i due vettori ordinati ottenuti Fa solo attenzione che la “fusione” sia ordinata! Divide et Impera

Ordinamento per fusione o “MergeSort” void MergeSort(int A[], int i, int j) { if (i < j) { int m = (i+j)/2; MergeSort(A, i, m); MergeSort(A, m+1, j); /* per completare l’opera, devo solo “fondere” i segmenti ordinati A[i,m] e A[m+1,j] */ Merge(A, i, m, j); }} Divide et Impera

Fusione ordinata (merge) di due segmenti ordinati adiacenti Definiamo un metodo per “fondere” due segmenti ordinati consecutivi A[i..m] e A[m+1..j] in un segmento ordinato A[i...j] che comprende tutti i loro punti. Creiamo un vettore di appoggio B in cui costruire l’unione ordinata di A[i..m] e A[m+1..j]. Prendiamo il primo elemento di A[i..m] e il primo elemento di A[m+1..j] e li confrontiamo. Il più piccolo dei due diventa il minimo di B. Continuiamo così a togliere il più piccolo elemento rimasto da A[i…m] o da A[m+1..j] e a inserirlo in B, finché A[i..m] oppure A[m+1..j] diventano vuoti. A questo punto gli elementi rimasti in A[i..m] oppure A[m+1..j] sono i più grandi, e li ricopiamo in B. Finito di costruire B, lo ricopiamo all’indietro su A. Divide et Impera

I primi due passi del Merge 25,31,52,88,98 14,23,30,62,79 14 25,31,52,88,98 23,30,62,79 14 14, 23 Divide et Impera

Fusione ordinata (merge) di due segmenti ordinati adiacenti void Merge(int A[], int i, int m, int j) // pre: i <= m <= j A[i..m] e A[m+1..j] ordinati // post: A{i..j] e' ordinato {int* B = new int[j-i+1]; int p = i, q = m+1, k = 0; while (p <= m && q <= j) if (A[p]< A[q]) {B[k]=A[p];k++;p++} else {B[k]=A[q];k++;q++} /* se A[i..m] o A[m+1..j] sono vuoti copio tutti gli elementi rimasti in A[i..m] A[m+1..j] su B. */ Copy(A, p, m, B, k); Copy(A, q, j, B, k+(m-p+1)); /* Riporto il risultato da B in A */ Copy(B, 0, k-1, A, i); delete B;} Invariante while: A[p..m], A[q..j] ordinati, B[0..k – 1] ordinato ed i suoi elem. sono quelli di A[i..p – 1] e A[m+1..q – 1] Divide et Impera

La funzione di “copia” tra vettori Nel lucido precedente abbiamo utilizzato una funzione di “copia” definita come segue: void Copy(int A[], int i, int j, int B[], int k) // post: copia A[i..j] su B[] a partire da k { for (int h = i; h <= j; h++, k++) B[k] = A[h]; } Divide et Impera

Merge Sort: prima parte esecuzione (divisione) 7 4 1 8 2 3 6 5 7 4 1 8 2 3 6 5 7 4 1 8 2 3 6 5 7 4 1 8 2 3 6 5 Scomponiamo il vettore in segmenti di un punto soltanto (necessariamente ordinati!) Divide et Impera

Merge Sort: seconda parte esecuzione (merge) 1 2 3 4 5 6 7 8 1 4 7 8 2 3 5 6 4 7 1 8 2 3 5 6 7 4 1 8 2 3 6 5 Fondiamo tra loro i segmenti ordinati in segmenti più grandi, preservando l’ordine, fino a ricostruire il vettore Divide et Impera

Come si stima il tempo di calcolo di una funzione ricorsiva? Ricordiamo quanto abbiamo visto studiando i tempi di calcolo: a ogni algoritmo associamo un ordine di infinito per il tempo di calcolo nel caso peggiore. Per le funzioni ricorsive il tempo di calcolo è a sua volta definito ricorsivamente Per esempio, questa è la definizione ricorsiva del tempo di calcolo per la funzione ricorsiva “fattoriale” Divide et Impera

Il tempo di Merge Sort Questa è la definizione ricorsiva del tempo di calcolo per il MergeSort. Richiede di conoscere il tempo richiesto dal Merge: E’ facile vedere che dunque: Occorrono log2(n) dimezzamenti successivi per trasformare n in 1. Dunque la formula per calcolare T(n) ci chiede di sommare n per log2(n) volte (vedi prossimo lucido) Divide et Impera

Il tempo di Merge Sort Divide et Impera

Il tempo di Merge Sort Divide et Impera

Il tempo di Merge Sort Divide et Impera

Il tempo del Merge Sort è O(n log(n)) Albero delle chiamate ricorsive, ciascuna con il suo costo È possibile ordinare in tempo meno di O(n log n) ? Ogni “livello” dell’albero ha costo totale n, e i livelli sono + + + + Dunque la somma di tutti i costi è: Il MergeSort è ulteriormente migliorabile? Bisogna prima stabilire quale è il tempo minimo richiesto dall’ordinamento Divide et Impera

Alberi di decisione e limitazioni inferiori al tempo di calcolo Un albero rappresenta le decisioni prese da un algoritmo quando valgono le condizioni seguenti: i ”nodi interni” dell’albero rappresentano le decisioni prese dall’algoritmo le ”foglie” dell’albero rappresentano i possibili risultati dell’algoritmo i ”rami” dell’albero rappresentano particolari esecuzioni dell’algortimo. La minima lunghezza del ramo più lungo di un albero di decisione di un algoritmo fornisce una limitazione inferiore al numero di decisioni necessarie all’algoritmo nel caso peggiore. Divide et Impera

Alberi quasi perfettamente bilanciati Def. Un albero binario è completo se ha 2k vertici per ogni livello k non vuoto. Un albero binario è quasi perfettamente bilanciato (qpb) se, avendo altezza h, è completo sino al livello h 1 (come nella figura qui sopra). Le foglie di un albero quasi perfettamente bilanciato di altezza h sono in numero di: 2h1  s  2h , ovvero h  log2 (s) Quindi un problema la cui soluzione può rappresentarsi con un albero q.p.b. con s(n) possibili soluzioni richiede tempo almeno O(log2 s(n)) (la lunghezza del suo ramo più lungo).

Un esempio di albero q. p. b Un esempio di albero q.p.b. di decisione per l’ordinamento di 3 elementi a:b a < b b < a b:c b:c b < c c < b b < c c < b a, b, c a:c a:c b, c, a a < c c < a a < c c < a a, c, b c, a, b b, a, c b, c, a Ogni nodo corrisponde al confronto tra due elementi del vettore {a,b,c} da ordinare, ogni foglia è uno dei 3! = 6 possibili ordinamenti finali, la massima lunghezza di un “ramo” è 3, mentre la minima è 2 (dato che l’albero è q.p.b.). Divide et Impera

Il tempo di calcolo minimo richiesto dall’ordinamento Nel caso dell’ordinamento le foglie dell’albero di decisione sono s(n) = n! (il risultato di un algoritmo di ordinamento è una permutazione, dunque i risultati possibili sono n!). I nodi interni rappresentano i confronti tra due elementi. Nel caso dell’ordinamento il numero dei confronti nel caso peggiore deve essere dunque almeno log2(n!). Usando la formula di Stirling per n! concludiamo che: Ossia il tempo per ordinare è almeno O(nlog(n)). Algoritmi O(nlog(n)), come il MergeSort, impiegano dunque tempo minimo (a meno di costanti moltiplicative, che la Teoria del Tempo di Calcolo non considera). Divide et Impera

3. Divide et impera: il Quick Sort Dividi l’insieme in due scegliendo un elemento (detto “perno”) a caso, e disponendo gli elementi ≤ del perno da una parte e quelli ≥ dall’altra 88 14 98 25 62 52 79 30 23 31 14 25 30 23 31 88 98 62 79 ≤ 52 ≤ Divide et Impera

Quick Sort Fà ordinare una metà …e la seconda metà ad un amico … 14 25 30 23 31 88 98 62 79 ≤ 52 ≤ 14,23,25,30,31 Fà ordinare una metà ad un amico … 62,79,98,88 …e la seconda metà ad un altro amico Divide et Impera

Quick Sort 14,23,25,30,31 52 62,79,98,88 Metti insieme i due risultati con il perno in mezzo: formano un insieme ordinato senza bisogno di fare altro 14,23,25,30,31,52,62,79,88,98 Divide et Impera

Quick Sort (supponendo già definita la funzione Perno) void QuickSort(int A[], int i, int j) //pre: A[] e' un vettore, i <= j < dim. di A[] // post: ordina A in senso non decrescente { if (i < j) { int k = Perno(A, i, j); QuickSort(A, i, k); QuickSort(A, k+1, j); } Divide et Impera

Divisione di A[p,u] in due parti con il perno in mezzo int Perno (int A[], int p, int u) // pre: p <= u < dimensione di A[], x = A[p] “perno” // post: se y in A[p..j-1] allora y <= x, A[j-1] == x // se y in A[j..u] allora y >= x { int x = A[p], i = p+1, j = p+1; while (i <= u) // INVARIANTE. Se y in v[p+1..j-1] allora y < x // se z in v[j..i-1] allora z >= x if (A[i] < x) {swap(A[i], A[j]);i++;j++;} else i++; swap(A[p], A[j-1]); // inserisco il perno in mezzo return j-1;} // restituisco la posizione del perno Divide et Impera

Quick Sort: il caso pessimo 14,23,25,30,31,52,62,79,88,98 ≤ 14 ≤ 23,25,30,31,52,62,79,88,98 (vuoto) Se Perno sceglie sempre il primo elemento, allora il caso peggiore si verifica se la lista è già ordinata, perché la dimensione del secondo sottoproblema descresce molto lentamente, di un solo elemento alla volta. Divide et Impera

Il tempo peggiore per il Quick Sort è O(n2) Sia n la lunghezza del vettore da ordinare e p la posizione del primo perno da inserire poniamo Tempo = num. dei confronti Tempo della funzione Perno Caso peggiore: avviene quando p = 1. In tal caso, infatti, abbiamo P(n) = n – 1 e T(1) = 0, quindi deduciamo che: Divide et Impera

Il tempo medio per il Quick Sort è O(nlog(n)) Il tempo impiegato nel caso medio è la media dei tempi impiegati nelle n possibili posizioni del perno: p=0,…,n-1. p è la posizione del perno Partendo dalla formula per il tempo nel caso medio si dimostra che: Almeno, il QuickSort è ottimo nel caso medio: richiede tempo medio O(nlog(n)) Divide et Impera

Fine del Corso di Informatica 2009/2010 Divide et Impera