Algoritmi di Ordinamento
di Caterina Vetti
Definizione
• Un algoritmo è un procedimento che risolve
un determinato problema attraverso un
numero finito di passi. Un problema risolvibile
mediante un algoritmo si dice computabile.
Tipi di algoritmi (di ordinamento)
•
•
•
•
•
•
•
•
Selection Sort;
Insertion Sort;
Bubble Sort;
Quick Sort;
Merge Sort;
Heap Sort;
Counting Sort;
Bucket Sort.
Selection Sort:
E’ un algoritmo di ordinamento che opera in place ed in modo
simile all'ordinamento per inserzione. L'algoritmo è di tipo non
adattivo, ossia il suo tempo di esecuzione non dipende
dall'input ma dalla dimensione dell'array.
Alla prima iterazione verrà selezionato l’elemento più piccolo
dell’intero insieme e sarà scambiato con quello che occupa la
prima posizione.
Alla seconda iterazione è selezionato il secondo elemento più
piccolo
dell’insieme è viene scambiato con l’elemento che occupa la
seconda posizione.
Si ripete fino ad aver collocato nella posizione corretta tutti gli
n elementi.
Selection Sort
• Esempio:
void selsort(int x[ ], int y) {
int z=0;
for (z=0;z<n;z++) {
int y=0;
for (y=z+1;y<n;y++) {
if (x[y] < x[y]) {
int t=x[y];
x[y]=x[z];
x[z]=t;
}
}
}
Inserction Sort
E’ un algoritmo relativamente semplice per ordinare un array. Non
è molto diverso dal modo in cui un essere umano, spesso, ordina un
mazzo di carte. Esso è un algoritmo in place, cioè ordina l'array
senza doverne creare una copia, risparmiando memoria. Pur
essendo molto meno efficiente di algoritmi più avanzati, può avere
alcuni vantaggi: ad esempio, è semplice da implementare ed è
efficiente per insiemi di partenza che sono quasi ordinati.
Ad ogni iterazione, il vettore è costituito da una parte iniziale
ordinata e da la parte rimanente che
contiene i valori da ordinare. Per ogni valore ancora da inserire,
viene fatta una ricerca binaria nella parte ordinata del vettore e
vengono spostati in avanti tutti gli elementi per liberare una
posizione
Nella posizione liberata viene inserito il valore.
Inserction Sort
• Esempio:
void inssort(int a[ ] ,int n) {
int i=0,j=0;
for (i=1;i<n;i++) {
int x=a[i], s=1, d=i-1;
while (s<=d) {
int m=(s+d)/2;
if (x<a[m]) d=m-1;
else s=m+1;
}
for (j=i-1,j>=s;j--) a[j+1]=a[j];
a[s]=x;
}
}
Bubble Sort
E’ un semplice algoritmo di ordinamento dei dati. Il suo
funzionamento è semplice: ogni coppia di elementi
adiacenti della lista viene comparata e se essi sono
nell'ordine sbagliato vengono invertiti. L'algoritmo scorre
poi tutta la lista finché non vengono più eseguiti scambi,
situazione che indica che la lista è ordinata.
L’algoritmo si basa sull’idea di far emergere pian piano gli
elementi più piccoli verso l’inizio dell’insieme da ordinare
facendo sprofondare gli elementi maggiori verso il fondo:
un po’ come le bollicine in un bicchiere di acqua gassata
da qui il nome di ordinamento a bolle.
Bubble Sort
• Esempio:
void bubbsort(int x[ ], int y) {
bool scambio=true;
int ultimo=y-1,i=0;
while (scambio) {
scambio=false;
for (i=0;i<ultimo;i++) {
if ( x[i]> x[i+1]) {
int t= x[i];
x[i]=x[i+1];
x[i+1]=t;
scambio=true;
}
}
ultimo --;
}
}
Quick Sort
E’ un algoritmo di ordinamento ricorsivo in place che, come
merge sort, si basa sul paradigma divide et impera. La base
del suo funzionamento è l'utilizzo ricorsivo della procedura
partition: preso un elemento da una struttura dati (es.
array) si pongono gli elementi minori a sinistra rispetto a
questo e gli elementi maggiori a destra.
Assunto un elemento come perno, si confrontano con esso
gli altri elementi e si posizionano alla sua sinistra i minori e
a destra i maggiori, senza tener conto del loro ordine. Dopo
questo stadio si ha che il perno è nella sua posizione
definitiva. Successivamente si procede in modo ricorsivo
all'ordinamento parziale delle sottosequenze di elementi
rimasti non ordinati, fino al loro esaurimento.
Quick Sort
• Esempio:
void sort(int a[ ], int inizio, int fine) {
int x, y, z;
if (fine >inizio) {
x = a [inizio];
y= inizio + 1;
z= fine+1;
while (y < z) {
if (a [y] < x) y++;
else {
r--;
swap(a[y], a[z]);
}
void swap(int & x, int & y) {
int temp=x;
x=y;
y=temp;
}
Merge Sort
E’ un algoritmo di ordinamento basato su confronti che
utilizza un processo di risoluzione ricorsivo, sfruttando la
tecnica del Divide et Impera, che consiste nella
suddivisione del problema in sottoproblemi della stessa
natura di dimensione via via più piccola.
L'insieme di elementi viene diviso in 2 metà. Se l'insieme
è composto da un numero dispari di elementi, viene
diviso in 2 sottogruppi dei quali il primo ha un elemento
in meno del secondo. Supponendo di avere due sequenze
già ordinate. Per unirle, mergesort estrae ripetutamente il
minimo delle due sequenze in ingresso e lo pone in una
sequenza in uscita.
Merge Sort
• Esempio:
void mersort (int x[ ], int sinistra, int centro, int destra)
int i = sinistra, j=centro+ 1,k=0;
int y[ ];
while ((i <= centro) && (j <= destra)) {
if (x[i] <= x[j]){
y[k]=a[i];
i=i + 1;
} else {
void mergesort (int[] a, int left, int right) {
y[k] = x[j];
int center;
j=j + 1;
if (left < right) {
}
k=k + 1;
center = (left + right) / 2;
}
mergesort(a, left, center);
for (k =left ;k<right;k++) {
mergesort(a, center+1, right);
a[k] = b[k - left];
merge(a, left, center, right);
}
}
Heap Sort
E’ un algoritmo di ordinamento iterativo ed in-place che si
basa su strutture dati ausiliarie.
L' heapsort per eseguire l'ordinamento, utilizza una struttura
chiamata heap (mucchio); un heap è rappresentabile con un
albero binario in cui tutti i nodi seguono una data proprietà,
detta priorità. Esso è completo almeno fino al penultimo
livello dell'albero e ad ogni nodo corrisponde uno ed un solo
elemento.
In uno heap decrescente (utilizzato per ordinare ad esempio
un array in senso crescente) ogni nodo padre contiene un
valore maggiore o uguale a quello dei suoi due figli diretti, di
conseguenza risulterà maggiore anche di tutti i nodi che si
trovano nel sottoalbero di cui esso è la radice.
Heap Sort
• Esempio:
void HeapSort(int a[ ], int n){
int i;
int lh = n;
Costruisci_Heap(a, n);
for(i = n-1; i > 0; i--){
temp = a[i];
a[i] = a[0];
a[0] = temp;
lh--;
Rendi_Heap(a, n, lh, 0); }
}
Counting Sort
E’ un algoritmo di ordinamento per valori numerici interi
con complessità lineare. L'algoritmo si basa sulla
conoscenza a priori dell'intervallo in cui sono compresi i
valori da ordinare.
Per ogni elemento x dell'insieme da ordinare si
determinano quanti elementi sono minori di x, si usa
questa informazione per assegnare ad x la sua posizione
finale nel vettore ordinato. Se, ad esempio, vi sono 8
elementi minori di x, allora x andrà messo nella posizione
9 bisogna fare attenzione al caso in cui vi siano elementi
coincidenti. In questo caso infatti non vogliamo assegnare
a tutti la stessa posizione.
Counting Sort
• Esempio:
void counting_sort(int* A, int Alen, int* B, int k){
int i;
int C[k];
for(i=0; i<k; i++)
C[i] = 0;
int j;
for(j=0; j<Alen; j++)
C[A[j]] = C[A[j]]+1;
for(i=1; i<k; i++)
C[i] = C[i]+C[i-1];
for (j=Alen-1; j>=0; j--){
B[C[A[j]]-1] = A[j];
C[A[j]] = C[A[j]]-1;
}
}
Bucket Sort
E’ un algoritmo di ordinamento per valori numerici che si assume siano
distribuiti uniformemente in un intervallo semichiuso (0,1).
Bucket sort suppone che l’input sia generato da un processo casuale
che distribuisce gli elementi uniformemente nell’intervallo [0, 1 ]. Il
concetto che sta alla base
dell’algoritmo è quello di dividere l’intervallo [0, 1 ] in n sottointervalli
della stessa dimensione, detti bucket, nei quali vengono distribuiti gli n
valori di input. A questo
scopo lo pseudocodice che definisce l’algoritmo suppone che l’input
sia un array A di n elementi e richiede un array ausiliario B[0...n−1] di
liste concatenate (bucket). L’algoritmo procede semplicemente
ordinando i valori in ogni bucket tramite un ordinamento di tipo
insertion sort. L’output viene infine prodotto concatenando in ordine i
vari bucket in un array.
Bucket Sort
• Esempio:
#include <stdio.h>
void bucketSort(int array[ ], int n) {
int i, j;
int count[n];
for(i=0; i < n; i++) {
count[i] = 0;
}
for(i=0; i < n; i++) {
(count[array[i]])++;
}
for(i=0,j=0; i < n; i++) {
for(; count[i]>0; (count[i])--) {
array[j++] = i;
}}}
int main() {
int array[] = {1,3,4,6,4,2,9,1,2,9};
int n = 10;
int i;
for (i = 0;i < n;i++) {
printf("%d ", array[i]);
}
printf("\n");
bucketSort(array, n);
for (i = 0;i < n;i++) {
printf("%d ", array[i]);
}
printf("\n");
return 0;