la recherche dichotomique

01 May 2019 01 May 2019 18249 vues ESSADDOUKI Mostafa 9 min de lecture

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[].

Définition

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é.

Schéma de recherche dichotomique

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

Principe de l'algorithme récursif

Nous ignorons initialement la moitié des éléments juste après une seule comparaison.

  1. Comparez x avec l'élément du milieu.
  2. Si x correspond à l'élément du milieu, nous retournons l'indice du milieu.
  3. 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.
  4. 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
FINFONCTION
def 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")
Sortie
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")
Sortie
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é

AlgorithmeMeilleur casCas moyenPire casEspace mémoire
Recherche linéaireO(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)
Relation de récurrence

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]

Étapedebutfinmilieutab[milieu]Action
10942525 > 8 → chercher à gauche
203177 < 8 → chercher à droite
32328Trouvé !

  Exemple n°2 : Recherche de 15 dans le même tableau (non trouvé)

Étapedebutfinmilieutab[milieu]Action
10942525 > 15 → chercher à gauche
203177 < 15 → chercher à droite
323288 < 15 → chercher à droite
43332020 > 15 → chercher à gauche
532debut > fin → élément non trouvé

Comparaison : recherche linéaire vs dichotomique

CritèreRecherche linéaireRecherche dichotomique
Condition préalableAucune (tableau non trié accepté)Tableau trié obligatoire
Complexité temporelleO(n)O(log n)
Complexité spatialeO(1)O(1) (itératif) ou O(log n) (récursif)
Facilité d'implémentationTrès simpleMoyenne
Performance pour n = 1000Jusqu'à 1000 comparaisonsEnviron 10 comparaisons (log₂1000 ≈ 10)
Quand utiliser la recherche dichotomique ?
  • 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
Attention !

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 resultat

Recherche 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 resultat
Exemple avec doublons
Entrée
tab = [1, 2, 3, 3, 3, 4, 5, 5, 6]
x = 3
Sortie
Première occurrence: 2
Dernière occurrence: 4
Nombre d'occurrences: 3
Points clés à retenir
  • 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".
Sortie
// La sortie apparaîtra ici…
Prêt · Ctrl+Entrée pour exécuter

Discussion (0)

Soyez le premier à laisser un commentaire !

Laisser un commentaire

Votre commentaire sera visible après modération.