Sistemi e Tecnologie
Informatiche
Strategie di Ricerca
Umberto Ferraro Petrillo
Ricerca di un elemento
Problema: Dato un elenco di voti ed un valore x
(e.g., 29), stabilire se x compare
nell’elenco e in che posizione
25
27
21
29
24
26
19
27
20
30
25
Ricerca sequenziale
(in ordine crescente)
• Consente l’individuazione di un qualsiasi valore
all’interno di un elenco
• Gli elementi che compongono l’elenco sono disposti
in un ordine qualunque
• Si scorre l’elenco dal primo all’ultimo elemento
confrontando l’elemento corrente con quello ricercato
• E’ possibile stabilire che un elemento è assente
solo dopo aver considerato tutti gli elementi della lista
1 int PosizioneElemento(int Voti[], int elem, int n)
/* Effettua
la di
ricerca
elem stesso
tra i primi
elementi di Voti.
2 Voti
Sia
l’elenco
input,esaustiva
n la tagliadidello
ed nelem
Il valore
di ritorno e` -1 se elem non e` presente in Voti,
3
l’elemento
cercato
altrimenti e` l'indice della posizione di elem. */
4
5 {
i = 0; dell’elemento attualmente considerato, inizialmente i = 0
6 i int
Sia
l’indice
7
8 // Verifichiamo se la fine dell’elenco è stata raggiunta
se l’elemento
coincide
quelload
cercato
Ripeti
n-1 volte ocorrente
fino a che
Voti[i] con
è uguale
elem
9 // oper
10 while ( i<n-1 && Voti[i] != elem )
// Consideriamo il prossimo elemento
11 i++;
Considera il prossimo elemento (i=i+1)
12
13 if (Voti[i] == elem)
return i;
// L’elemento è stato individuato
14
15 else
return -1;
// L’elemento non è presente
16
17
} /* PosizioneElemento
18
Se Voti[i]
è uguale ad elem*/ restituisci i altrimenti restituisci -1
19
20
21
22
23
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
int PosizioneElemento(int Voti[], int elem, int n)
/* Effettua la ricerca esaustiva di elem tra i primi n elementi di Voti.
Il valore di ritorno e` -1 se elem non e` presente in Voti,
altrimenti e` l'indice della posizione di elem. */
{
int i = 0;
// Verifichiamo se la fine dell’elenco è stata raggiunta
// o se l’elemento corrente coincide con quello cercato
while ( i<n-1 && Voti[i] != elem )
i++;
// Consideriamo il prossimo elemento
if (Voti[i] == elem)
return i;
// L’elemento è stato individuato
else
return -1;
// L’elemento non è presente
} /* PosizioneElemento */
Ricerca di un elemento
Supponiamo che l’elenco di partenza sia
ordinato, è possibile migliorare la ricerca
sequenziale?
19
21
24
25
25
26
27
28
28
29
Ricerca binaria
Si consideri un elenco in input ordinato A ed un
valore x da ricercare (e.g., 26):
Passo 1: Confrontiamo x con l’elemento centrale dell’elenco (A[4])
0
1
2
3
4
5
6
7
8
9
19
21
24
25
25
26
27
28
28
29
Caso 1: x==A[4], Ricerca terminata!
Caso 2: x<A[4], proseguiamo la ricerca in A[0…3]
Caso 3: x>A[4], proseguiamo la ricerca in A[5…9]
Ricerchiamo
l’elemento 26
Ricerca binaria
0
1
2
3
4
5
6
7
8
9
19
21
24
25
25
26
27
28
28
29
3
4
5
6
7
8
9
Confrontiamo
26 con A[4], è più
grande (caso 3),
proseguiamo la
ricerca in A[5..9]
26>25 (A[4])
0
19
1
21
2
24
25
25
26
27
28
28
29
3
4
5
6
7
8
9
Confrontiamo
26 con A[7], è più
piccolo (caso 2),
proseguiamo la
ricerca in A[5..6]
26<28 (A[7])
0
19
1
21
2
24
26==26 (A[5])
25
25
26
27
28
28
29
10
30
Confrontiamo
26 con A[5], i due
numeri
coincidono,
la ricerca termina
1 int PosizioneElemento(int inf, int sup, int Voti[], int elem) {
2 /* Effettua la ricerca binaria di elem tra i primi n elementi di Voti.
Cerca
elem nel vettore ordinato Voti[inf … sup]
Il valore di ritorno e` -1 se elem non e` presente in Voti,
3
altrimenti e` l'indice della posizione di elem. */
4
5
if ( inf>sup)
// Verifichiamo
esistono
ancora
elementi
6 l’array
Se
è vuoto
(inf>sup) la se
ricerca
termina
(ritorna
-1) da considerare
return -1;
7
8 else{
= (int) (infnella
+ sup)
/ 2;
Considera
l’elemento
posizione
centrale (med=(inf+sup)/2)
9 int med
10
11 if (Voti[med] == elem)
Se elem
è uguale a Voti[med]
la ricerca termina (ritorna med)
return med;
// L’elemento è stato individuato
12
13 else
if (elem
< Voti[med])
{ di Voti[med] cerca elem nel vettore
Altrimenti,
se elem
è minore
14
sup = med
-1; //-1]
Cerchiamo nella porzione di sinistra
ordinato
Voti[inf
… med
15
return PosizioneElemento(Voti, inf, sup, elem);
16
} else{
17
inf = med + 1; // Cerchiamo nella porzione di destra
18
Altrimenti,return
cercaPosizioneElemento(Voti,
elem nel vettore ordinato
Voti[med+1 … sup]
inf, sup, elem);
19
20 }
21 }
22 } /* PosizioneElemento */
23
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
int PosizioneElemento(int inf, int sup, int Voti[], int elem) {
/* Effettua la ricerca binaria di elem tra i primi n elementi di Voti.
Il valore di ritorno e` -1 se elem non e` presente in Voti,
altrimenti e` l'indice della posizione di elem. */
if ( inf>sup) // Verifichiamo se esistono ancora elementi da considerare
return -1;
else{
int med = (int) (inf + sup) / 2;
if (Voti[med] == elem)
return med;
// L’elemento è stato individuato
else
if (elem < Voti[med]) {
sup = med -1; // Cerchiamo nella porzione di sinistra
return PosizioneElemento(Voti, inf, sup, elem);
} else{
inf = med + 1; // Cerchiamo nella porzione di destra
return PosizioneElemento(Voti, inf, sup, elem);
}
}
} /* PosizioneElemento */
Ricerca binaria vs
Ricerca sequenziale
L’efficienza di un algoritmo di ricerca può
essere stimata in funzione del numero di
confronti che esso richiede
L’algoritmo peggiore è quello che necessita
del maggior numero di confronti
Ricerca sequenziale
Si consideri il problema della ricerca di un valore x
all’interno di un elenco di taglia n
Nella ricerca sequenziale ogni confronto ci consente
di escludere al più un elemento
Dopo il primo confronto avremo escluso l’elemento 0
Dopo il secondo confronto avremo escluso l’elemento
1
…
Dopo il confronto k-esimo avremo escluso k elementi
Nel peggiore dei casi (l’elemento ricercato non
esiste nell’elenco) saranno necessari n
confronti per dare una risposta
Ricerca binaria vs
Ricerca sequenziale
Nella ricerca binaria ogni confronto ci consente di escludere circa
la metà degli elementi presenti
Dopo il primo confronto restringiamo la ricerca ad n/2
elementi
Dopo il secondo confronto restringiamo la ricerca ad (n/2)/2 =
n/4 elementi
…
Dopo il confronto k-esimo restringiamo la ricerca ad n/2k
elementi
Nel peggiore dei casi (l’elemento ricercato non esiste nell’elenco)
porteremo avanti la ricerca sino a restringerla ad un solo
elemento n/2k =1
Saranno quindi necessari al più k = log(n) confronti
Ricerca binaria vs
Ricerca sequenziale
Taglia elenco
Ricerca
input
sequenziale
n=1,000
1,000
Ricerca
binaria
9,96
n=10,000
10,000
13,28
n=100,000
100,000
16,6
n=1,000,000
1,000,000
19,9