25
Gli algoritmi di Ricerca e di Ordinamento Sabrina Mantaci A.A.2007-2008 1 Gli algoritmi di ricerca Il problema della ricerca ` e il seguente: dato un insieme V di oggetti di un certo tipo, e un altro oggetto x dello stesso tipo, stabilire se x V . Ci proponiamo di scrivere un programma che risolve questo problema. Prima di tutto quando abbiamo a che fare con un problema complesso, ci dobbiamo domandare come rappresentare il nostro insieme. Infatti potremmo rappresentarlo mediante un tipo strut- turato set, mediante un array, mediante una lista concatenata, mediante un albero, etc. In realt`aquest’osservazione non` e banale, visto chequesto problema pu`oessere impostato su ciascuna di queste strutture, con performances diverse che vedremo via via. Per il momento vediamo come il problema pu`o essere risolto utilizzando un vettore come struttura dati per rappresentare il nostro insieme. Supponiamo quindi di avere strutturato i nostri dati (per esempio interi) in un vettore V e di voler verificare se un certo intero x ` e contenuto o meno nel vettore. Scriviamo quindi una funzione a valori booleani che presi in input (ossia come parametri) un vettore di interi e un numero intero, restituisce TRUE se l’elemento ` e contenuto nel vettore, e FALSE altrimenti. I parametri saranno ovviamente passati per valore, visto che il problema non richiede di effettuare alcuna modifica n` e nel vettore, n` e nell’elemento da cercare. La funzione sar`a la seguente: Function ricercalineare(V:vettore; x:integer):boolean; var i:integer; trovato:boolean; begin i:=1; trovato:=FALSE; while (i<=n) and (trovato=FALSE) do if V[i]=x then trovato:=TRUE else i:=i+1 ricercalineare:=trovato; end; 1

Gli algoritmi di Ricerca e di Ordinamento - math.unipa.itsabrina/public_Programmazione/Materiale corso... · I numeri interi, i numeri relativi, ... 2.1 Algoritmo di ordinamento per

Embed Size (px)

Citation preview

Page 1: Gli algoritmi di Ricerca e di Ordinamento - math.unipa.itsabrina/public_Programmazione/Materiale corso... · I numeri interi, i numeri relativi, ... 2.1 Algoritmo di ordinamento per

Gli algoritmi di Ricerca e di Ordinamento

Sabrina MantaciA.A.2007-2008

1 Gli algoritmi di ricerca

Il problema della ricerca e il seguente: dato un insieme V di oggetti di un certo tipo,e un altro oggetto x dello stesso tipo, stabilire se x ∈ V .

Ci proponiamo di scrivere un programma che risolve questo problema. Prima di tuttoquando abbiamo a che fare con un problema complesso, ci dobbiamo domandare comerappresentare il nostro insieme. Infatti potremmo rappresentarlo mediante un tipo strut-turato set, mediante un array, mediante una lista concatenata, mediante un albero, etc.In realta quest’osservazione non e banale, visto che questo problema puo essere impostatosu ciascuna di queste strutture, con performances diverse che vedremo via via.

Per il momento vediamo come il problema puo essere risolto utilizzando un vettorecome struttura dati per rappresentare il nostro insieme.

Supponiamo quindi di avere strutturato i nostri dati (per esempio interi) in un vettoreV e di voler verificare se un certo intero x e contenuto o meno nel vettore. Scriviamoquindi una funzione a valori booleani che presi in input (ossia come parametri) un vettoredi interi e un numero intero, restituisce TRUE se l’elemento e contenuto nel vettore, e FALSEaltrimenti. I parametri saranno ovviamente passati per valore, visto che il problema nonrichiede di effettuare alcuna modifica ne nel vettore, ne nell’elemento da cercare. Lafunzione sara la seguente:

Function ricercalineare(V:vettore; x:integer):boolean;

var i:integer;

trovato:boolean;

begin

i:=1;

trovato:=FALSE;

while (i<=n) and (trovato=FALSE) do

if V[i]=x then trovato:=TRUE

else i:=i+1

ricercalineare:=trovato;

end;

1

Page 2: Gli algoritmi di Ricerca e di Ordinamento - math.unipa.itsabrina/public_Programmazione/Materiale corso... · I numeri interi, i numeri relativi, ... 2.1 Algoritmo di ordinamento per

La funzione ricercalineare ha una complessita di tempo che dipende dal numero divolte in cui durante lo svolgimento della funzione vengono effettuate le istruzioni del ciclo.Il caso peggiore puo essere individuato come quello in cui l’elemento x non appartieneall’insieme, perche in questo caso e necessario scandire tutto il vettore. In questo caso sie costretti a compiere n iterazioni, per cui la complessita dell’algoritmo e O(n) nel casopeggiore. Per inciso, e questo il motivo per cui e denominata ricerca lineare.

Tuttavia, se gli elementi del vettore sono ordinati dal piu piccolo al piu grande possiamofare di meglio. In questo caso infatti si puo osservare che e possibile terminare la ricercalineare con risposta FALSE nel momento in cui procedendo da sinistra verso destra troviamoun elemento piu grande di x. Infatti se gli elementi sono ordinati, appena troviamo unelemento del vettore piu grande di x, tutti quelli alla sua destra saranno ancora piu grandi.Questo ci autorizza a dire che x non e contenuto nell’insieme. Il programma diventa ilseguente:

Function ricercalineare(V:vettore; x:integer):boolean;

var i:integer;

trovato:boolean;

begin

i:=1;

trovato:=FALSE;

while (i<=n) and (trovato=FALSE) do

if V[i]=x then trovato:=TRUE

else if V[i]>x then i:=n+1

else i:=i+1

ricercalineare:=trovato;

end;

Tuttavia anche se in media la situazione migliora nei casi in cui x non appartiene alvettore, la complessita di tempo di questa funzione resta O(n) nel caso peggiore. Infattil’elemento x potrebbe trovarsi nell’ultima posizione del vettore, oppure essere maggioredi tutti gli elementi del vettore, e questo comporterebbe comunque una scansione di tuttoil vettore.

Invece, nel caso in cui il vettore e ordinato, possiamo sfruttare quest’ipotesi supple-mentare per operare in maniera diversa e ottenere un grande vantaggio in termini ditempo di calcolo.

