Recherche dichotomique (Binary Search)
Étant donné un tableau trié tab[] de n éléments, écrivez une fonction pour rechercher un élément donné x dans tab[].
La recherche dichotomique (ou recherche binaire) est un algorithme de recherche qui permet de trouver la position d'une valeur cible dans un tableau trié.
Une approche simple consiste à effectuer une recherche linéaire (parcourir le tableau élément par élément). La complexité temporelle de cette approche est O(n).
La recherche dichotomique est beaucoup plus efficace avec une complexité O(log n), mais elle nécessite que le tableau soit préalablement trié.

Figure : Principe de la recherche dichotomique - à chaque étape, on élimine la moitié du tableau
La recherche dichotomique consiste à rechercher dans un tableau trié en divisant de manière récursive l'intervalle de recherche en deux. Commencez par un intervalle couvrant tout le tableau. Si la valeur de la clé de recherche est inférieure à l'élément situé au milieu de l'intervalle, limitez l'intervalle à la moitié inférieure. Sinon, le réduire à la moitié supérieure. Vérifiez à plusieurs reprises jusqu'à ce que la valeur soit trouvée ou que l'intervalle soit vide.
L'idée de la recherche dichotomique est de profiter du tableau trié et de réduire la complexité à O(log n), ce qui est exponentiellement plus rapide que la recherche linéaire O(n) pour de grands ensembles de données.
Implémentation récursive de la recherche dichotomique
Nous ignorons initialement la moitié des éléments juste après une seule comparaison.
- Comparez x avec l'élément du milieu.
- Si x correspond à l'élément du milieu, nous retournons l'indice du milieu.
- Sinon, si x est supérieur à l'élément milieu, alors x ne peut se situer que dans la moitié droite du sous-tableau après l'élément milieu.
- Sinon, recherchez dans la moitié gauche.
FONCTION RechercheDichotomique(tab, debut, fin, x):
SI fin >= debut ALORS
milieu ← (debut + fin) // 2
SI tab[milieu] == x ALORS
RETOURNER milieu
SINON SI tab[milieu] > x ALORS
RETOURNER RechercheDichotomique(tab, debut, milieu-1, x)
SINON
RETOURNER RechercheDichotomique(tab, milieu+1, fin, x)
FINSI
SINON
RETOURNER -1 // Élément non trouvé
FINSI
FINFONCTIONdef recherche_dichotomique_recursive(tab, debut, fin, x):
"""
Recherche récursive d'un élément x dans un tableau trié.
Paramètres:
tab: tableau trié
debut: indice de début de la recherche
fin: indice de fin de la recherche
x: élément recherché
Retourne:
L'indice de l'élément s'il est trouvé, -1 sinon
"""
if fin >= debut:
milieu = (debut + fin) // 2
# Élément trouvé au milieu
if tab[milieu] == x:
return milieu
# Si x est plus petit, chercher dans la moitié gauche
elif tab[milieu] > x:
return recherche_dichotomique_recursive(tab, debut, milieu - 1, x)
# Sinon, chercher dans la moitié droite
else:
return recherche_dichotomique_recursive(tab, milieu + 1, fin, x)
# Élément non trouvé
return -1
# Test de la fonction
tab = [2, 7, 8, 20, 25, 30, 33, 39, 45, 50]
x = 8
resultat = recherche_dichotomique_recursive(tab, 0, len(tab) - 1, x)
if resultat != -1:
print(f"L'élément {x} est présent à l'indice {resultat}")
else:
print(f"L'élément {x} n'est pas présent dans le tableau")L'élément 8 est présent à l'indice 2
Implémentation itérative de la recherche dichotomique
La version itérative utilise une boucle while au lieu de la récursion, ce qui évite l'utilisation de la pile d'appels et peut être plus efficace en termes de mémoire.
def recherche_dichotomique_iterative(tab, x):
"""
Recherche itérative d'un élément x dans un tableau trié.
Paramètres:
tab: tableau trié
x: élément recherché
Retourne:
L'indice de l'élément s'il est trouvé, -1 sinon
"""
debut = 0
fin = len(tab) - 1
while debut <= fin:
milieu = (debut + fin) // 2
if tab[milieu] == x:
return milieu
elif tab[milieu] < x:
# Chercher dans la moitié droite
debut = milieu + 1
else:
# Chercher dans la moitié gauche
fin = milieu - 1
# Élément non trouvé
return -1
# Test de la fonction
tab = [2, 7, 8, 20, 25, 30, 33, 39, 45, 50]
x = 8
resultat = recherche_dichotomique_iterative(tab, x)
if resultat != -1:
print(f"L'élément {x} est présent à l'indice {resultat}")
else:
print(f"L'élément {x} n'est pas présent dans le tableau")
# Test avec un élément absent
x = 15
resultat = recherche_dichotomique_iterative(tab, x)
if resultat != -1:
print(f"L'élément {x} est présent à l'indice {resultat}")
else:
print(f"L'élément {x} n'est pas présent dans le tableau")L'élément 8 est présent à l'indice 2 L'élément 15 n'est pas présent dans le tableau
Analyse de complexité
| Algorithme | Meilleur cas | Cas moyen | Pire cas | Espace mémoire |
|---|---|---|---|---|
| Recherche linéaire | O(1) (premier élément) | O(n) | O(n) (dernier élément ou absent) | O(1) |
| Recherche dichotomique (récursive) | O(1) (milieu) | O(log n) | O(log n) | O(log n) (pile d'appels) |
| Recherche dichotomique (itérative) | O(1) (milieu) | O(log n) | O(log n) | O(1) |
Pour la version récursive, la relation de récurrence est : T(n) = T(n/2) + O(1)
En appliquant le théorème maître (cas 2), on obtient T(n) = O(log n).
Exemple d'exécution pas à pas
Exemple n°1 : Recherche de 8 dans [2, 7, 8, 20, 25, 30, 33, 39, 45, 50]
| Étape | debut | fin | milieu | tab[milieu] | Action |
|---|---|---|---|---|---|
| 1 | 0 | 9 | 4 | 25 | 25 > 8 → chercher à gauche |
| 2 | 0 | 3 | 1 | 7 | 7 < 8 → chercher à droite |
| 3 | 2 | 3 | 2 | 8 | Trouvé ! |
Exemple n°2 : Recherche de 15 dans le même tableau (non trouvé)
| Étape | debut | fin | milieu | tab[milieu] | Action |
|---|---|---|---|---|---|
| 1 | 0 | 9 | 4 | 25 | 25 > 15 → chercher à gauche |
| 2 | 0 | 3 | 1 | 7 | 7 < 15 → chercher à droite |
| 3 | 2 | 3 | 2 | 8 | 8 < 15 → chercher à droite |
| 4 | 3 | 3 | 3 | 20 | 20 > 15 → chercher à gauche |
| 5 | 3 | 2 | debut > fin → élément non trouvé | ||
Comparaison : recherche linéaire vs dichotomique
| Critère | Recherche linéaire | Recherche dichotomique |
|---|---|---|
| Condition préalable | Aucune (tableau non trié accepté) | Tableau trié obligatoire |
| Complexité temporelle | O(n) | O(log n) |
| Complexité spatiale | O(1) | O(1) (itératif) ou O(log n) (récursif) |
| Facilité d'implémentation | Très simple | Moyenne |
| Performance pour n = 1000 | Jusqu'à 1000 comparaisons | Environ 10 comparaisons (log₂1000 ≈ 10) |
- Lorsque le tableau est déjà trié (ou peut être trié une fois pour plusieurs recherches)
- Pour les grandes quantités de données où O(n) serait trop lent
- Dans les applications où les performances sont critiques
La recherche dichotomique ne fonctionne pas sur un tableau non trié. Si vous l'appliquez à un tableau non trié, les résultats seront incorrects.
Variantes de la recherche dichotomique
Recherche de la première occurrence (lower bound)
def premier_occurrence(tab, x):
"""Trouve la première occurrence de x dans un tableau trié."""
debut, fin = 0, len(tab) - 1
resultat = -1
while debut <= fin:
milieu = (debut + fin) // 2
if tab[milieu] == x:
resultat = milieu
fin = milieu - 1 # Chercher encore à gauche
elif tab[milieu] < x:
debut = milieu + 1
else:
fin = milieu - 1
return resultatRecherche de la dernière occurrence (upper bound)
def derniere_occurrence(tab, x):
"""Trouve la dernière occurrence de x dans un tableau trié."""
debut, fin = 0, len(tab) - 1
resultat = -1
while debut <= fin:
milieu = (debut + fin) // 2
if tab[milieu] == x:
resultat = milieu
debut = milieu + 1 # Chercher encore à droite
elif tab[milieu] < x:
debut = milieu + 1
else:
fin = milieu - 1
return resultattab = [1, 2, 3, 3, 3, 4, 5, 5, 6] x = 3
Première occurrence: 2 Dernière occurrence: 4 Nombre d'occurrences: 3
- La recherche dichotomique est un algorithme efficace pour trouver un élément dans un tableau trié.
- Complexité temporelle : O(log n) – exponentiellement plus rapide que la recherche linéaire O(n).
- Deux implémentations possibles : récursive (élégante mais utilise la pile) et itérative (plus économe en mémoire).
- Principe : à chaque étape, on compare l'élément recherché avec l'élément du milieu et on élimine la moitié du tableau.
- Le tableau doit être trié au préalable – c'est la seule condition d'utilisation.
- Il existe des variantes pour trouver la première ou la dernière occurrence d'un élément.
- La recherche dichotomique est un excellent exemple de l'approche "diviser pour régner".
Discussion (0)
Soyez le premier à laisser un commentaire !
Laisser un commentaire
Votre commentaire sera visible après modération.