View
1.346
Download
2
Category
Preview:
DESCRIPTION
Citation preview
Complessità e Ordinamento
Ezio Sperduto
Notazioni Asintotiche
grandi O(…) Ω(…) Θ(…)
piccole o(…) ω(…)piccole o(…) ω(…)
definiscono ordini di grandezza delle funzioni
Notazioni Asintotiche
parametro n: dimensione dell’input
T(n)=O(n2)T(n)=O(n2)
Complessità temporale Classe delle funzioni
quadratiche
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))
(c) f(n) è spinta sopra la funzione c·g(n) Ω(g(n))
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)
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
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
…
Ordinamento
Input: a1, a2,…,an
sequenza di valori (interi) non-ordinata
Output: a’1, a’2,…,a’n
permutazione ordinata dei valori in input
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
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)
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 è un heap
(il valore di v potrà essere scambiato con i valori
nei sottoalberi)
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)
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.
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)
HeapSort
Caso peggiore: O(nlogn)
Caso migliore: O(nlogn)
Caso medio: O(nlogn)
Complessità spaziale: O(1)
Stabile: no
In place: si
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);
QuickSortMetodo 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;
QuickSort
Caso peggiore: O(n2)
Caso migliore: O(nlogn)
Caso medio: O(nlogn)
Complessità spaziale: O(logn)
Stabile: no
In place: si
OrdinamentoAlgoritmo 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
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.
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
…
Ordinamentojava.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.
Recommended