Ricerca binaria Corso di Algoritmi e Strutture Dati Esercitazione 4 Sommario • Algoritmi di ricerca – Ricerca lineare – Ricerca binaria • Manipolare array di oggetti Definizione del problema Dati: 1. Una sequenza A di elementi, 2. un elemento (chiave) x Verificare se x fa parte della sequenza oppure x non fa parte della sequenza stessa. Esempio • A= 7 2 4 5 3 • x = 5 Æ x∈A ?? SI • x = 9 Æ x∈A ?? NO 1 5 6 Ricerca lineare o sequenziale L’algoritmo di ricerca lineare (o sequenziale) in una sequenza (array) è basato sulla seguente strategia: – Gli elementi dell’array vengono analizzati in sequenza, confrontandoli con la chiave per determinare se almeno uno degli elementi è uguale alla chiave. – Quando si trova un elemento uguale alla chiave la ricerca termina. Ricerca lineare o sequenziale 7 2 4 5 3 1 5 6 Ricerca x = 5 7 2 4 5 3 1 5 6 7==5 ?? 7 2 4 5 3 1 5 6 2==5 ?? 7 2 4 5 3 1 5 6 7==5 ?? 7 2 4 5 3 1 5 6 exit 5==5 ?? SI Ricerca lineare o sequenziale 7 2 4 5 3 1 5 6 Ricerca x = 9 7 2 4 5 3 1 5 6 7==9 ?? 7 2 4 5 3 1 5 6 2==9 ?? 7 2 4 5 3 1 5 6 7==9 ?? 7 2 4 5 3 1 5 6 5==9 ?? Ricerca lineare o sequenziale 7 2 4 5 3 1 5 6 Ricerca x = 9 7 2 4 5 3 1 5 6 3==9 ?? 7 2 4 5 3 1 5 6 1==9 ?? 7 2 4 5 3 1 5 6 5==9 ?? 7 2 4 5 3 1 5 6 6==9 ?? 7 2 4 5 3 1 5 6 exit NO Ricerca lineare o sequenziale • La ricerca è sequenziale, nel senso che gli elementi dell’array vengono scanditi uno dopo l’altro sequenzialmente. • L’algoritmo prevede che al più tutti gli elementi dell’array vengano confrontati con la chiave. Se l’elemento viene trovato prima di raggiungere la fine della sequenza non sarà necessario proseguire la ricerca. Ricerca sequenziale in java /* * Algoritmo di ricerca sequenziale di un elemento x in un array A */ static boolean sequentialSearch (int A[], int x, int numeroConfronti[]) { numeroConfronti[0]=0; boolean found=false; for(int i=0;i<A.length;i++){ numeroConfronti[0]++; if(A[i]==x) // operazione predominante { found=true; break; } } return found; } Considerazioni relative al costo • L’algoritmo di ricerca lineare richiede che al più tutti gli elementi dell’array vengano confrontati con la chiave. Questo è necessario perché la sequenza non è ordinata. • Considerando il confronto(A[i]==x) come operazione predominante il costo della ricerca è pari a 1. 1 se x==A[0] 2. A.length se x=A[A.length-1] 3. A.length se x∉A In generale 1<=costo<=A.length Ricerca binaria • E se l’array fosse già ordinato?? – elenco telefonico, agenda, etc. • Sfrutto ordinamento per ridurre il numero di confronti nella ricerca Æ ricerca binaria Ricerca binaria: esempio 1 2 3 4 5 6 7 8 Ricerca x = 4 1 2 3 4 5 6 7 8 inizio = 0 fine = A.length = 8 • Elemento centrale – centro=(inizio+fine)/ 2 : A[4]=5 !=4 • In particolare 2<A[4] Î proseguo la ricerca nella porzione di array a sinistra di A[4], 1 2 3 4 5 6 7 8 inizio = 0 fine = centro = 4 <=5 Ricerca binaria: esempio inizio Ricerca x = 4 • Elemento centrale 1 fine 2 3 4 5 6 7 8 – centro=(inizio+fine)/2 : A[2]=3 !=4 • In particolare A[2]<4 Î proseguo la ricerca nella porzione di array a sinistra di A[2], 1 2 3 4 5 6 7 8 inizio = centro + 1 = 3 fine = 4 >=3 Ricerca binaria: esempio inizio fine 1 2 3 4 Ricerca x = 4 • Elemento centrale 5 6 7 8 – centro=(inizio+fine)/2 : A[3]=4 ==4 EXIT with TRUE Numero di confronti: 1 2 3 4 5 6 7 8 1 2 3 4 5 6 7 8 1 2 3 4 5 6 7 3 confronti ! 8 Ricerca binaria: strategia mentre (la chiave non è trovata e ci sono elementi da analizzare): 1. Confronta la chiave con l’elemento centrale dell’array, 2. Se la chiave è uguale all’elemento centrale, allora la ricerca termina positivamente, 3. Se invece la chiave è maggiore dell’elemento centrale si effettua la ricerca solo sulla porzione di array a destra, 4. Se invece la chiave è minore dell’elemento centrale si effettua la ricerca solo sullaporzione di array a sinistra. Ricerca binaria: strategia Note per l’implementazione in Java Denotiamo: 1. inizio: posizione di inizio della partizione da esplorare 2. fine: posizione di fine della partizione da esplorare 3. centro = (inizio+fine)/2 posizione di elemento centrale Si itera la ricerca al soddisfacimento della condizione “inizio<fine and not trovato” Svolgere l’esercizio completando l’implementazione della classe RicercaArray (vedi RicercaArray.java) Costo al variare della posizione della chiave chiave ∉Array length(Array)=15 chiave ∉Array 16 14 costo 12 10 8 6 4 2 0 -3 -2 -1 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 chiave costo ric. lineare costo ric. binaria Ricerca chiave non appartenente ad array ordinato costo (caso in cui chiave non appartiene ad array) 25 costo 20 costo ~ length(Array) 15 ricerca lineare ricerca binaria 10 5 costo ~ log2(length(Array)) 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 length(Array)