Outils pour utilisateurs

Outils du site


nsi:terminales:recherche_dichotomique

Recherche dichotomique

On fournit un tableau d'items.

Besoin : pour une valeur needle donnée, chercher l'indice de sa première occurrence dans le tableau, si elle s'y trouve, sinon -1.

Précondition : un critère d'ordre est défini et le tableau doit être trié dans l'ordre croissant.

Principe : Le tableau contient n = len(tableau) items. les indices vont de 0 à n - 1.

  • On initialise a à 0 et b à n - 1.
  • Nous faisons en sorte que si needle est dans le tableau, sa première occurrence est toujours entre a et b (ce qui est vrai avec les valeurs initiales de a et b)
  • Nous faisons aussi en sorte que l'écart b - a se réduise d'au moins 1 à chaque étape de sorte que l'écart b - a finit forcément par être nul.
  • Les deux éléments précédents font qu'à la fin, si needle est dans le tableau, sa première occurrence est forcément a – la valeur de a finale.

Voyons comment nous faisons évoluer a et b :

  • On lit la valeur du tableau à l'indice au milieu entre a et b : en i_m = (a + b)//2.
  • Si cette valeur >= needle cela signifie que la première occurrence de needle est forcément sur la gauche de i_m ou éventuellement en i_m. On peut donc continuer à chercher sur [a;i_m] et donc on décide que : b = i_m
    On sait que i_m < b, en choisissant b = i_m on réduit b d'au moins 1 et donc b - a aussi.
  • Sinon, cela signifie que valeur < needle et que needle est strictement à droite de i_m. On peut donc continuer à chercher dans [i_m + 1 ; b]]. On décide donc a = i_m + 1
    Si on se contentait de a = i_m, dans certains cas a ne changerait pas et donc b - a ne diminuerait plus, ce qui ferait une boucle infinie.

Exemple :

tableau = [5, 7, 19, 21, 45, 45, 74]
n = len(tableau) # n = 7
needle = 45 # needle = aiguille, la valeur cherchée

# a et b délimitent la zone de recherche.
# On commence avec les bords du tableau : [0 ; 6]
a, b = 0, 6
i_m = (a + b) // 2 # i_m = 3

tableau[i_m] < needle # car tableau[i_m] = 21
# on peut continuer strictement sur la moitié droite
a = i_m + 14 # a passe à 4. La recherche continue sur [4 ; 6]

i_m = (a + b) // 2 # i_m = 5
tableau[i_m] >= needle # car tableau[i_m] = 45
# on peut continuer à gauche de 5
b = i_m # recherche continue sur [4;5]

i_m = (a + b) // 2 # i_m = 4
tableau[i_m] >= needle # car tableau[i_m] = 45
b = i_m # recherche continue sur [4;4]

# a == b pas besoin d'aller plus loin
# puisque tableau[a] == 45 == needle, la réponse est a = 4

La recherche de l'exemple s'est faite en 3 étapes ce qui correspond au fait que $7 < 2^3$. Si le tableau contenait $n = 1\,000\,000 < 2^{20}$ items, 20 étapes suffiraient.

À faire
Implémenter en Python un algorithme de recherche par dichotomie.

nsi/terminales/recherche_dichotomique.txt · Dernière modification : de goupillwiki