Menu
Coddy logo textTech

Ricerca binaria

Ultimo aggiornamento

La ricerca binaria trova un valore in un array **ordinato** dimezzando ripetutamente la finestra di ricerca. Confronta l'elemento centrale con il valore cercato: se coincidono, la ricerca finisce; altrimenti scarta la metà che non può contenere il valore e la finestra si riduce all'altra metà. Ogni confronto elimina metà degli elementi rimasti, ed è per questo che richiede O(log n): cercare in un milione di valori ordinati richiede al massimo circa 20 confronti.

L'animazione qui sopra mostra i puntatori lo, mid e hi e oscura la metà eliminata dopo ogni confronto. L'unica condizione irrinunciabile: l'array deve essere già ordinato. Su dati non ordinati ti serve la ricerca lineare oppure prima un ordinamento (vedi merge sort). La stessa idea di dimezzamento è alla base dell'albero binario di ricerca.

Complessità temporale e spaziale

CasoComplessitàNote
Caso miglioreO(1)L'elemento centrale è quello cercato al primo confronto.
Caso medioO(log n)Ogni confronto dimezza la finestra rimasta.
Caso peggioreO(log n)La finestra si riduce a un solo elemento prima di trovarlo o mancarlo.
SpazioO(1)La versione iterativa tiene solo gli indici lo, hi e mid.

Passo dopo passo

PassoCosa succede
1Imposta lo al primo indice e hi all'ultimo indice dell'array ordinato.
2Calcola l'indice centrale: mid = (lo + hi) // 2.
3Se a[mid] è uguale al valore cercato, restituisci mid (trovato).
4Se a[mid] è **minore** del valore cercato, questo può stare solo nella metà destra: imposta lo = mid + 1.
5Se a[mid] è **maggiore** del valore cercato, cerca nella metà sinistra: imposta hi = mid - 1.
6Ripeti dal passo 2 finché lo <= hi; se la finestra si svuota, il valore non è nell'array.

Esempio svolto

Ricerca di 5 in [1, 2, 3, 5, 7, 8, 9]:

PassataFinestra (lo..hi)mida[mid]Azione
1[1, 2, 3, 5, 7, 8, 9] (0..6)35a[3] = 5: valore trovato all'indice 3.

Una ricerca a vuoto, passo dopo passo

Cercare 4 nello stesso array mostra come la finestra si svuota:

PassataFinestra (lo..hi)mida[mid]Azione
10..6355 > 4: cerca nella metà sinistra, hi = 2.
20..2122 < 4: cerca nella metà destra, lo = 2.
32..2233 < 4, quindi lo diventa 3 e la finestra si svuota: non trovato.

Quando usare la ricerca binaria

Usala quandoEvitala quando
I dati sono già ordinati (o li cerchi molte volte)I dati non sono ordinati e li cerchi una sola volta (ordinarli prima costa O(n log n))
La collezione supporta un accesso casuale veloce (array)Hai solo accesso sequenziale (liste concatenate)
L'insieme di dati è grande (O(log n) dà il meglio su larga scala)L'insieme di dati è minuscolo (una semplice scansione è altrettanto veloce e più semplice)

Un'implementazione di Binary Search pulita ed eseguibile in Python, JavaScript, Java, C++, C, Pseudocode. Scegli un linguaggio, copia il codice o aprilo già caricato nel Playground di Coddy.

Codice Binary Search in Python

Python
1def binary_search(a, target):2    lo, hi = 0, len(a) - 13    while lo <= hi:4        mid = (lo + hi) // 25        if a[mid] == target:6            return mid7        if a[mid] < target:8            lo = mid + 1  # search the right half9        else:10            hi = mid - 1  # search the left half11    return -112
13
14nums = [1, 2, 3, 5, 7, 8, 9]  # must be sorted15print("Index of 5:", binary_search(nums, 5))16print("Index of 4:", binary_search(nums, 4))
Esegui questo codice nel playground Python

Domande frequenti sulla ricerca binaria

Qual è la complessità temporale della ricerca binaria?
O(log n) nel caso medio e peggiore, perché ogni confronto dimezza la finestra di ricerca rimasta, e O(1) nel caso migliore, quando il primo elemento centrale è quello cercato. La versione iterativa usa O(1) di spazio extra.
Perché la ricerca binaria richiede un array ordinato?
Il dimezzamento si basa sull'ordine: confrontare il valore cercato con l'elemento centrale ti dice quale metà scartare solo se tutto ciò che sta a sinistra del centro è più piccolo e tutto ciò che sta a destra è più grande. Su dati non ordinati questa deduzione non vale, quindi usa la ricerca lineare oppure ordina prima.
Qual è la differenza tra ricerca binaria e ricerca lineare?
La ricerca lineare scorre gli elementi uno a uno (O(n)) e funziona su qualsiasi array; la ricerca binaria dimezza la finestra di ricerca di un array ordinato (O(log n)) ma richiede un input ordinato. Con pochi elementi la differenza è trascurabile; su larga scala la ricerca binaria vince nettamente.
Quanti confronti servono alla ricerca binaria?
Al massimo circa log2(n) + 1: 10 confronti coprono 1.000 elementi, 20 confronti ne coprono 1.000.000. Questa crescita logaritmica è ciò che la rende la ricerca predefinita sui dati ordinati.
Qual è il classico bug di overflow nella ricerca binaria?
Calcolare il centro come (lo + hi) / 2 può causare un overflow con gli interi a dimensione fissa quando lo + hi supera il massimo del tipo. La forma sicura è mid = lo + (hi - lo) / 2. In Python non importa (gli interi hanno precisione arbitraria), ma in Java/C/C++ è un bug reale e famoso.
La ricerca binaria è la stessa cosa di un albero binario di ricerca?
Condividono l'idea del dimezzamento ma hanno una struttura diversa: la ricerca binaria è un algoritmo su un array ordinato, mentre un albero binario di ricerca è una struttura dati collegata che mantiene le chiavi ordinate, così le ricerche scendono a sinistra o a destra a ogni nodo.
Illustrazione dei linguaggi di programmazione di Coddy

Padroneggia gli algoritmi con Coddy

INIZIA