Confrontiamo l’elemento x con quello che si trova a meta del vettore. Se in quelpunto c’e l’elemento cercato, la funzione termina e restituisce il valore TRUE. In casocontrario, ci sono due possibili casi: o e maggiore, o e minore dell’elemento a meta delvettore. Se x e minore di questo elemento, allora possiamo essere sicuri che se c’e sitrovera nella prima meta del vettore, poiche gli elementi nella seconda meta sono tuttimaggiori di x. Viceversa, se x e piu grande di quest’elemento, cercheremo x nella secondameta del vettore. Questo comporta che ad ogni iterazione scartiamo meta dei confrontipossibili. Questa intuitivamente e la ragione per cui si ottiene un grande miglioramento

2

Page 3: Gli algoritmi di Ricerca e di Ordinamento - math.unipa.itsabrina/public_Programmazione/Materiale corso... · I numeri interi, i numeri relativi, ... 2.1 Algoritmo di ordinamento per

della complessita. La funzione che implementa quest’algoritmo, che chiameremo ricercabinaria, e la seguente:

Function ricercabinaria(V:vettore; x:integer):boolean;

var i, j, m: integer;

trovato: boolean;

begin

i:=1;

j:=n;

trovato:=FALSE;

while (i<>j) and (trovato=FALSE) do

begin

m:=(i+j) div 2;

if V[m]=x then trovato:=TRUE

else if V[i]>x then j:=m-1

else i:=m+1

end;

ricercabinaria:=trovato;

end;

Con quest’algoritmo, ogni volta che si fa un confronto viene eliminata la meta deglielementi rimanenti. Quindi il numero dei confronti effettuati e uguale al numero di volteche possiamo dividere la dimensione iniziale n per 2 fino ad arrivare ad uno. Questonumero e il logaritmo in base 2 di n. Dunque quest’algoritmo ha una complessita ditempo O(log2 n).

Questo algoritmo e chiaramente molto piu efficiente del precedente, visto che f(n) =log2 n e una funzione che al crescere di n, cresce molto piu lentamente della funzioneg(n) = n. Per avere un’idea di questa differenza, si pensi al tempo che occorre a trovare unnome nell’elenco telefonico (ordinato) utilizzando il metodo di ricerca che istintivamenteutilizziamo, e che e di tipo binario, e a quanto tempo occorrerebbe per trovare un nome sel’elenco telefonico non fosse ordinato. Ovviamente nell’algoritmo ricercabinaria vienepesantemente utilizzata l’ipotesi che il vettore sia ordinato. Non si puo quindi applicarela ricerca binaria in mancanza di quest’ipotesi.

Si noti che questo algoritmo ha per definizione stessa una forma ricorsiva:

Function ricercabinaria(V:vettore; x,primo,ultimo:integer):integer;

var m:integer;

begin

if primo=ultimo then

if V[primo]=x then RICERCABINARIA=TRUE

else RICERCABINARIA=FALSE;

else begin

m:=(primo+ultimo) div 2;

if V[m]=x then trovato:=TRUE

3

Page 4: Gli algoritmi di Ricerca e di Ordinamento - math.unipa.itsabrina/public_Programmazione/Materiale corso... · I numeri interi, i numeri relativi, ... 2.1 Algoritmo di ordinamento per

else if V[m]>x then ricercabinaria:=ricercabinaria(V,x,primo,m-1)

else ricercabinaria:=ricercabinaria(V,x,m+1,ultimo)

end;

end;

Si lascia come esercizio di scrivere un programma ricorsivo che realizzi la ricerca lineare.

4

Page 5: Gli algoritmi di Ricerca e di Ordinamento - math.unipa.itsabrina/public_Programmazione/Materiale corso... · I numeri interi, i numeri relativi, ... 2.1 Algoritmo di ordinamento per

2 Algoritmi di ordinamento

Definizione 2.1 Dato un insieme X, una relazione R sull’insieme X e un insieme dicoppie di elementi di X. Detto in altre parole, R e un sottoinsieme dei prodotto cartesianoX ×X.

Definizione 2.2 Diciamo che una relazione R su un insieme X e una relazione d’or-dine se i suoi elementi godono delle proprieta antisimmetrica e transitiva. Ossia:

• per ogni coppia di elementi x, y ∈ X le condizioni xRy e yRx implicano che x = y(proprieta antisimmetrica);

• xRy e yRz allora xRz (proprieta transitiva).

Una relazione R su un insieme X si dice relazione d’ordine totale se comunque presidue elementi x, y ∈ X, o xRy oppure yRx.

Definizione 2.3 Diciamo che un insieme X e totalmente ordinato se e possibiledefinire una relazione d’ordine totale R fra i suoi elementi.

Esempio:

1. I numeri interi, i numeri relativi, i numeri razionali, i numeri reali, rispetto allarelazione ≤ sono insiemi totalmente ordinati;

2. Le lettere dell’alfabeto, rispetto all’ordine alfabetico.

3. Dato un insieme finito Σ, detto alfabeto, definiamo Σ∗ l’insieme di tutte le sequenzefinite di elementi di Σ, che chiamiamo parole o stringhe. Data una parola u ∈ Σ∗,denotiamo con ui l’i-esimo carattere di u e con |u| la lunghezza di u. Su Σ∗ sipuo definire l’ordine lessicografico. L’ordine lessicografico e definito nel modoseguente: date due parole u, v ∈ Σ∗, diciamo che u ≤lex v se:

• esiste un k tale che ui = vi per ogni i ≤ k |u| = k e |v| > k (ossia u e prefissodi v);

• oppure esiste un k tale che ui = vi per ogni i ≤ k e uk+1 < vk+1 (ossia u e vsono uguali fino al k esimo carattere, ma il (k + 1)-esimo carattere di u e piupiccolo del (k + 1)-esimo carattere di v).

L’ordine lessicografico e una relazione d’ordine totale su Σ∗.

4. La relazione di inclusione fra i sottoinsiemi di un insieme e una relazione d’ordine(verificare), ma non e una relazione d’ordine totale. Infatti possiamo avere duesottoinsiemi di X che non sono in relazione di inclusione uno con l’altro.

5

Page 6: Gli algoritmi di Ricerca e di Ordinamento - math.unipa.itsabrina/public_Programmazione/Materiale corso... · I numeri interi, i numeri relativi, ... 2.1 Algoritmo di ordinamento per

Sia dato un insieme di elementi A = {a1, a2, . . . , an}, presi da un insieme totalmenteordinato. Il problema dell’ordinamento (o, in inglese sorting) consiste nel trovareuna permutazione σ degli indici {1, 2, . . . , n} tale che

aσ(1) ≤ aσ(2) ≤ · · · ≤ aσ(n)

