Sei sulla pagina 1di 26

Laboratorio di Programmazione

(Laurea triennale in matematica)

Lezione 11
Problema della ricerca
Il problema della ricerca (searching) può essere posto
nei seguenti termini:
- Dati un insieme di elementi qualsiasi A={a1,a2,…,an}
appartenenti ad un insieme S e dato un elemento k di
S, verificare se k è presente in A .

- Se A è rappresentato con un array, in genere si chiede


di restituire la posizione dell'array in cui si trova k.
Ricerca lineare
int linearSearch(int a [], int key, int size)
{
int i;

for (i = 0; i <= size - 1; ++i)


if (array[i] == key)
return i;

return -1;
}
Ricerca lineare 2
int linearSearch2(int a [], int key, int size)
{
int i=0;
int trovato=0;
while ( i < size && !trovato){
if (a [i] == key)
trovato=1;
i++;
}
if (trovato) return (i-1);
else return -1;
}
Complessità

Caso peggiore: O(n)


Se l'elemento non si trova nell'array devo comunque
leggere tutto l'array!

Caso migliore: O(1),


L'elemento cercato è il primo (?)
Se l'array è ordinato...

Il problema della ricerca di un elemento è


molto più semplice (dal punto di vista di
complessità di tempo):

uso la ricerca binaria


(tecnica del divide et impera)
Ricerca binaria
int binarySearch(int b[], int Key, int l, int r)
{ int mid;
while (l <= r) {
mid = (l + r) / 2;
if (Key == b[mid])
return mid;
else
if (Key < b[mid])
r = mid - 1;
else
l = mid + 1;
}
return -1; /* Key non trovato*/
}
Ricerca binaria (versione ricorsiva)
int binSearchRic(int b[], int Key, int l, int r)
{ int mid;
if (l <= r) {
mid = (l + r) / 2;
if (Key == b[mid])
return mid;
else
if (Key < b[mid])
return binSearchRic(b, Key, l, mid - 1);
else
return binSearchRic(b, Key, mid + 1,r);
}
else
return -1; /* Key non trovato*/
}
Complessità

Caso peggiore: O(log n)


Ad ogni chiamata ricorsiva, l'array dimezza la sua
dimensione.

Caso migliore: O(1),


L'elemento cercato è il quello centrale..
Problema dell' ordinamento
Il problema dell’ordinamento (sorting) può essere posto nei
seguenti termini:
Dati un insieme di elementi A={a1,a2,…,an}, su cui
sia possibile definire una relazione d’ordine totale
≤ si richiede di produrre una permutazione degli
elementi in modo che a i h ≤ a i k per ogni
h,k=1,2,….,n e h ≤ k

- Una relazione d’ordine totale è una relazione riflessiva,


antisimmetrica e transitiva definita su ogni coppia di
elementi dell’insieme
- La soluzione è unica a meno di elementi uguali.
Algoritmi di ordinamento
Gli algoritmi di ordinamento sono un «argomento
classico» dell’informatica:

• Valenza didattica: problema in sè molto semplice che


presenta tutti aspetti fondamentali della
progettazione e della costruzione di un algoritmo
efficiente
Algoritmi di ordinamento
Valenza in ambito applicativo:
• L'ordinamento e' un passo intermedio utile per
l'ottimizzazione di altre procedure molto comuni in vari
algoritmi
• Una alta percentuale del tempo di esecuzione di una
applicazione complessa e' speso in operazioni di
ordinamento
• L'ordinamento e' in genere una sub-routine annidata
profondamente all'interno di procedure iterative e
dunque migliorarne l'efficienza ha profonde
implicazioni sull'efficienza complessiva dei programmi
Algoritmi di ordinamento

In letteratura esistono MOLTISSIMI algoritmi di


sorting MOLTO DIVERSI tra loro.

• In che cosa sono diversi?


• Come scelgo quello migliore?
• (Come scelgo quello adatto al mio problema?)
Algoritmo SelectionSort

