Complessità e ordinamento di Ezio Sperduto

25
Complessità e Ordinamento Ezio Sperduto

description

 

Transcript of Complessità e ordinamento di Ezio Sperduto

Page 1: Complessità e ordinamento di Ezio Sperduto

Complessità e Ordinamento

Ezio Sperduto

Page 2: Complessità e ordinamento di Ezio Sperduto

Notazioni Asintotiche

grandi O(…) Ω(…) Θ(…)

piccole o(…) ω(…)piccole o(…) ω(…)

definiscono ordini di grandezza delle funzioni

Page 3: Complessità e ordinamento di Ezio Sperduto

Notazioni Asintotiche

parametro n: dimensione dell’input

T(n)=O(n2)T(n)=O(n2)

Complessità temporale Classe delle funzioni

quadratiche

Page 4: Complessità e ordinamento di Ezio Sperduto

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)

Page 5: Complessità e ordinamento di Ezio Sperduto

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))

Page 6: Complessità e ordinamento di Ezio Sperduto

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)

Page 7: Complessità e ordinamento di Ezio Sperduto

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

Page 8: Complessità e ordinamento di Ezio Sperduto

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

Page 9: Complessità e ordinamento di Ezio Sperduto

Ordinamento

Input: a1, a2,…,an

sequenza di valori (interi) non-ordinata

Output: a’1, a’2,…,a’n

permutazione ordinata dei valori in input

Page 10: Complessità e ordinamento di Ezio Sperduto

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

Page 11: Complessità e ordinamento di Ezio Sperduto

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)

Page 12: Complessità e ordinamento di Ezio Sperduto

HeapSort

Heap property

Page 13: Complessità e ordinamento di Ezio Sperduto

HeapSort

Implementazione mediante vettore, per livelli:

left(i) = 2*i

right(i) = 2*i + 1

Page 14: Complessità e ordinamento di Ezio Sperduto

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)

Page 15: Complessità e ordinamento di Ezio Sperduto

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)

Page 16: Complessità e ordinamento di Ezio Sperduto

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.

Page 17: Complessità e ordinamento di Ezio Sperduto

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)

Page 18: Complessità e ordinamento di Ezio Sperduto

HeapSort

Caso peggiore: O(nlogn)

Caso migliore: O(nlogn)

Caso medio: O(nlogn)

Complessità spaziale: O(1)

Stabile: no

In place: si

Page 19: Complessità e ordinamento di Ezio Sperduto

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);

Page 20: Complessità e ordinamento di Ezio Sperduto

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;

Page 21: Complessità e ordinamento di Ezio Sperduto

QuickSort

Caso peggiore: O(n2)

Caso migliore: O(nlogn)

Caso medio: O(nlogn)

Complessità spaziale: O(logn)

Stabile: no

In place: si

Page 22: Complessità e ordinamento di Ezio Sperduto

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

Page 23: Complessità e ordinamento di Ezio Sperduto

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.

Page 24: Complessità e ordinamento di Ezio Sperduto

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

Page 25: Complessità e ordinamento di Ezio Sperduto

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.