Per risolvere il problema del sorting esistono diversi metodi, ciascuno dei quali ha deipregi e dei difetti. In mancanza di ipotesi supplementari, tutti gli algoritmi di sortingsono basati su confronti degli elementi dell’insieme. Per avere un algoritmo di sortingefficiente, dobbiamo cercare di limitare il numero di confronti. Ma fino a che punto epossibile limitare il numero di questi confronti? Tutti gli algoritmi di sorting basati suconfronti rispettano il seguente teorema fondamentale:

Teorema 2.1 [Lower bound per gli algoritmi di sorting] Nessun algoritmo di sor-ting basato su confronti puo avere complessita di tempo “worst case” inferiore a O(n log2 n).Ossia un qualunque algoritmo di ordinamento basato su confronti deve svolgere necessa-riamente almeno O(n log2 n) confronti, se applicato a un generico vettore.

2.1 Algoritmo di ordinamento per selezione (selection sort)

Il primo algoritmo che esaminiamo e quello piu immediato. Supponiamo che i nostri datisiano organizzati in un array A = [a1, a2, . . . , an]. L’idea del selectionsort e la seguente:

1. si determina l’elemento piu piccolo di tutto il vettore;

2. lo si scambia con l’elemento in prima posizione del vettore

3. si cerca il secondo elemento piu piccolo lo si scambia con l’elemento in secondaposizione del vettore;

4. si procede cosı fino a quando l’intero vettore e ordinato.

Esempio: Supponiamo di avere il seguente array A :

23 14 6 12 34 4 15 20

Al primo passo, l’algoritmo deve cercare l’elemento piu piccolo del vettore e piazzarlo nellaprima posizione. Con una scansione del vettore verifichiamo che il minimo del vettore eil 4 che si trova nella posizione 6. Scambiamo dunque A[1] e A[6].

4 14 6 12 34 23 15 20

Alla seconda iterazione verra cercato il secondo elemento piu piccolo del vettore, che e il6, che si trova nella posizione 3. Alla fine della seconda iterazione A[2] e A[3] vengonoscambiati. Cosı via in tutte le altre iterazioni:

6

Page 7: Gli algoritmi di Ricerca e di Ordinamento - math.unipa.itsabrina/public_Programmazione/Materiale corso... · I numeri interi, i numeri relativi, ... 2.1 Algoritmo di ordinamento per

i=3

4 6 14 12 34 23 15 20

i=4

4 6 12 14 34 23 15 20

i=5

4 6 12 14 34 23 15 20

i=6

4 6 12 14 15 23 34 20

i=7

4 6 12 14 15 20 34 23

Si ottiene quindi:

4 6 12 14 15 20 23 34

La procedura che implementa l’algoritmo di selectionsort sara la seguente:

Procedure selectionsort (var V:vettore);

var i, j:integer;

procedure scambia(var x,y:integer);

var aux:integer;

begin

aux:=x;

x:=y;

y:=aux;

end;

begin

for i:=1 to n do

begin

indmin:=i;

for j:=i+1 to n do

if V[j]<V[indmin] then indmin:=j

scambia (V[i],V[indmin])

end;

end;

7

Page 8: Gli algoritmi di Ricerca e di Ordinamento - math.unipa.itsabrina/public_Programmazione/Materiale corso... · I numeri interi, i numeri relativi, ... 2.1 Algoritmo di ordinamento per

Qual’e la complessita di quest’algoritmo? Dobbiamo contare il numero di confrontieffettuati. Nella prima iterazione vengono svolti n − 1 confronti per trovare il minimo,nella seconda n − 2 confronti per trovare il secondo minimo , ... , nella i-esima n − iconfronti,..., nella (n− 1)-esima 1 confronto. Dunque in totale avremo:

T (n) =n−1∑i=1

i = n(n− 1)/2

Dunque l’algoritmo e O(n2).

Definizione 2.4 Un algoritmo dice adattivo se la complessita di tempo della sua esecu-zione dipende dall’input. Si dice non adattivo nel caso contrario.

Si puo notare che nel selectionsort il numero di confronti effettuati dall’algoritmoe indipendente dal tipo di input. Per esempio se il vettore e ordinato sin dall’inizio,l’algoritmo non si accorge che non deve fare nessuno scambio prima di avere svolto tuttii confronti. Il selectionsort e quindi un algoritmo non adattivo.

Definizione 2.5 Un algoritmo di sorting si dice stabile se gli elementi che hanno lostesso valore appaiono dopo l’applicazione dell’algoritmo nello stesso ordine relativo incui si trovavano nel vettore iniziale.

L’importanza di questa proprieta sta nel fatto che a volte gli ordinamenti vengono fattisecondo una “chiave” di un record (un particolare insieme di dati relativi ad una stessaentita). Supponiamo per esempio di voler ordinare un elenco di persone secondo il lorocognome, e per quelle persone che hanno lo stesso cognome, secondo l’ordine dei loro nomi.Supponiamo di avere gia ordinato i nomi. Se poi ordiniamo secondo i cognomi, vogliamoche venga rispettato, per tutte le persone che hanno uno stesso cognome, l’ordine sui nomiche era stato ottenuto in precedenza. In questo caso occorre che il secondo ordinamentovenga effettuato mediante un ordinamento stabile.

Detto questo, possiamo osservare che l’algoritmo di selectionsort descritto non estabile. Consideriamo ad esempio il seguente vettore che contiene due elementi uguali:

4 4 23 2 34 12 15 20

Per chiarezza indichiamo con 41 il 4 che compare in posizione 1 e con 42 quello checompare in posizione 2.

41 42 23 2 34 12 15 20

Alla prima iterazione l’elemento nella prima posizione verra scambiato col minimo, ossiail valore 2 che si trova alla quarta posizione.

2 42 23 41 34 12 15 20

8

Page 9: Gli algoritmi di Ricerca e di Ordinamento - math.unipa.itsabrina/public_Programmazione/Materiale corso... · I numeri interi, i numeri relativi, ... 2.1 Algoritmo di ordinamento per

All’iterazione successiva, il 4 che si trova nella posizione 2 non verra spostato, poichee il minimo degli elementi rimanenti. Alla terza iterazione il 4 che si trova alla primaposizione verra scambiato con l’elemento in posizione 3.

2 42 41 23 34 12 15 20

Dopo questa iterazione i 4 alla posizione 2 e 3 sono nella loro posizione definitiva, ma comesi evince dagli indici, si trovano in ordine inverso rispetto all’ordine in cui si trovavanoall’inizio. Dunque l’algoritmo non e stabile.

2.2 Bubblesort

