Individuare la posizione di un certo elemento all’interno di una sequenza data.
Posizione di un valore k all’interno di un array v
Function Posizione(V: Vettore; N: Integer; K: Real): Integer; Var i, Risp: Integer; Begin Risp:=0; For i:=1 to N do If(V[i] = K) Then Risp:=i; Posizione:=Risp; End;
Purtroppo restituisce la posizione dell’ultimo valore presente.
Posizione di un elemento (la prima…)
Function Posizione(V: Vettore; N: Integer; K: Real): Integer; Var i, Risp: Integer; Begin i:=1; Risp:=0; While(i <= N) And (Risp = 0) Do Begin If(V[i] = K) Then Risp:=i; i:=i+1; End; Posizione:=Risp; End;
Semplifico il ciclo
Function Posizione(V: Vettore; N: Integer; K: Real): Integer; Var i: Integer; Begin i:=1; While(i <= N) And (V[i] <> K) Do i:=i+1; If(i > N) Then Posizione:=0 Else Posizione:=i; End;
La ricerca sequenziale effettua una scansione dell'array finché non trova il valore richiesto, se presente, o l'array finisce.
Array ordinato
Se l'array è ordinato e l'elemento non compare la ricerca sequenziale può essere interrotta se l'elemento esaminato è maggiore di quello cercato
Function Posizione(V: Vettore; N: Integer; K: Real): Integer; Var i: Integer; Begin i:=1; While(i <= N) And (V[i] < K) Do i:=i+1; If(i > N) Or (V[i] > K) Then Posizione:=0 Else Posizione:=i; End;
Ricerca sequenziale con sentinella
Si tratta di una versione leggermente migliorata dell'algoritmo.
Il confronto (i <= n) ripetuto a ogni passo può essere eliminato se si introduce la sentinella, la chiave della ricerca, alla prima posizione libera nell'array.
Il ciclo si chiude comunque nel caso in cui la chiave non esista.
Function Sentinella(V: Vettore; N: Integer; K: Real): Integer; Var i: Integer; Begin i:=1; V[N+1]:=K; While(V[i] <> K) Do i:=i+1; If(i > N) Then Sentinella:=0 Else Sentinella:=i; End;
Array ordinato
Se l'array è ordinato si può introdurre un ulteriore miglioramento...
Function Sentinella(V: Vettore; N: Integer; K: Real): Integer; Var i: Integer; Begin i:=1; V[N+1]:=K; While(V[i] < K) do i:=i+1; If(i > N) Or (V[i] > K) Then Sentinella:=0 Else Sentinella:=i; End;
Analisi della complessità, in tempo e asintotica, dell'algoritmo di ricerca sequenziale.
Il codice analizzato è il seguente
Function ricercaSequenziale(V: Vettore; N: Integer; K: Real): Integer; Var i: Integer; Begin i:=1; (* 1 *) While(i <= N) And (V[i] <> K) Do (* 2, 3, 4 *) i:=i+1; (* 5, 6 *) If(i > N) Then (* 7 *) ricercaSequenziale:=0 (* 8 *) Else ricercaSequenziale:=i; (* 9 *) End;
presenta operazioni di
- assegnamento: 1, 5, 8, 9
- confronto: 2, 4, 7
- aritmetico-logiche: 3, 6
Il tempo totale richiesto da questo sottoprogramma alla CPU è
con
- (T2+T3+T4+T5+T6), le operazioni svolte ad ogni passo del While
- x, il numero di volte che viene eseguito il While (da 0 a n)
- (T2+T3+T4), quando K viene individuato alla posizione i-esima oppure il vettore finisce
- T8|9, una delle due istruzioni finali
Per semplificare i calcoli si decide di trascurare le differenze esistenti tra i tempi di esecuzione delle diverse operazioni e di stabilire un tempo costante per tutte, allora
I valori effettivi di T sono
- vettore vuoto: T1+(T2+T3+T4)+T7+T8 = 6
- elemento in 1° posizione: T1+(T2+T3+T4)+T7+T9 = 6
- elemento in 2° posizione: T1+[T2+T3+T4+T5+T6]+(T2+T3+T4)+T7+T9 = 6+5*1 = 11
- elemento in 3° posizione: T1+[T2+T3+T4+T5+T6]*2+ ... = 6+5*2 = 16
- ...
- elemento in ultima posizione: 6+5*(n-1)
- elemento non presente: 6+5n
Analizziamo i casi più interessanti
- Caso ottimo, quando il vettore è vuoto oppure l'elemento K compare in 1° posizione: T=6
- Caso pessimo, se l'elemento K non è presente: T=6+5n
- Caso medio, supponiamo di effettuare n ricerche con l'elemento presente alle diverse posizioni: T=3.5+2.5n
Conclusioni
Il tempo richiesto è, tranne che nei casi banali, una funzione lineare di n, il numero di elementi presenti nel vettore
I valori delle due costanti c1 e c2 sono modesti e comunque poco significativi.
T=[(6+5*0)+(6+5*1)+(6+5*2)+...+(6+5(n-1))]/n
=[6n+5(1+2+...+n-1)]/n
=[6n+5(n-1)*n/2]/n
=6+5(n-1)/2
=6+5/2*n-5/2
=7/2+5/2*n
=3.5+2.5*n