Plus facile à lire avec un fond crème, une teinte, plus de contraste ou un texte plus grand ? Choisissez vos couleurs et votre texte, une fois pour toutes les pages.

Leçon gratuite

Recherche linéaire et recherche dichotomique

Après cette leçon: Je peux comparer la recherche linéaire et la recherche dichotomique.

Leçon de 55 min4 commandesLab Linux du quotidien : la trentaine de commandes que les ingénieurs tapent de tête

Un million de valeurs, vingt comparaisons

La recherche dichotomique retrouve une valeur dans une liste triée en coupant la liste en deux à chaque étape. Pour un million de valeurs, elle demande au plus 20 comparaisons, contre un million pour la recherche linéaire.

Une université garde un fichier trié de 40 000 numéros de carte étudiante. Retrouver une carte à la main demande de la patience. Avec la bonne méthode, 16 cases suffisent.

À la fin de cette leçon

Remarque

Je peux comparer la recherche linéaire et la recherche dichotomique.

Mots-clés

MotCe que ça veut direExemple
Recherche linéaireregarder les cases une à une, depuis le début
Recherche dichotomiqueregarder la case du milieu et écarter une moitié
Liste triéeune liste rangée du plus petit au plus grand
Indicela place d’une case dans la liste0 pour la première
Pire des casle plus grand nombre d’étapes possible

Les cellules que les étudiants remplissent restent vides dans cet aperçu.

La recherche linéaire regarde chaque case

La recherche linéaire commence à la première case et avance jusqu’à trouver la valeur. Elle marche sur toute liste, triée ou non.

Dans le pire des cas, la valeur est en dernière place ou absente : il faut regarder les n cases. Sa complexité est donc linéaire, O(n).

Une recherche linéaire qui compte

Code: python
# Recherche linéaire dans la liste des numéros de carte.
cartes = [3, 9, 14, 21, 28, 37, 45, 52, 60, 71, 83]
cible = 21
pas = 0
trouve = -1
for i in range(len(cartes)):
    pas = pas + 1  # une comparaison
    if cartes[i] == cible:
        trouve = i
        break
print("indice :", trouve, "en", pas, "étapes")
# Cherchez 100, qui n’est pas dans la liste.

La dichotomie écarte la moitié de la liste

Dans une liste triée, on regarde la case du milieu. Si la valeur est plus grande que la cible, la cible ne peut pas être à droite : on écarte toute la moitié de droite.

Si elle est plus petite, on écarte la moitié de gauche. On recommence sur la moitié qui reste, jusqu’à trouver la cible ou n’avoir plus de case.

Exemple travaillé : chercher 21

PasZone gardée (indices)Case du milieuValeurDécision
10 à 10537Trop grande : on garde 0 à 4
20 à 4214Trop petite : on garde 3 à 4
33 à 4321Égale : trouvé à l’indice 3

Les cellules que les étudiants remplissent restent vides dans cet aperçu.

Une recherche dichotomique qui compte

Code: python
# Recherche dichotomique : la liste doit être triée.
cartes = [3, 9, 14, 21, 28, 37, 45, 52, 60, 71, 83]
cible = 21
debut = 0
fin = len(cartes) - 1
pas = 0
trouve = -1
while debut <= fin and trouve == -1:
    milieu = (debut + fin) // 2
    pas = pas + 1  # on regarde une seule case
    if cartes[milieu] == cible:
        trouve = milieu
    elif cartes[milieu] < cible:
        debut = milieu + 1
    else:
        fin = milieu - 1
print("indice :", trouve, "en", pas, "étapes")
# Cherchez 83, puis 50.

Combien d’étapes demande la dichotomie ?

À chaque étape, la zone à explorer est divisée par deux. Une liste de 1 000 cases passe à 500, 250, 125, et ainsi de suite jusqu’à une seule case.

Le pire des cas vaut donc environ le nombre de fois qu’on peut diviser n par deux : c’est la complexité logarithmique, O(log n). Elle bat la recherche linéaire dès que la liste est un peu longue.

Pire des cas, deux méthodes

Cases (n)Recherche linéaireRecherche dichotomique
10104
1001007
1 0001 00010
1 000 0001 000 00020

Les cellules que les étudiants remplissent restent vides dans cet aperçu.

Faut-il trier avant de chercher ?

Trier une liste coûte plus cher qu’une seule recherche linéaire. Trier d’abord ne vaut donc pas la peine pour une seule recherche.

Il devient utile quand on cherche souvent dans la même liste : le tri se paie une fois, puis chaque recherche coûte peu. Un annuaire est trié pour cette raison.

Une recherche linéaire en une ligne

Commande
seq 1 1000 | grep -n -x 700

Affichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.

Pire des cas pour 1 000 cases

Commande
python3 -c "print(1000 .bit_length())"

Affichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.

Pire des cas pour un million de cases

Commande
python3 -c "print((10 ** 6).bit_length())"

Affichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.

Un tri de textes, pas de nombres

Commande
printf '5\n12\n7\n' | sort | xargs

Affichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.

Erreur fréquente

Attention

Beaucoup pensent que la recherche dichotomique marche sur n’importe quelle liste. Elle suppose une liste triée, et triée dans le même ordre que la comparaison. Sinon, écarter une moitié écarte peut-être la bonne réponse. Sur une liste non triée, utilisez la recherche linéaire.

À propos de ce labo et de sa source: Lab Linux du quotidien : la trentaine de commandes que les ingénieurs tapent de tête

Vous enseignez à une classe ? Proposez ce module à vos étudiants avec un guide de l'enseignant, des devoirs corrigés et un laboratoire pour chaque étudiant.