L’algoritmo di sorting che andiamo a descrivere e basato sulla seguente idea. Si scan-disce il vettore da sinistra a destra, confrontando ogni elemento con quello adiacente, escambiandoli se il primo e maggiore del secondo.

Ci si rende conto subito che una sola scansione del vettore non basta. Per esempioconsideriamo il seguente vettore:

23 14 6 12 34 4 15 20

consideriano la prima scansione del vettore: il primo confronto viene fatto tra il 23 e il14. Il 23 e maggiore del 14, dunque i due elementi vengono scambiati

14 23 6 12 34 4 15 20

il 23 viene confrontato col 6. Essendo piu grande, viene scambiato.

14 6 23 12 34 4 15 20

quindi confrontiamo il 23 col 12 e li scambiamo

23 6 12 23 34 4 15 20

il 23 e confrontato col 34, e questa volta non viene effettuato nessuno scambio.

23 6 12 23 34 4 15 20

Si passa quindi all’elemento successivo, il 34, che viene confrontato col 4, e vengonoscambiati.

23 6 12 23 4 34 15 20

quindi si scambia il 34 col 15

23 6 12 23 4 15 34 20

9

Page 10: Gli algoritmi di Ricerca e di Ordinamento - math.unipa.itsabrina/public_Programmazione/Materiale corso... · I numeri interi, i numeri relativi, ... 2.1 Algoritmo di ordinamento per

Quindi il 34 viene scambiato col 20. Il vettore alla fine della prima scansione sara ilseguente:

23 6 12 23 4 15 20 34

E evidente che il vettore non e ancora ordinato, ma possiamo osservare che, comunque siafatto il vettore, l’elemento piu grande trova la sua posizione definitiva, ossia l’ultima po-sizione. E per questo che l’algoritmo si chiama Bubblesort, o ordinamento a bolle, poichel’elemento piu grande “affiora” in superficie come le bolle nell’acqua. Ma allora possiamoprevedere che alla prossima iterazione il secondo elemento piu grande si trovera alla pe-nultima posizione. In generale, alla i-esima iterazione l’i-esimo elemento piu grande sarapiazzato alla posizione n− i+1. Questo ci dice che dopo al piu n− 1 iterazioni, il vettoresara completamente ordinato. In prima approssimazione la procedura che implementa ilbubblesort e la seguente:

procedure bubblesort (var V:vettore);

var i,j:integer;

procedure scambia(var x,y:integer);

var aux:integer;

begin

aux:=x;

x:=y;

y:=aux;

end;

begin

for i:= 1 to n do

for j:= 1 to n-1 do

if V[j]>V[j+1] then

scambia (V[j],V[j+1]);

end;

In realta alcune iterazioni potrebbero essere superflue. Infatti se a una certa iterazioneil vettore fosse gia ordinato, basterebbe una sola ulteriore iterazione per accorgersi che none piu necessario nessuno scambio, e quindi il vettore e ordinato e l’algoritmo puo terminare.Questo puo essere controllato trasformando il ciclo esterno in un ciclo repeat-until, uti-lizzando una variabile booleana che verifica se nella iterazione precedente e stato effettuatouno scambio.

procedure bubblesort (var V:vettore);

var i,j:integer;

scambio:boolean;

10

Page 11: Gli algoritmi di Ricerca e di Ordinamento - math.unipa.itsabrina/public_Programmazione/Materiale corso... · I numeri interi, i numeri relativi, ... 2.1 Algoritmo di ordinamento per

procedure scambia(var x,y:integer);

var aux:integer;

begin

aux:=x;

x:=y;

y:=aux;

end;

begin

repeat

scambio:=FALSE

for j:= 1 to n-1 do

if V[j]>V[j+1] then begin

scambia (V[j],V[j+1]);

scambio:=TRUE;

end;

until scambio=FALSE

end;

Nel caso peggiore vengono fatte comunque n iterazioni esterne. Possiamo anche osser-vare che, visto che all’i-esima iterazione gli ultimi i elementi del vettore sono nella loroposizione definitiva, possiamo interrompere il ciclo interno dopo n− i iterazioni. Questosi puo realizzare riducendo di un unita la variabile n alla fine del ciclo interno

procedure bubblesort (var V:vettore);

var i,j:integer;

scambio:boolean

procedure scambia(var x,y:integer);

var aux:integer;

begin

aux:=x;

x:=y;

y:=aux;

end;

begin

repeat

scambio:=FALSE

for j:= 1 to n-1 do

if V[j]>V[j+1] then begin

scambia (V[j],V[j+1]);

scambio:=TRUE;

11

Page 12: Gli algoritmi di Ricerca e di Ordinamento - math.unipa.itsabrina/public_Programmazione/Materiale corso... · I numeri interi, i numeri relativi, ... 2.1 Algoritmo di ordinamento per

end;

n:=n-1;

until scambio=FALSE

end;

Ma si puo fare ancora di meglio. Infatti se in una iterazione interna da un certo puntoin poi non vengono effettuati scambi, significa che tali valori si trovano nella loro posizionedefinitiva. Questo puo essere controllato tenendo traccia della posizione in cui e effettuatol’ultimo scambio, e far sı che il successivo ciclo for termini in questa posizione.

procedure bubblesort (var V:vettore);

var i,j,p:integer;

scambio:boolean

procedure scambia(var x,y:integer);

var aux:integer;

begin

aux:=x;

x:=y;

y:=aux;

end;

begin

p:=n;

repeat

scambio:=FALSE

for j:= 1 to n-1 do

if V[j]>V[j+1] then begin

scambia (V[j],V[j+1]);

scambio:=TRUE;

p:=j+1

end;

n:=p;

until scambio=FALSE

end;

Si puo notare che, malgrado tutte le ottimizzazioni effettuate migliorino in mediale prestazioni dell’algoritmo, nel caso peggiore (che e per quest’algoritmo quello in cui ilvettore da ordinare e ordinato in senso inverso), si devono effettuare nella prima iterazionen−1 confronti e scambi, nella seconda n−2, e cosı via. In totale verranno svolte n∗(n−1)/2operazioni di confronto e/o scambio. Anche questo algoritmo e quindi un algoritmo ditempo quadratico O(n2) nel caso peggiore.

Tuttavia, per quanto osservato prima, questo algoritmo si arresta non appena il vettorediventa ordinato. In casi particolarmente fortunati il numero di confronti puo essere vicino

12

Page 13: Gli algoritmi di Ricerca e di Ordinamento - math.unipa.itsabrina/public_Programmazione/Materiale corso... · I numeri interi, i numeri relativi, ... 2.1 Algoritmo di ordinamento per

