Complessità e Ordinamento
Ezio Sperduto
Notazioni Asintotiche
grandi O(…) Ω(…) Θ(…)
piccole o(…) ω(…)piccole o(…) ω(…)
definiscono ordini di grandezza delle funzi...
Notazioni Asintotiche
parametro n: dimensione dell’input
T(n)=O(n2)T(n)=O(n2)
Complessità temporale Classe delle funzioni
...
Notazioni Asintotiche
Formalmente:
f(n) ∈ O(g(n))∈
O(g(n)) =
{h(n): ∃x0, c t.c. ∀n≥x0 ⇒ 0 ≤ h(n) ≤ c·g(n)}
Notazioni Asintotiche
(a) f(n) è stretta tra c1·g(n) e c2·g(n) Θ(g(n))
(b) f(n) è spinta sotto la funzione c·g(n) O(g(n))
...
Notazioni Asintotiche
Θ(n)
Θ(n log n)
Θ(n2)
Θ(log n)
Gli ordini di grandezza identificano delle
CLASSI di COMPLESSITA’
Scr...
Notazioni Asintotiche
Notazioni grandi e notazioni piccole:
f(n)=O(g(n)) f(n) ≤ classe di g(n)
la notazione O-grande indic...
Complessità Temporale
Classi di complessità asintotica più note:
O(1) costante
O(logn) logaritmico
O(n) lineare
O(nlogn) l...
Ordinamento
Input: a1, a2,…,an
sequenza di valori (interi) non-ordinata
Output: a’1, a’2,…,a’n
permutazione ordinata dei v...
Ordinamento
La tecnica di ordinamento varia in base agli
elementi da ordinare:
- valori
- strutture/oggetti con attributo ...
HeapSort
Basato su struttura Heap: albero binario con 2 proprietà
- Heap property: un nodo contiene un valore
maggiore dei...
HeapSort
Heap property
HeapSort
Implementazione mediante vettore, per livelli:
left(i) = 2*i
right(i) = 2*i + 1
HeapSort
Operazione Heapify:
- input: nodo v dell’heap
(assunto: i sottoalberi sono heap)
- output: il sottoalbero su v è ...
HeapSort
void heapify(int[] h, int i){
int sx=left(i);
int dx=right(i);
int m=indMax(h, sx, dx, i);
complessità:
O(logn)
a...
HeapSort
void buildHeap(int[] h){
for(int i=h.length/2; i>=0; i--)
heapify(h,i);
}
complessità:
O(n)
analisi ammortizzata
...
HeapSort
void heapSort(int[] h){
buildheap(h); O(n)
for(int i=h.length-1; i<=1;i--){ O(n)for(int i=h.length-1; i<=1;i--){ ...
HeapSort
Caso peggiore: O(nlogn)
Caso migliore: O(nlogn)
Caso medio: O(nlogn)
Complessità spaziale: O(1)
Stabile: no
In pl...
QuickSort
void quickSort(int[] a, int n1, int n2){
if(n1<n2){
p=partition(a,n1,n2);
quickSort(a,n1,p);
quickSort(a,p+1,n2)...
QuickSort
Metodo partition (versione di Hoare):
int partition(int[] a, int n1, int n2){
int x=a[n1];
int i=n1-1;
int j=n2+...
QuickSort
Caso peggiore: O(n2)
Caso migliore: O(nlogn)
Caso medio: O(nlogn)
Complessità spaziale: O(logn)
Stabile: no
In p...
Ordinamento
Algoritmo Peggiore Medio Migliore Memoria Stabile In Place
CountingSort O(n+k) O(n+k) O(n+k) O(n+k) SI NO
Heap...
Ordinamento
java.util.Arrays.sort(…)
The sorting algorithm is a Dual-Pivot Quicksort by
Vladimir Yaroslavskiy, Jon Bentley...
Ordinamento
OpenJDK: java.util.Arrays.sort(…)
private static void sort1(int x[], int off, int len) {
// Insertion sort on ...
Ordinamento
java.util.Collections.sort(…)
• Implementation note: This implementation is a stable, adaptive, iterative merg...
Upcoming SlideShare
Loading in …5
×

Complessità e ordinamento di Ezio Sperduto

1,902 views

Published on

Published in: Technology
  • Be the first to comment

  • Be the first to like this

Complessità e ordinamento di Ezio Sperduto

  1. 1. Complessità e Ordinamento Ezio Sperduto
  2. 2. Notazioni Asintotiche grandi O(…) Ω(…) Θ(…) piccole o(…) ω(…)piccole o(…) ω(…) definiscono ordini di grandezza delle funzioni
  3. 3. Notazioni Asintotiche parametro n: dimensione dell’input T(n)=O(n2)T(n)=O(n2) Complessità temporale Classe delle funzioni quadratiche
  4. 4. Notazioni Asintotiche Formalmente: f(n) ∈ O(g(n))∈ O(g(n)) = {h(n): ∃x0, c t.c. ∀n≥x0 ⇒ 0 ≤ h(n) ≤ c·g(n)}
  5. 5. Notazioni Asintotiche (a) f(n) è stretta tra c1·g(n) e c2·g(n) Θ(g(n)) (b) f(n) è spinta sotto la funzione c·g(n) O(g(n)) (c) f(n) è spinta sopra la funzione c·g(n) Ω(g(n))
  6. 6. Notazioni Asintotiche Θ(n) Θ(n log n) Θ(n2) Θ(log n) Gli ordini di grandezza identificano delle CLASSI di COMPLESSITA’ Scrivere T(n)=O(log n) equivale a scrivere “correttamente” T(n) ∈ O(log n)
  7. 7. Notazioni Asintotiche Notazioni grandi e notazioni piccole: f(n)=O(g(n)) f(n) ≤ classe di g(n) la notazione O-grande indica un limite superiore non strettola notazione O-grande indica un limite superiore non stretto f(n)=o(g(n)) f(n) < classe di g(n) la notazione O-piccola indica un limite superiore stretto
  8. 8. Complessità Temporale Classi di complessità asintotica più note: O(1) costante O(logn) logaritmico O(n) lineare O(nlogn) log-lineareO(nlogn) log-lineare O(n2) quadratico O(n3) cubico O(n4) ….. polinomiali superiori O(cn) esponenziale O(n!) super-esponenziale …
  9. 9. Ordinamento Input: a1, a2,…,an sequenza di valori (interi) non-ordinata Output: a’1, a’2,…,a’n permutazione ordinata dei valori in input
  10. 10. Ordinamento La tecnica di ordinamento varia in base agli elementi da ordinare: - valori - strutture/oggetti con attributo discriminante- strutture/oggetti con attributo discriminante La tecnica di ordinamento varia in base alla struttura contenitore: - array / blocco di memoria ad accesso costante - lista collegata di elementi
  11. 11. HeapSort Basato su struttura Heap: albero binario con 2 proprietà - Heap property: un nodo contiene un valore maggiore dei sottoalberimaggiore dei sottoalberi - shape property: albero completo tranne ultimo livello altezza dell’albero O(logn)
  12. 12. HeapSort Heap property
  13. 13. HeapSort Implementazione mediante vettore, per livelli: left(i) = 2*i right(i) = 2*i + 1
  14. 14. HeapSort Operazione Heapify: - input: nodo v dell’heap (assunto: i sottoalberi sono heap) - output: il sottoalbero su v è un heap (il valore di v potrà essere scambiato con i valori nei sottoalberi)
  15. 15. HeapSort void heapify(int[] h, int i){ int sx=left(i); int dx=right(i); int m=indMax(h, sx, dx, i); complessità: O(logn) applicato alla radice int m=indMax(h, sx, dx, i); if(i != m){ swapValue(h,i,m); heapify(h,m) } }
  16. 16. HeapSort void buildHeap(int[] h){ for(int i=h.length/2; i>=0; i--) heapify(h,i); } complessità: O(n) analisi ammortizzata } Applico heapify a tutti i nodi con figli dell’heap. Partendo dall’ultimo, fino al primo.
  17. 17. HeapSort void heapSort(int[] h){ buildheap(h); O(n) for(int i=h.length-1; i<=1;i--){ O(n)for(int i=h.length-1; i<=1;i--){ O(n) swapValue(h,0,i); O(1) heapify(h,0,i-1); O(logn) } } Il terzo parametro nell’heapify diminuisce la dimensione. Complessità: O(nlogn)
  18. 18. HeapSort Caso peggiore: O(nlogn) Caso migliore: O(nlogn) Caso medio: O(nlogn) Complessità spaziale: O(1) Stabile: no In place: si
  19. 19. QuickSort void quickSort(int[] a, int n1, int n2){ if(n1<n2){ p=partition(a,n1,n2); quickSort(a,n1,p); quickSort(a,p+1,n2); } }
  20. 20. QuickSort Metodo partition (versione di Hoare): int partition(int[] a, int n1, int n2){ int x=a[n1]; int i=n1-1; int j=n2+1; while(true){ vettore a Pivot valori ≤ valori ≥ i j while(true){ do j--; while(!(a[j]<=x)); do i++; while(!(a[i]>=x)); if(i<j) swap(A,i,j); else return j; } }
  21. 21. QuickSort Caso peggiore: O(n2) Caso migliore: O(nlogn) Caso medio: O(nlogn) Complessità spaziale: O(logn) Stabile: no In place: si
  22. 22. Ordinamento Algoritmo Peggiore Medio Migliore Memoria Stabile In Place CountingSort O(n+k) O(n+k) O(n+k) O(n+k) SI NO HeapSort O(nlogn) O(nlogn) O(nlogn) O(1) NO SI QuickSort(2) O(nlogn) O(nlogn) O(nlogn) O(nlogn) NO SI MergeSort O(nlogn) O(nlogn) O(nlogn) O(n) SI NO SelectionSort O(n2) O(n2) O(n2) O(1) NO SISelectionSort O(n ) O(n ) O(n ) O(1) NO SI InsertionSort O(n2) O(n2) O(n) O(1) SI SI BubbleSort O(n2) O(n2) O(n) O(1) SI SI QuickSort(1) O(n2) O(nlogn) O(nlogn) O(nlogn) NO SI StupidSort Illimitato O(n*n!) O(n) O(n) NO SI
  23. 23. Ordinamento java.util.Arrays.sort(…) The sorting algorithm is a Dual-Pivot Quicksort by Vladimir Yaroslavskiy, Jon Bentley, and JoshuaVladimir Yaroslavskiy, Jon Bentley, and Joshua Bloch. This algorithm offers O(n log(n)) performance on many data sets that cause other quicksorts to degrade to quadratic performance, and is typically faster than traditional (one-pivot) Quicksort implementations.
  24. 24. Ordinamento OpenJDK: java.util.Arrays.sort(…) private static void sort1(int x[], int off, int len) { // Insertion sort on smallest arrays if (len < 7) { … } // Choose a partition element, v … // Establish Invariant: v* (<v)* (>v)* v* … // Swap partition elements back to middle … // Recursively sort non-partition-elements … }
  25. 25. Ordinamento java.util.Collections.sort(…) • Implementation note: This implementation is a stable, adaptive, iterative mergesort that requires far fewer than n lg(n) comparisons when the input array is partially sorted, while offering the performance of a traditional mergesort when the input array is randomly ordered. If the input array is nearly sorted, the implementation requires approximately n comparisons. Temporary storage requirements vary from a small constant for nearly sorted input arrays to n/2 object references for randomly ordered input arrays. • The implementation takes equal advantage of ascending and descending order in its input• The implementation takes equal advantage of ascending and descending order in its input array, and can take advantage of ascending and descending order in different parts of the same input array. It is well-suited to merging two or more sorted arrays: simply concatenate the arrays and sort the resulting array. • The implementation was adapted from Tim Peters's list sort for Python (TimSort). It uses techiques from Peter McIlroy's "Optimistic Sorting and Information Theoretic Complexity", in Proceedings of the Fourth Annual ACM-SIAM Symposium on Discrete Algorithms, pp 467- 474, January 1993. • This implementation dumps the specified list into an array, sorts the array, and iterates over the list resetting each element from the corresponding position in the array. This avoids the n2 log(n) performance that would result from attempting to sort a linked list in place.

×