Aller au contenu principal

Informatique · Première · 5 min de lecture

Recherche dichotomique : couper en deux à chaque étape

Dans un tableau TRIÉ, on compare la valeur cherchée à l'élément du milieu et on poursuit dans la moitié qui peut la contenir ; la largeur de l'intervalle de recherche (variant de boucle) diminue strictement à chaque tour, ce qui prouve la terminaison ; le nombre de tours est au plus ⌊log₂ n⌋ + 1, soit un coût logarithmique, contre un coût linéaire pour le parcours séquentiel.

Chapitre du programme : Numérique et sciences informatiques (spécialité)

Bloc 1 sur 7 · Comprendre

Comprendre : éliminer la moitié du tableau

Pour chercher une valeur dans un tableau quelconque, il faut au pire regarder toutes les cases : c'est le parcours séquentiel, de coût linéaire. Mais si le tableau est trié dans l’ordre croissant, on peut faire beaucoup mieux, comme on cherche un mot dans un dictionnaire.

On compare la valeur cherchée v à l'élément du milieu de la zone de recherche :

  • s'il est égal à v, on a trouvé ;
  • s'il est plus petit que v, v ne peut être qu'à droite du milieu : on garde la moitié droite ;
  • s'il est plus grand, on garde la moitié gauche.

À chaque étape, la zone de recherche est au moins divisée par deux.

def recherche(t, v):
    debut = 0
    fin = len(t) - 1
    while debut <= fin:
        milieu = (debut + fin) // 2
        print(debut, fin, milieu, t[milieu])
        if t[milieu] == v:
            return milieu
        elif t[milieu] < v:
            debut = milieu + 1
        else:
            fin = milieu - 1
    return -1

t = [3, 8, 12, 17, 21, 26, 30, 34, 41, 47]
print(recherche(t, 34))
0 9 4 21
5 9 7 34
7

La ligne print(debut, fin, milieu, t[milieu]) affiche l'état de chaque tour : deux tours suffisent pour trouver 34, à l'indice 7.

Bloc 2 sur 7 · Approfondir

Approfondir : terminaison, valeur absente, coût

Terminaison : un variant de boucle. La quantité fin - debut est un entier ; à chaque tour où la valeur n'est pas trouvée, elle diminue strictement, car debut devient milieu + 1 ou fin devient milieu - 1. Tant que la garde est vraie, fin − debut est en outre positif ou nul. Un entier non négatif ne peut pas décroître strictement indéfiniment : la condition debut <= fin finit donc par être fausse, ou un return termine la fonction.

C'est pour cela qu'on écrit milieu + 1 et milieu - 1, et non milieu : sans le « + 1 », la zone peut cesser de diminuer.

Valeur absente. Quand la zone devient vide (debut > fin), la fonction renvoie -1 :

def recherche(t, v):
    debut = 0
    fin = len(t) - 1
    while debut <= fin:
        milieu = (debut + fin) // 2
        if t[milieu] == v:
            return milieu
        elif t[milieu] < v:
            debut = milieu + 1
        else:
            fin = milieu - 1
    return -1

t = [3, 8, 12, 17, 21, 26, 30, 34, 41, 47]
print(recherche(t, 20))
-1

Coût logarithmique. Après un tour sans succès, une zone de L éléments en laisse au plus L // 2. Le nombre maximal de tours est donc le nombre de divisions par 2 qu'on peut faire avant d'atteindre 0 :

for n in [10, 1000, 1000000]:
    tours = 0
    taille = n
    while taille > 0:
        tours = tours + 1
        taille = taille // 2
    print(n, tours)
10 4
1000 10
1000000 20

Pour un tableau vide (n = 0), la boucle n’effectue aucun tour. Pour un million d’éléments, 20 tours au plus, contre un million pour un parcours séquentiel. Ce nombre de tours est le nombre de bits de n : c'est un coût en log₂(n).

Bloc 3 sur 7 · Exemple

Exemple guidé : chercher 12

Énoncé. Dans t = [3, 8, 12, 17, 21, 26, 30, 34, 41, 47], combien de tours fait la boucle pour trouver 12 ?

Tableau : Tour, debut, fin, milieu, t[milieu], Décision
Tourdebutfinmilieut[milieu]Décision
10942121 > 12 : fin devient 3
203188 < 12 : debut devient 2
323212trouvé, indice 2

Trois tours. Remarquez que (0 + 3) // 2 vaut 1 : le quotient entier arrondit vers le bas.

Bloc 4 sur 7 · Visualiser

Voir : la zone de recherche qui rétrécit

Tableau : Tour, Zone (indices), Taille de la zone
TourZone (indices)Taille de la zone
départ0 à 910
après le tour 10 à 34
après le tour 22 à 32
tour 3trouvé—

À chaque tour, la taille passe de L à au plus L // 2 : 10, puis au plus 5, puis 2, puis 1. D'où au plus 4 tours pour 10 éléments.

Continuez sur votre lancée

Vous avez découvert l’essentiel et un exemple. Retrouvez la suite du cours et les points à retenir, puis passez à l’entraînement guidé dans votre compte.

  • Les formules et les repères à retenir
  • Les erreurs fréquentes expliquées
  • Un exercice avec des aides et sa correction

L’accès gratuit comprend les cours et exercices de votre niveau choisi.

Sources

  • BO spécial n°1 du 22 janvier 2019 — programme de spécialité numérique et sciences informatiques de première, rubrique « Algorithmique »
  • BO spécial n°8 du 25 juillet 2019 — programme de spécialité numérique et sciences informatiques de terminale, rubrique « Algorithmique » (introduction)
  • T. H. Cormen, C. E. Leiserson, R. L. Rivest, C. Stein, Algorithmique (Introduction to Algorithms), 3e édition française, Dunod

Vous pensez avoir trouvé une erreur dans cette leçon ? Signalez-la par e-mail.

Explorer les autres cours

Accès rapide