ad n. Questo algoritmo e quindi un algoritmo adattivo. Inoltre l’algoritmo e stabile inquanto elementi con la stessa chiave non vengono mai invertiti. Infine anche questoalgoritmo lavora in loco, ossia non utilizza nessun vettore ausiliario, dunque nessunospazio di memoria supplementare.

2.3 Mergesort

Un altro metodo per il sorting utilizza la tecnica algoritmica del divide et impera (dividie governa o, in inglese, divide and conquer). Secondo questa tecnica l’input viene divisoin due o piu parti piu piccole e l’algoritmo viene applicato ricorsivamente a ciascuna delleparti in cui e diviso l’input.

In particolare questo metodo di sorting, chiamato mergesort, consiste nel dividere ilvettore in due parti e operare ricorsivamente un ordinamento su ciascuna delle due parti.Nella fase di ricostruzione occorre fondere (merge) due vettori ordinati in un unico vettoreordinato. Vediamo cosa succede su un esempio:

Esempio: Supponiamo di volere ordinare il seguente array:

23 14 6 12 34 4 15 20

Il vettore viene suddiviso in due vettori di taglia meta:

23 14 6 12 34 4 15 20

A sua volta, ciascuno di essi viene diviso a meta

23 14 6 12 34 4 15 20

e ancora una volta a meta

23 14 6 12 34 4 15 20

A un certo punto si arriva ad avere tanti array di taglia 1. Tali array sono ovviamenteordinati. Il nostro scopo e quello di costruire un vettore ordinato di taglia 2k a partire dadue vettori ordinati di taglia k. Al primo passo e molto semplice. Confrontiamo i primidue vettori, nel nostro esempio quello costituito dal solo elemento 23 e quello costituito dalsolo elemento 14. Se vogliamo costruire un vettore di taglia 2 con tali elementi ordinati,basta un singolo confronto per stabilire che 14 < 23, e quindi collocare il 14 prima di23. Lo stesso si fa per le coppie (6, 12), (34, 4), (15, 20). Si ottengono dunque i seguentivettori:

14 23 6 12 4 34 15 20

13

Page 14: Gli algoritmi di Ricerca e di Ordinamento - math.unipa.itsabrina/public_Programmazione/Materiale corso... · I numeri interi, i numeri relativi, ... 2.1 Algoritmo di ordinamento per

A questo punto vogliamo unificare in un unico vettore ordinato i primi due vettori (or-dinati). Dobbiamo quindi trovare il minimo valore contenuto nei due vettori per trovarequale deve essere inserito come primo elemento nel nuovo vettore. Visto che i due vettoridi partenza sono ordinati, l’elemento piu piccolo sara sicuramente o il primo del primovettore o il primo del secondo vettore. Con un solo confronto riusciamo a stabilire quant’eil minimo. Nella fattispecie e il 6, e lo mettiamo in prima posizione. A questo punto ilsecondo elemento piu piccolo sara o il primo del primo vettore o il secondo del secondovettore. In questo caso e il 12, e lo inseriamo in seconda posizione. Essendo che il secondovettore e esaurito, gli elementi rimanenti del primo vettore vanno ordinatamente inseri-ti nel nuovo vettore. Lo stesso procedimento puo essere adottato per le coppie (4, 34),(15, 20). Otteniamo la seguente configurazione:

6 12 23 14 4 15 20 34

A questo punto restano da fondere gli ultimi due vettori utilizzando la stessa tecnica vistaprima. Si ottiene quindi:

6 4 12 15 20 23 34

La procedura mergesort fara quindi uso di una procedura ausiliaria (che chiameremomerge) che, presi in input due vettori ordinati di taglia k, genera un vettore di taglia2k. La procedura in realta lavora su una porzione di vettore, e utilizza una variabilelocale B di tipo vettore, che ci servira come vettore ausiliario. Vengono passati comeparametri il vettore V, e gli interi l,m,r, che rappresentano le due porzioni di vettoreadiacenti che stiamo analizzando ossia l’intervallo [l,m] e l’intervallo [m+1,r]. Si supponeche gli elementi dell’intervallo [l,m] e quelli dell’intervallo [m+1,r] del vettore sianoordinati. Alla fine della procedure vogliamo che gli elementi dell’intervallo [l,r] sianotutti ordinati. La seguente procedura implementa questo algoritmo:

· · · · · ·l m r

procedure merge (var V:vettore, l,m,r:integer);

var i,j,k:integer;

begin

i:=l;

k:=l;

j:=m+1;

While (i<=m) and (j<=r) do

begin

if V[i]<=V[j] then

begin

B[k]:=V[i];

14

Page 15: Gli algoritmi di Ricerca e di Ordinamento - math.unipa.itsabrina/public_Programmazione/Materiale corso... · I numeri interi, i numeri relativi, ... 2.1 Algoritmo di ordinamento per

i:=i+1;

k:=k+1;

end

else

begin

B[k]:=V[j];

j:=j+1;

k:=k+1;

end;

end;

while i<=m do

begin

B[k]:=V[i];

i:=i+1;

k:=k+1;

end;

while j<=r do

begin

B[k]:=V[j];

j:=j+1;

k:=k+1;

end;

for k:=l to r do V[k]:=B[k]

end;

La procedura mergesort fara uso di questa procedura. L’idea e quella accennata nel-l’esempio, ossia considerato un vettore, si divide a meta e si applica ricorsivamente laprocedura mergesort a ciascuna delle due meta. Una volta che i due sottoarray sonoordinati, si fondono mediante la procedura merge:

procedure mergesort (var V:vettore, l,r:integer);

var m:integer;

begin

m:=(l+r) div 2;

mergesort(V,l,m);

mergesort(V,m+1,r);

merge(V,l,m,r)

end;

Andiamo ora a calcolare la complessita. Prima di tutto consideriamo la complessita dellaprocedura merge. Per ogni elemento che viene inserito nel vettore B si applica tempocostante. Infatti si svolge al piu un confronto e l’elemento piu piccolo viene copiato nelvettore B. In totale dunque la sua complessita e dell’ordine della taglia della porzione divettore che si sta ordinando.

15

Page 16: Gli algoritmi di Ricerca e di Ordinamento - math.unipa.itsabrina/public_Programmazione/Materiale corso... · I numeri interi, i numeri relativi, ... 2.1 Algoritmo di ordinamento per

