Algoritmi e Strutture Dati
Capitolo 4
Ordinamento
Algoritmi e strutture dati
Luigi Laura
Ordinamento
Dato un insieme S di n oggetti presi da un
dominio totalmente ordinato, ordinare S
• Esempi: ordinare alfabeticamente lista di nomi,
o insieme di numeri, o insieme di compiti
d’esame in base a cognome studente
• Subroutine di molti problemi
• E’ possibile effettuare ricerche in array ordinati
in tempo O(log n)
2
da Demetrescu et al. McGraw Hill 2004
Algoritmi e strutture dati
Luigi Laura
Algoritmi e tempi tipici
• Numerosi algoritmi
• Tre tempi tipici: O(n2), O(n log n), O(n)
n
10
100
n log2 n
~ 33
~ 665
n2
100
104
1000
106
109
~ 104 ~ 2 · 107 ~ 3 · 1010
106
1012
1018
da Demetrescu et al. McGraw Hill 2004
3
Algoritmi e strutture dati
Luigi Laura
Algoritmi di ordinamento
4
da Demetrescu et al. McGraw Hill 2004
Algoritmi e strutture dati
Luigi Laura
SelectionSort
Approccio incrementale. Estende ordinamento da k a
(k+1) elementi, scegliendo minimo tra (n-k) elementi
non ancora ordinati e mettendolo in posizione (k+1)
da Demetrescu et al. McGraw Hill 2004
5
Algoritmi e strutture dati
Luigi Laura
SelectionSort: analisi
k - esima estrazione di minimo costa tempo O(n-k)
In totale, il tempo di esecuzione è:
n-1
∑ O(n-k)
k=1
n-1
=
O
( ∑ i) = O(n )
2
i=1
[ cambiamento di variabile (i = n – k) e serie aritmetica ]
6
da Demetrescu et al. McGraw Hill 2004
Algoritmi e strutture dati
Luigi Laura
InsertionSort
Approccio incrementale. Estende ordinamento da k a (k+1)
elementi, posizionando elemento (k+1)-esimo nella
posizione corretta rispetto ai primi k elementi
da Demetrescu et al. McGraw Hill 2004
7
Algoritmi e strutture dati
Luigi Laura
InsertionSort: analisi
Inserimento del k-esimo elemento nella posizione corretta
rispetto ai primi k richiede tempo O(k) nel caso peggiore
In totale, il tempo di esecuzione è :
n-1
O
( ∑ k) = O(n )
2
k=1
[ serie aritmetica ]
8
da Demetrescu et al. McGraw Hill 2004
Algoritmi e strutture dati
Luigi Laura
BubbleSort
• Esegue una serie di scansioni dell’array
– In ogni scansione confronta coppie di elementi
adiacenti, scambiandoli se non sono nell’ordine
corretto
– Dopo una scansione in cui non viene effettuato
nessuno scambio l’array è ordinato
• Dopo la k-esima scansione, i k elementi più
grandi sono correttamente ordinati ed occupano le
k posizioni più a destra
correttezza e tempo
2
di esecuzione O(n )
9
Algoritmi e strutture dati
da Demetrescu et al. McGraw Hill 2004
Luigi Laura
Esempio di esecuzione
10
da Demetrescu et al. McGraw Hill 2004
Algoritmi e strutture dati
Luigi Laura
O( n2 ) è quanto di peggio si possa
fare: tutti i confronti possibili!
Possiamo fare di meglio ?
da Demetrescu et al. McGraw Hill 2004
11
Algoritmi e strutture dati
Luigi Laura
1. QuickSort
2. MergeSort
3. HeapSort
12
da Demetrescu et al. McGraw Hill 2004
Algoritmi e strutture dati
Luigi Laura
QuickSort
• Usa la tecnica del divide et impera:
1 Divide: scegli un elemento x della sequenza
(pivot) e partiziona la sequenza in elementi ≤
x ed elementi > x
2 Risolvi i due sottoproblemi ricorsivamente
3 Impera: restituisci la concatenazione delle
due sottosequenze ordinate
da Demetrescu et al. McGraw Hill 2004
13
Algoritmi e strutture dati
Luigi Laura
Partizione in loco
• Scorri l’array “in parallelo” da sinistra verso
destra e da destra verso sinistra
– da sinistra verso destra, ci si ferma su un elemento
maggiore del pivot
– da destra verso sinistra, ci si ferma su un elemento
minore del pivot
• Scambia gli elementi e riprendi la scansione
Tempo di esecuzione: O(n)
14
da Demetrescu et al. McGraw Hill 2004
Algoritmi e strutture dati
Luigi Laura
Partizione in loco: un esempio
da Demetrescu et al. McGraw Hill 2004
15
Algoritmi e strutture dati
Luigi Laura
Analisi nel caso peggiore
• Nel caso peggiore, il pivot scelto ad ogni
passo è il minimo o il massimo degli elementi
nell’array
• Il numero di confronti nel caso peggiore è :
C(n) = C(n-1) + O(n)
• Risolvendo per iterazione si ottiene
C(n) = O(n2)
16
da Demetrescu et al. McGraw Hill 2004
Algoritmi e strutture dati
Luigi Laura
Esempio di
esecuzione
L’albero delle
chiamate
ricorsive può
essere
sbilanciato
da Demetrescu et al. McGraw Hill 2004
17
Algoritmi e strutture dati
Luigi Laura
Randomizzazione
• Possiamo evitare il caso peggiore scegliendo
come pivot un elemento a caso
• Poiché ogni elemento ha la stessa probabilità,
pari a 1/n, di essere scelto come pivot, il
numero di confronti nel caso atteso è:
n-1
C(n)=
∑
a=0
n-1
1 n-1+C(a)+C(n-a-1) = n-1+ ∑ 2 C(a)
n
n
a=0
dove a e (n-a-1) sono le dimensioni dei sottoproblemi
risolti ricorsivamente
18
da Demetrescu et al. McGraw Hill 2004
Algoritmi e strutture dati
Luigi Laura
Analisi nel caso medio
n-1
La relazione di ricorrenza C(n)= n-1+ ∑ 2n C(a)
ha soluzione C(n) ≤ 2 n log n
a=0
Dimostrazione per sostituzione
Assumiamo per ipotesi induttiva che C(i) ≤ 2 i log i
n-1
C(n)≤ n-1+ ∑ 2 2 i log i ≤ n-1+ 2
n
n
i=0
n
∫2
x log x dx
Integrando per parti si dimostra che C(n) ≤ 2 n log n
da Demetrescu et al. McGraw Hill 2004
19
Algoritmi e strutture dati
Luigi Laura
MergeSort
Usiamo la tecnica del divide et impera:
1 Divide: dividi l’array a metà
2 Risolvi il sottoproblema ricorsivamente
3 Impera: fondi le due sottosequenze ordinate
Rispetto a QuickSort, divide semplice ed impera complicato
20
da Demetrescu et al. McGraw Hill 2004
Algoritmi e strutture dati
Luigi Laura
Fusione (Merge)
• Due array ordinati A e B possono essere fusi
rapidamente:
– estrai ripetutamente il minimo di A e B e copialo
nell’array di output, finché A oppure B non
diventa vuoto
– copia gli elementi dell’array non vuoto alla fine
dell’array di output
• Tempo: O(n), dove n è il numero totale di
elementi
da Demetrescu et al. McGraw Hill 2004
21
Algoritmi e strutture dati
Luigi Laura
Mergesort: esempio di esecuzione
Input ed
output delle
chiamate
ricorsive
22
da Demetrescu et al. McGraw Hill 2004
Algoritmi e strutture dati
Luigi Laura
Tempo di esecuzione
• Numero di confronti del MergeSort descritto
da relazione di ricorrenza:
C(n) = 2 C(n/2) + O(n)
• Da Teorema Master si ottiene la soluzione
C(n) = O(n log n)
da Demetrescu et al. McGraw Hill 2004
23
Algoritmi e strutture dati
Luigi Laura
HeapSort
• Stesso approccio incrementale del SelectionSort
• Usa però struttura dati più efficiente per estrarre
massimo ad ogni iterazione
• Struttura dati heap associata ad insieme S :
albero binario radicato con le seguenti proprietà:
1) completo fino al penultimo livello
2) elementi di S memorizzati nei nodi dell’albero
3) chiave(padre(v)) ≥ chiave(v) per ogni nodo v
24
da Demetrescu et al. McGraw Hill 2004
Algoritmi e strutture dati
Luigi Laura
Struttura dati heap
Rappresentazione ad albero e con vettore posizionale
sin(i) = 2i
des(i) = 2i+1
da Demetrescu et al. McGraw Hill 2004
25
Algoritmi e strutture dati
Luigi Laura
Heap con struttura rafforzata
Le foglie nell’ultimo livello sono compattate a sinistra
Il vettore
posizionale ha
esattamente
dimensione n
26
da Demetrescu et al. McGraw Hill 2004
Algoritmi e strutture dati
Luigi Laura
Proprietà salienti degli heap
1) Il massimo è contenuto nella radice
2) L’albero ha altezza O(log n)
3) Gli heap con struttura rafforzata possono
essere rappresentati in un array di
dimensione n
da Demetrescu et al. McGraw Hill 2004
27
Algoritmi e strutture dati
Luigi Laura
La procedura fixHeap
Se tutti i nodi di H tranne v soddisfano la proprietà di
ordinamento a heap, possiamo ripristinarla come segue:
fixHeap(nodo v, heap H)
if (v è una foglia) then return
else
sia u il figlio di v con chiave massima
if ( chiave(v) < chiave(u) ) then
scambia chiave(v) e chiave(u)
fixHeap(u,H)
Tempo di esecuzione: O(log n)
28
da Demetrescu et al. McGraw Hill 2004
Algoritmi e strutture dati
Luigi Laura
Estrazione del massimo
• Copia nella radice la chiave contenuta nella
la foglia più a destra dell’ultimo livello
• Rimuovi la foglia
• Ripristina la proprietà di ordinamento a
heap richiamando fixHeap sulla radice
Tempo di esecuzione: O(log n)
da Demetrescu et al. McGraw Hill 2004
29
Algoritmi e strutture dati
Luigi Laura
Costruzione dell’heap
Algoritmo ricorsivo basato su divide et impera
heapify(heap H)
if (H è vuoto) then return
else
heapify(sottoalbero sinistro di H)
heapify(sottoalbero destro di H)
fixHeap(radice di H,H)
Tempo di esecuzione: T(n) = 2 T(n/2) + O(log n)
T(n) = O(n)
30
dal Teorema Master
da Demetrescu et al. McGraw Hill 2004
Algoritmi e strutture dati
Luigi Laura
HeapSort
• Costruisci un heap tramite
heapify
• Estrai ripetutamente il massimo
per (n-1) volte
O(n)
O(n log n)
– ad ogni estrazione memorizza il massimo
nella posizione dell’array che si è appena
liberata
ordina “in loco” in tempo O(n log n)
31
da Demetrescu et al. McGraw Hill 2004
Algoritmi e strutture dati
Luigi Laura
Possiamo fare meglio
di O(n log n)?
32
da Demetrescu et al. McGraw Hill 2004
Algoritmi e strutture dati
Luigi Laura
Lower bound
• Dimostrazione (matematica) che non possiamo
andare più veloci di una certa quantità
• Più precisamente, ogni algoritmo all’interno di un
certo modello di calcolo deve avere tempo di
esecuzione almeno pari a quella quantità
• Non significa necessariamente che non è possibile
fare di meglio
• Potrebbe essere possibile fare di meglio al di fuori
di quel modello
33
da Demetrescu et al. McGraw Hill 2004
Algoritmi e strutture dati
Luigi Laura
Lower bound
• Delimitazione inferiore: quantità di risorsa
necessaria per risolvere un determinato problema
• Dimostrare che Ω(n log n) è lower bound al
numero di confronti richiesti per ordinare n oggetti.
• Come?
• Dobbiamo dimostrare che tutti gli algoritmi
richiedono Ω(n log n) confronti!
34
da Demetrescu et al. McGraw Hill 2004
Algoritmi e strutture dati
Luigi Laura
Modello basato su confronti
• In questo modello, per ordinare è possibile
usare solo confronti tra oggetti
• Primitive quali operazioni aritmetiche
(somme o prodotti), logiche (and e or), o altro
(shift) sono proibite
• Sufficientemente generale per catturare le
proprietà degli algoritmi più noti
da Demetrescu et al. McGraw Hill 2004
35
Algoritmi e strutture dati
Luigi Laura
Come dimostrare lower bound
• Consideriamo un qualsiasi algoritmo A, che
ordina solo mediante confronti
• Non abbiamo assolutamente idea di come
funziona A !
• Ciò nonostante, dimostreremo che A deve
eseguire almeno Ω(n log n) confronti
• Dato che l’unica ipotesi su A è che ordini
mediante confronti, il lower bound sarà valido
per tutti gli algoritmi basati su confronti!
36
da Demetrescu et al. McGraw Hill 2004
Algoritmi e strutture dati
Luigi Laura
Alberi di decisione
• Strumenti per rappresentare algoritmi di
ordinamento
• Descrivono sequenza di confronti che un
algoritmo esegue su istanze di lunghezza n
37
da Demetrescu et al. McGraw Hill 2004
Algoritmi e strutture dati
Luigi Laura
Alberi di decisione
= algoritmi basati
su confronti!
• Ogni algoritmo basato su confronti può essere
rappresentato da un albero di decisione:
– confronti scelti dall’algoritmo possono dipendere solo
dagli esiti dei confronti precedenti!
• Un albero di decisione può essere “letto” come
algoritmo basato su confronti:
– per ogni input, il cammino nell’albero descrive confronti
da effettuare e permutazione che produce soluzione
38
da Demetrescu et al. McGraw Hill 2004
Algoritmi e strutture dati
Luigi Laura
Proprietà alberi di decisione
• Per una particolare istanza, i confronti eseguiti
da A su quella istanza sono rappresentati da un
cammino radice - foglia
• Il numero di confronti nel caso peggiore è pari
all’altezza dell’albero di decisione
• Un albero di decisione per l’ordinamento di n
elementi contiene almeno (n!) foglie
(una per ogni possibile permutazione degli n oggetti)
da Demetrescu et al. McGraw Hill 2004
39
Algoritmi e strutture dati
Luigi Laura
Lower bound
• Un albero binario con k foglie tale che ogni
nodo interno ha esattamente due figli ha
altezza almeno log2 k
• Dimostrazione per induzione su k:
– Passo base: 0 ≥ log2 1
– h(k) ≥ 1 + h(k/2) poiché uno dei due sottoalberi ha
almeno metà delle foglie
– h(k/2) ≥ log2 (k/2) per ipotesi induttiva
– h(k) ≥ 1 + log2 (k/2) = log2 k
40
da Demetrescu et al. McGraw Hill 2004
Algoritmi e strutture dati
Luigi Laura
Il lower bound Ω (n log n)
• L’albero di decisione ha almeno n! foglie
• La sua altezza è almeno log2 (n!)
• Formula di Stirling: n! ≥ (2πn)1/2 · (n/e) n
• Quindi: log2 (n!) = Ω (n log n)
da Demetrescu et al. McGraw Hill 2004
41
Algoritmi e strutture dati
Luigi Laura
Ordinamenti lineari
(per dati con proprietà particolari)
42
da Demetrescu et al. McGraw Hill 2004
Algoritmi e strutture dati
Luigi Laura
Sappiamo che gli n elementi da ordinare
sono tutti distinti e nell’intervallo [1,n]
In quanto tempo possiamo ordinarli?
O(1)
Contraddice il lower bound?
No. Perché?
da Demetrescu et al. McGraw Hill 2004
43
Algoritmi e strutture dati
Luigi Laura
IntegerSort: fase 1
Meno banale: ordinare n interi con valori in [1,k]
Mantieni array Y di k contatori tale che
Y[x] = numero di occorrenze di x
44
da Demetrescu et al. McGraw Hill 2004
Algoritmi e strutture dati
Luigi Laura
IntegerSort: fase 2
Scandisci Y da sinistra verso destra.
Se Y[x] = k, scrivi in X il valore x per k volte
da Demetrescu et al. McGraw Hill 2004
45
Algoritmi e strutture dati
Luigi Laura
IntegerSort: analisi
• O(k) per inizializzare contatori a 0
• O(n) per calcolare valori dei contatori
• O(n + k) per ricostruire sequenza ordinata
O(n + k)
Tempo lineare se k = O(n)
46
da Demetrescu et al. McGraw Hill 2004
Algoritmi e strutture dati
Luigi Laura
BucketSort
Per ordinare n record con chiavi intere in [1,k]
• Basta mantenere un array di liste, anziché di
contatori, ed operare come per IntegerSort
• La lista Y[x] conterrà gli elementi con chiave
uguale a x
• Concatenare poi le liste
Tempo O(n + k) come per IntegerSort
47
Algoritmi e strutture dati
da Demetrescu et al. McGraw Hill 2004
Luigi Laura
Stabilità
• Un algoritmo è stabile se preserva ordine iniziale
tra elementi uguali (stessa chiave)
• QuickSort è stabile se la partizione lo rende
stabile
• MergeSort è stabile se divisione lo rende stabile
(pari e dispari non lo rende stabile)
• HeapSort non è stabile
• BucketSort può essere reso stabile appendendo
gli elementi di X in coda alla opportuna lista Y[i]
48
da Demetrescu et al. McGraw Hill 2004
Algoritmi e strutture dati
Luigi Laura
RadixSort
• Cosa fare se k > n, ad esempio k = Θ(nc)?
• Rappresentiamo gli elementi in base b, ed
eseguiamo una serie di BucketSort
• Procediamo dalla cifra meno significativa a
quella più significativa
Per
b=10
2397
4368
5924
5924
2397
4368
5924
4368
2397
4368
2397
5924
2397
4368
5924
da Demetrescu et al. McGraw Hill 2004
49
Algoritmi e strutture dati
Luigi Laura
Correttezza
• Se x e y hanno una diversa t-esima cifra, la
t-esima passata di BucketSort li ordina
• Se x e y hanno la stessa t-esima cifra, la
proprietà di stabilità del BucketSort li
mantiene ordinati correttamente
Dopo la t-esima passata di BucketSort, i
numeri sono correttamente ordinati rispetto
alle t cifre meno significative
50
da Demetrescu et al. McGraw Hill 2004
Algoritmi e strutture dati
Luigi Laura
Tempo di esecuzione
• O(logb k) passate di bucketsort
• Ciascuna passata richiede tempo O(n + b)
O( (n + b) logb k)
Se b = Θ(n), si ha O(n logn k) = O n
log k
log n
Tempo lineare se k = O(nc), c costante
da Demetrescu et al. McGraw Hill 2004
51
Algoritmi e strutture dati
Luigi Laura
Riepilogo
• Nuove tecniche algoritmiche:
–
–
–
–
Incrementale (SelectionSort, InsertionSort)
Divide et impera (MergeSort, QuickSort)
Plug in di strutture dati efficienti (HeapSort)
Randomizzazione (QuickSort)
• Alberi di decisione per dimostrare lower bound
• Sfruttare proprietà dei dati in ingresso (fuori dal
modello) per progettare algoritmi più efficienti:
algoritmi lineari
52
da Demetrescu et al. McGraw Hill 2004
Algoritmi e strutture dati
Luigi Laura
Esempio di esecuzione
53
da Demetrescu et al. McGraw Hill 2004