• Effettuo n-1 ricerche di minimo sui vettori


(sempre più corti) a[0.....n-1], a[1, ...n-1],
a[2....n-1],.....
– Scorro il vettore da sin verso destra alla
ricerca dell'elemento minimo, alla fine
scambio il primo elemento con quello
contenente il minimo.
NOTA: alla fine i-esima iterazione i primi i
elementi sono ordinati.
SelectionSort
//calcola indice del valore min nella porzione v[k]…… v[n-1]
int findMin(int[] v, int k,int n) {
int j, min;
min=k;
for (j=k+1;j<n;j++)
if (v[j] < v[min])
min = j;
return min;
}

void selectionSort(int[] a, int n) {


int i, min, tmp;
for (i=0;i<n-1;i++) {
min=findMin(a,i,n);
tmp=a[i]; //scambia a[i] e a[min]
a[i]=a[min];
a[min]=tmp;
}
}
SelectionSort
void selectionSort(int[] a, int n) {
int i,j, min;
int tmp;
for (i=0;i<n-1;i++) {
int min=i;
for (j=i+1;j<n;j++)
if (a[j] < a[min])
min = j;
tmp=a[i]; //scambia a[i] e a[min]
a[i]=a[min];
a[min]=tmp;
}
}
Dimostrazione correttezza e calcolo complessità

• Situazione del calcolo alla k-esima iterazione (i=k)

• Numero operazioni di confronto per la k-esima iterazione (i=k)


SelectionSort con max
void selectionSort2(int[] a, int n) {
int i,j, max;
int tmp;
for (i=0;i<n-1;i++) {
int max=i;
for (j=0;j<n-i;j++)
if (a[j] > a[max])
max = j;
tmp=a[i]; //scambia a[i] e a[min]
a[i]=a[max];
a[max]=tmp;
}
}
Dimostrazione correttezza e calcolo complessità

• Situazione del calcolo alla k-esima iterazione (i=k)

• Numero operazioni di confronto per la k-esima iterazione (i=k)


Algoritmo BubbleSort
• Per n-1 volte:
– Scorro il vettore da sin verso destra confrontando le coppie di
elementi adiacenti.
– Se a[ i ] > a[ i+1],
scambio i due valori
BubbleSort v.1
void bubbleSort(int a[], int n)
{
int i, j, tmp;
for (i = 0; i < n-1; i++){
for (j = 0; j < n-1; j++){
if (a[j] > a[j+1]) {
tmp = a[j]; //scambia a[j] e a[j+1]
a[j] = a[j+1];
a[j+1] = tmp;
}
}
}
}
Dimostrazione correttezza e calcolo complessità

• Situazione del calcolo alla k-esima iterazione (i=k)


Alla fine del primo scorrimento il valore max sta nella posizione
più a destra.
Alla k-esima iterazione i k elementi più a destra sono ordinati
e "al loro posto"

• Numero operazioni di confronto per la k-esima iterazione (i=k)


BubbleSort v.2 (migliore!)
void bubbleSort(int[] v, int n) {
int i,j,scambi, tmp;
scambi = 1;
for (i=0; (i<n-1 && scambi) ; i++) {
scambi = 0;
for (j=0; j<n-1-i ; j++)
if (v[j] > v[j+1])
{ scambi = 1;
tmp = v[j];
v[j] = v[j+1];
v[j+1] = tmp; }
}
}
Dimostrazione correttezza e calcolo complessità

• Situazione del calcolo alla k-esima iterazione (i=k)


• Alla fine del primo scorrimento il valore max sta nella
posizione più a destra.
• Alla k-esima iterazione i k elementi più a destra sono ordinati
e "al loro posto "

• Se in una iterazione non faccio alcuno scambio, non ne farò più


neanche nelle successive

• Numero operazioni di confronto per la k-esima iterazione (i=k)


The end