Andiamo alla procedura mergesort. Ad ogni passo vengono applicate due chiamatericorsive del mergesort, a due vettori della taglia meta del vettore iniziale, piu unachiamata alla procedura merge. Un modo per calcolare la complessita e calcolare lafunzione ricorsiva T (n) che calcola la complessita di mergesort su un vettore di taglia n.

T (n) = 2T (n/2) + n = 2(2T (n/4) + n/2) + n =

= 4T (n/4) + n + n = 4(2T (n/8) + 1/4) + n + n =

= 8T (n/8) + n + n + n = · · · = n + n + · · ·+ n︸ ︷︷ ︸log n volte

= n log n

Dunque la complessita dell’algoritmo e O(n log n).Un altro modo piu intuitivo per calcolare questa complessita e il seguente: un vettore

puo essere diviso a meta un numero di volte uguale al logaritmo della sua taglia. La fase“divide” dell’algoritmo costa tempo costante ad ogni chiamata ricorsiva. La ricostruzionedi un vettore di taglia 2k a partire da due vettori di taglia k costa O(k). Possiamo peroosservare che ad ogni “livello” di divisione abbiamo un numero di array da fondere taleche la somma di tutte le taglie dei sottovettori e uguale ad n. Dunque la “composizione”costa O(n) ad ogni livello. Essendoci log n livelli, la complessita totale dell’algoritmo eO(n log n).

Questo algoritmo utilizza della memoria ausiliaria (il vettore B), dunque non lavora inloco.

Inoltre possiamo osservare che questo algoritmo svolge le stesse operazioni per qua-lunque vettore di input. Questo significa che l’algoritmo e non adattivo.

Inoltre questo algoritmo non scambia mai l’ordine di due elementi con chiavi uguali.Segue che il mergesort e un algoritmo stabile.

2.4 Quicksort

Un altro algoritmo di sorting e il quicksort o ordinamento rapido. Questo algoritmosi chiama cosı perche e quello che in media ha le performances migliori rispetto ad altrialgoritmi, anche se non ha la migliore complessita nel caso pessimo. E quello che si chiamaun algoritmo randomizzato, in quanto la sua esecuzione dipende da un valore che vieneestratto in maniera piu o meno casuale. Illustreremo qui un modo di estrarre questonumero, in dipendenza di alcuni valori del vettore, ma non e questo l’unico modo.

Il quicksort funziona come segue. Supponiamo di voler ordinare un insieme di interi.

• Si estrae a sorte un numero intero, che possibilmente appartenga al range deglielementi del vettore. Per fare questo potremmo scegliere tale elemento, detto pivot,come la media di due elementi del vettore, per esempio il primo e l’ultimo.

• si riarrangiano gli elementi del vettore in maniera tale che nella parte iniziale delvettore ci siano tutti gli elementi piu piccoli del pivot e nella parte finale tuttigli elementi piu grandi del pivot. Alla fine di questa fase il vettore risulta diviso

16

Page 17: Gli algoritmi di Ricerca e di Ordinamento - math.unipa.itsabrina/public_Programmazione/Materiale corso... · I numeri interi, i numeri relativi, ... 2.1 Algoritmo di ordinamento per

idealmente in due parti, non necessariamente uguali, quella con tutti gli elementipiu piccoli del pivot e quella con tutti gli elementi piu grandi del pivot.

• Quindi si applica il quicksort ricorsivamente a ciascuna delle due parti del vetto-re. Le chiamate ricorsive terminano quando la porzione di vettore analizzato e didimensione 1.

Supponiamo di avere il seguente vettore:

23 14 6 16 34 4 12 7

Consideriamo i due estremi del vettore e calcoliamone la media. Nel nostro caso talemedia e 15. Chiamiamo tale media pivot. L’idea e di mettere nella parte iniziale delvettore tutti gli elementi piu piccoli del pivot e nella parte finale gli elementi piu grandidel pivot. Per fare questo procediamo come segue: scandiamo il vettore da sinistra adestra, andando a cercare il primo elemento che risulta piu grande del pivot. Questoelemento e probabilmente nella posizione sbagliata. Teniamo in memoria la posizione diquesto elemento e cominciamo a scandire il vettore da destra a sinistra, andando a cercareil primo elemento piu piccolo del pivot. Tale elemento viene scambiato con quello trovatoprima, e si prosegue in questo modo fino a quando ogni elemento non sia stato esaminatoed eventualmente trasportato nella meta di pertinenza.

23 14 6 16 34 4 12 7

In particolare nel nostro vettore 23 risulta subito piu grande del pivot e 7 minore delpivot. Quindi i due elementi vengono scambiati.

7 14 6 16 34 4 12 23

si passa ad esaminare il secondo elemento, il 14. Essendo minore di 15 non verra spostatoe si passa all’elemento successivo. Anche 6 < 15 e si passa al successivo. Si trova 16 > 15,quindi ci si ferma e si comincia ad esaminare gli elementi da destra a sinistra. Si trovasubito il 12 < 15 che verra quindi scambiato col 16. Otteniamo quindi:

7 14 6 12 34 4 16 23

Andando avanti da sinistra a destra si trova il 34 > 15. Si riparte quindi da destra e sitrova il 4 < 15. I due elementi vengono scambiati.

7 14 6 12 4 34 16 23

Quindi gli indici che scandiscono i due vettori si incontrano. A questo punto tuttigli elementi piu piccoli del pivot si trovano prima della posizione 5, mentre tutti quel-li piu grandi si trovano dalla posizione 6 in poi. L’algoritmo viene quindi richiamatoricorsivamente su ciascuna delle due parti.

17

Page 18: Gli algoritmi di Ricerca e di Ordinamento - math.unipa.itsabrina/public_Programmazione/Materiale corso... · I numeri interi, i numeri relativi, ... 2.1 Algoritmo di ordinamento per

Si noti che gli elementi che alla fine di una di queste fasi sono collocate in una meta,non dovranno piu superare il confine ideale fra le due parti. Quindi un ordinamentoindipendente di ciascuna delle due parti portera ad un ordinamento dell’intero vettore.

Il codice in Pascal che implementa questo algoritmo e il seguente.

procedure quicksort (var V:vettore, left,right:integer);

var i,j, pivot:integer;

procedure scambia(var x,y:integer);

var aux:integer;

begin

aux:=x;

x:=y;

y:=aux;

end;

begin {quicksort}i:=left;

j:=right;

pivot:=(V[left]+V[right]) div 2;

repeat

While V[i]<pivot do i:=i+1;

While V[j]>pivot do j:=j-1;

scambia(V[i], V[j])

i:=i+1;

j:=j-1;

until i>j;

if right<j then quicksort(V,right,j);

if i>left then quicksort(V,i,left)

end;

Una chiamata della funzione fara un numero di confronti (di ogni elemento col pivot)proporzionale alla taglia della parte di vettore che si sta esaminando. In piu ci sonodue chiamate ricorsive sulle due parti del vettore. Possiamo notare che se il vettorevenisse diviso esattamente a meta la funzione di ricorsione che ne deriverebbe sarebbela stessa del mergesort. In questo caso particolarmente fortunato avremmo quindi chela complessita dell’algoritmo sarebbe O(n log n). Tuttavia il modo in cui il vettore vienesuddiviso dipende molto “dalla sorte” nel senso che dipende dalla scelta del pivot. Incasi particolarmente sfortunati, il pivot potrebbe essere tale da creare una partizionesbilanciata del vettore, ossia alla prima chiamata di quicksort il vettore verrebbe divisoin una parte di n− 1 elementi e un parte di un solo elemento. Quindi una sola delle duechiamate ricorsive si attiva, ma su un vettore di taglia n−1. La seconda chiamata ricorsival’algoritmo fara quindi n − 1 confronti. Se siamo ancora particolarmente “sfortunati” ilnuovo pivot sbilancia ancora la partizione. Otteniamo dunque un’unica chiamata ricorsiva

18

Page 19: Gli algoritmi di Ricerca e di Ordinamento - math.unipa.itsabrina/public_Programmazione/Materiale corso... · I numeri interi, i numeri relativi, ... 2.1 Algoritmo di ordinamento per

su un vettore di taglia n− 2. In maniera piu formale possiamo dire che se ogni estrazionedel pivot ci genera una partizione sbilanciata, la funzione di ricorsione sara:

T (n) = n+T (n− 1) = n+(n− 1)+T (n− 2) = · · · = n+(n− 1)+ (n− 2)+ · · ·+2+1 =

= n(n + 1)/2

ossia O(n2).Dunque abbiamo dimostrato il seguente Teorema

Teorema 2.2 Il quicksort ha una complessita nel caso pessimo di O(n2).

Ci possiamo chiedere comunque come questo algoritmo lavora in media. Si puo dimo-strare che nel caso medio questo algoritmo si comporta in maniera piu probabile come nelcaso migliore. Cioe:

Teorema 2.3 La complessita del quicksort nel caso medio e O(n log n).

In realta le costanti celate dietro l’ordine di grandezza sono molto piccole. Questo eil motivo per cui il quicksort ha in genere delle performances addirittura migliori delmergesort, che ha una complessita “worst case” migliore.

Notiamo infine che il quicksort e un algoritmo non adattivo in quando la sua esecu-zione non dipende da come e fatto l’input (puo dipendere eventualmente dalla scelta delpivot). Inoltre non e stabile poiche per esempio

7 161 6 12 162 4 18 23

il primo 16 viene scambiato col 4

7 4 6 12 162 161 18 23

e alla fine della prima ricorsione il vettore risulta

7 4 6 12 162 161 18 23

Si puo notare che 161 e 162 non si scambieranno piu di posto prima della fine dell’algoritmo.

2.5 Countingsort

L’algoritmo che ora andiamo a descrivere puo essere applicato quando gli elementi chedobbiamo ordinare appartengono ad un insieme finito. Per esempio possiamo supporreche gli elementi da ordinare siano interi compresi in un intervallo finito, oppure le letteredell’alfabeto. Invece l’algoritmo non puo essere applicato ad un insieme di numeri realicontenuti in un intervallo, perche in un intervallo sono contenuti infiniti numeri reali.

L’algoritmo di countingsort funziona come segue. Supponiamo di volere ordinare unvettore V, i cui elementi sono tratti da un insieme finito.

19

Page 20: Gli algoritmi di Ricerca e di Ordinamento - math.unipa.itsabrina/public_Programmazione/Materiale corso... · I numeri interi, i numeri relativi, ... 2.1 Algoritmo di ordinamento per

• si definisce un vettore count con taglia uguale alla dimensione dell’insieme da cuigli elementi sono tratti. Si inizializzano tutte le caselle del vettore a 0. L’elementoi-esimo di tale vettore servira a contare quante volte l’elemento di valore i e presentenel vettore.

• si scorre il vettore V con un ciclo, e per ogni i si incrementa di 1 la casella V[i]

(perche e stato visto un nuovo elemento con valore V[i]).

• si considera il vettore count e a partire dal secondo elemento collezioniamo in ogniposizione k tutte le somme parziali dei primi k elementi di count. In questo modoalla fine count[k] indichera la posizione in cui dovremo inserire l’ultimo elementocon valore k nel vettore ordinato.

• percorrendo il a ritroso vettore V dall’ultima posizione alla prima per ogni indice iinseriamo questo elemento in un vettore ausiliario W nella posizione count[V[i]].Quindi si decrementa count[V[i]] per determinare dove andra messo il prossimoelemento di valore V[i].

Vediamo come funziona su un esempio. Supponiamo di voler ordinare un vettore di 16interi nell’intervallo [1, 5].

V= 3 1 3 5 1 3 2 4 1 2 5 3 4 1 3 4

Si considera un vettore count di dimensione 5 e si inizializza a 0

count= 0 0 0 0 0

Si inizia a scandire il vettore V. Il primo elemento e un 3, dunque si incrementa ilcontatore count[3]

count= 0 0 1 0 0

al secondo passo si incrementera count[1].

count= 1 0 1 0 0

quindi di nuovo count[3]

count= 1 0 2 0 0

e cosı via. Alla fine della iterazione il vettore count sara il seguente:

count= 4 2 5 3 2

Costruiamo il vettore delle somme incrementali

count= 4 6 11 14 16

20

Page 21: Gli algoritmi di Ricerca e di Ordinamento - math.unipa.itsabrina/public_Programmazione/Materiale corso... · I numeri interi, i numeri relativi, ... 2.1 Algoritmo di ordinamento per

A questo punto consideriamo un vettore W della stessa dimensione di V e cominciamo ascandire V da destra a sinistra .

V= 3 1 3 5 1 3 2 4 1 2 5 3 4 1 3 4

W=

count= 4 6 11 14 16

Al primo passo si legge V[16]=4. Allora questo 4 viene inserito nella posizione count[4]

(14) e si decrementa count[4].

V= 3 1 3 5 1 3 2 4 1 2 5 3 4 1 3 4

W= 4

count= 4 6 11 13 16

Questo procedimento garantisce che l’ultima occorrenza del 4 sia messo nell’ultimaposizione in cui deve figurare un 4 nel vettore risultante. Applicato ad ogni elemento,questo fara si che il counting sort risulti stabile.

Al secondo passo si trova un 3, che si inserisce nella posizione count[3] (11), e sidecrementa di uno count[3], che diventa 10.

V= 3 1 3 5 1 3 2 4 1 2 5 3 4 1 3 4

W= 3 4

count= 4 6 10 13 16

Terzo passo

V= 3 1 3 5 1 3 2 4 1 2 5 3 4 1 3 4

W= 1 3 4

count= 3 6 10 13 16

Quarto passo

V= 3 1 3 5 1 3 2 4 1 2 5 3 4 1 3 4

W= 1 3 4 4

count= 3 6 10 12 16

21

Page 22: Gli algoritmi di Ricerca e di Ordinamento - math.unipa.itsabrina/public_Programmazione/Materiale corso... · I numeri interi, i numeri relativi, ... 2.1 Algoritmo di ordinamento per

Quinto passo

V= 3 1 3 5 1 3 2 4 1 2 5 3 4 1 3 4

W= 1 3 3 4 4

count= 3 6 9 12 16

Sesto passo

V= 3 1 3 5 1 3 2 4 1 2 5 3 4 1 3 4

W= 1 3 3 4 4 5

count= 3 6 9 12 15

Settimo passo

V= 3 1 3 5 1 3 2 4 1 2 5 3 4 1 3 4

W= 1 2 3 3 4 4 5

count= 3 5 9 12 15

Ottavo passo

V= 3 1 3 5 1 3 2 4 1 2 5 3 4 1 3 4

W= 1 1 2 3 3 4 4 5

count= 2 5 9 12 15

Nono passo

V= 3 1 3 5 1 3 2 4 1 2 5 3 4 1 3 4

W= 1 1 2 3 3 4 4 4 5

count= 2 5 9 11 15

Decimo passo

V= 3 1 3 5 1 3 2 4 1 2 5 3 4 1 3 4

W= 1 1 2 2 3 3 4 4 4 5

CONT= 2 4 9 11 15

22

Page 23: Gli algoritmi di Ricerca e di Ordinamento - math.unipa.itsabrina/public_Programmazione/Materiale corso... · I numeri interi, i numeri relativi, ... 2.1 Algoritmo di ordinamento per

Undicesimo passo

V= 3 1 3 5 1 3 2 4 1 2 5 3 4 1 3 4

W= 1 1 2 2 3 3 3 4 4 4 5

CONT= 2 4 8 11 15

Dodicesimo passo

V= 3 1 3 5 1 3 2 4 1 2 5 3 4 1 3 4

W= 1 1 1 2 2 3 3 3 4 4 4 5

CONT= 1 3 8 11 15

Tredicesimo passo

V= 3 1 3 5 1 3 2 4 1 2 5 3 4 1 3 4

W= 1 1 1 2 2 3 3 3 4 4 4 5 5

CONT= 1 3 8 11 14

Quattordicesimo passo

V= 3 1 3 5 1 3 2 4 1 2 5 3 4 1 3 4

W= 1 1 1 2 2 3 3 3 3 4 4 4 5 5

CONT= 1 3 7 11 14

Quindicesimo passo

V= 3 1 3 5 1 3 2 4 1 2 5 3 4 1 3 4

W= 1 1 1 1 2 2 3 3 3 3 4 4 4 5 5

CONT= 0 3 7 11 14

Sedicesimo passo

V= 3 1 3 5 1 3 2 4 1 2 5 3 4 1 3 4

W= 1 1 1 1 2 2 3 3 3 3 3 4 4 4 5 5

CONT= 0 3 6 11 14

23

Page 24: Gli algoritmi di Ricerca e di Ordinamento - math.unipa.itsabrina/public_Programmazione/Materiale corso... · I numeri interi, i numeri relativi, ... 2.1 Algoritmo di ordinamento per

Il codice che implementa questo algoritmo e il seguente:

procedure countingsort (var V:vettore);

var i,k:integer;

count:array [1..k] of integer;

W:vettore

begin

for j:=1 to k do {inizializzazione di count}count[j]:=0;

for i:=1 to n do {creazione del vettore contatore}count[V[i]]:=count[V[i]]+1;

for j:=2 to k do {creazione del vettore delle somme incrementali}count[i]:=count[i]+count[i-1];

for i:=n downto 1 do begin {Costruzione del vettore ordinato}W[count[V[i]]]:=V[i];

count[V[i]]:=count[V[i]]-1;

end;

for i:=i to n do V[i]:=W[i]; {copia del vettore W in V}end;

Questo algoritmo contiene un ciclo di lunghezza k per l’inizializzazione di count, unciclo di lunghezza n per la creazione del vettore count, un ciclo di lunghezza k per lacreazione del vettore delle somme incrementali, un ciclo di lunghezza n per la creazionedel vettore ordinato e un ciclo di lunghezza n per copiare il vettore ordinato in V. Essendotutti cicli disgiunti, la complessita dell’algoritmo e uguale al massimo tra O(k) e O(n). Ingenere si suppone che n sia molto maggiore di k, quindi il counting sort ha complessitaO(n).

Si noti che questo risultato non contraddice il teorema del lower bound per gli algoritmidi sorting. Infatti il counting sort non e un algoritmo di sorting basato su confronti, equesto e possibile perche sfrutta pesantemente l’ipotesi che l’insieme da cui sono trattigli elementi e un insieme finito. Infatti se cosı non fosse, non saremmo in grado didimensionare il vettore count.

L’algoritmo sfrutta un vettore ausiliario (il vettore W), quindi non lavora in loco. Inoltreil funzionamento dell’algoritmo non dipende dal vettore iniziale. Quindi e non adattivo.Infine, per come e stato implementato, l’algoritmo e stabile.

Nella seguente tabella schematizziamo tutte le caratteristiche fondamentali degli al-goritmi di sorting illustrati.

24

Page 25: Gli algoritmi di Ricerca e di Ordinamento - math.unipa.itsabrina/public_Programmazione/Materiale corso... · I numeri interi, i numeri relativi, ... 2.1 Algoritmo di ordinamento per

Caso pessimo Caso medio Caso migliore In Loco Adattivo StabileSelectionsort O(n2) O(n2) O(n2) SI NO NOBubblesort O(n2) ? O(n) SI SI SIMergesort O(n log n) O(n log n) O(n log n) NO NO NOQuicksort O(n2) O(n log n) O(n log n) SI NO NO

Countingsort O(n) O(n) O(n) NO NO SI

25