Ch. 04 · Leçon 1
Méthodes de recherche : séquentielle et dichotomique
Ce que vous saurez faire
- Comparer les approches séquentielle et dichotomique
- Implémenter les deux méthodes en Analyse et en Python
- Évaluer le coût de chaque méthode selon la taille du tableau
- Choisir la méthode adaptée selon les pré-requis (tri ou non)
Plan de cours
Trouver vite, c'est diviser
Chercher un élément dans un tableau est une opération omniprésente : un mot dans un dictionnaire, un produit dans un catalogue, un élève dans une liste. Selon la structure des données, deux méthodes s'opposent radicalement par leur efficacité.
Objectifs d'apprentissage
- Comparer séquentielle et dichotomique
- Implémenter les deux algorithmes
- Coût en fonction de n
- Choisir selon le contexte
Concepts clés
- Recherche séquentielle — parcours linéaire,
O(n). - Recherche dichotomique — par division,
O(log n), exige un tableau trié. - Comparaison de coût — 1 M éléments → 1 M vs 20 comparaisons.
- Trade-off du tri — vaut-il la peine de trier avant ?
Avant de commencer — qu'est-ce que vous savez déjà ?
- Q1. Comment cherchez-vous un mot dans un dictionnaire papier ? Pas du tout au hasard, j'imagine. Pourquoi ?
- Q2. Pour chercher 17 dans
[3, 7, 12, 17, 22, 29, 35], pouvez-vous utiliser une stratégie « plus efficace » que parcourir un par un ? - Q3. Quel est le pire cas pour la recherche séquentielle ?
1. Le contenu du cours
1.1 Recherche séquentielle
Fonction recherche_sequentielle(t : tableau de entier ; cible : entier) → entier
Pour i De 0 À long(t) - 1 Faire
Si t[i] = cible Alors
Retourner(i)
FinSi
FinPour
Retourner(-1)
FinFonction
def recherche_sequentielle(t: list[int], cible: int) -> int:
for i in range(len(t)):
if t[i] == cible:
return i
return -1
Coût
- Meilleur cas : élément en position 0 → 1 comparaison.
- Pire cas : élément absent ou en dernière position →
ncomparaisons. - Moyenne :
n / 2comparaisons.
On parle de complexité linéaire O(n) : le coût croît proportionnellement à la taille du tableau.
Avantage
- Aucune contrainte sur le tableau (non trié, valeurs en doublon, types variés).
- Simple à coder, peu d'erreurs possibles.
1.2 Recherche dichotomique (ou binaire)
Fonction recherche_dichotomique(t : tableau trié ; cible : entier) → entier
gauche ← 0
droite ← long(t) - 1
Tant que gauche ≤ droite Faire
milieu ← (gauche + droite) div 2
Si t[milieu] = cible Alors
Retourner(milieu)
Sinon
Si t[milieu] < cible Alors
gauche ← milieu + 1
Sinon
droite ← milieu - 1
FinSi
FinSi
FinTantQue
Retourner(-1)
FinFonction
def recherche_dichotomique(t: list[int], cible: int) -> int:
gauche = 0
droite = len(t) - 1
while gauche <= droite:
milieu = (gauche + droite) // 2
if t[milieu] == cible:
return milieu
elif t[milieu] < cible:
gauche = milieu + 1
else:
droite = milieu - 1
return -1
Visualisation — cas générique
Chercher 22 dans [3, 7, 12, 17, 22, 29, 35] (indices 0 à 6) :
| Étape | gauche | droite | milieu | t[milieu] | Action |
|---|---|---|---|---|---|
| 1 | 0 | 6 | 3 | 17 | 17 < 22 → gauche = 4 |
| 2 | 4 | 6 | 5 | 29 | 29 > 22 → droite = 4 |
| 3 | 4 | 4 | 4 | 22 | égal → retourne 4 |
3 étapes pour un tableau de 7 éléments — à comparer aux 5 étapes qu'aurait demandé une recherche séquentielle (parcours 3 → 7 → 12 → 17 → 22). Le gain est déjà visible sur un petit exemple ; il devient écrasant pour 1 000 ou 1 000 000 d'éléments.
Cas chanceux — la cible est pile au milieu
Chercher 17 dans le même tableau :
| Étape | gauche | droite | milieu | t[milieu] | Comparaison |
|---|---|---|---|---|---|
| 1 | 0 | 6 | 3 | 17 | égal → retourne 3 |
1 seule comparaison suffit ! C'est le meilleur cas de la dichotomie. Au pire cas, on fait log₂(n) étapes — pour 1 000 000 d'éléments, au plus 20 comparaisons.
Cas absent : chercher 13
| Étape | gauche | droite | milieu | t[milieu] | Action |
|---|---|---|---|---|---|
| 1 | 0 | 6 | 3 | 17 | 17 > 13 → droite = 2 |
| 2 | 0 | 2 | 1 | 7 | 7 < 13 → gauche = 2 |
| 3 | 2 | 2 | 2 | 12 | 12 < 13 → gauche = 3 |
| 4 | 3 | 2 | — | — | gauche > droite → retourne -1 |
Coût
- À chaque étape, l'intervalle est divisé par 2.
- Pour
néléments, le nombre d'étapes est environlog₂(n). - Complexité logarithmique O(log n).
1.3 Comparaison chiffrée
Taille n | Séquentielle (pire cas) | Dichotomique |
|---|---|---|
| 10 | 10 | 4 |
| 100 | 100 | 7 |
| 1 000 | 1 000 | 10 |
| 10 000 | 10 000 | 14 |
| 1 000 000 | 1 000 000 | 20 |
| 1 000 000 000 | 1 milliard | 30 |
Sur 1 million d'éléments, la dichotomie est 50 000 fois plus rapide.
1.4 Trace : dichotomique pas-à-pas
Chercher 42 dans [3, 8, 15, 22, 30, 42, 51, 65, 78] :
| N° | Instruction | gauche | droite | milieu |
|---|---|---|---|---|
| 01 | ··· | ? | ? | ? |
| 02 | ··· | ? | ? | ? |
| 03 | ··· | ? | ? | ? |
| 04 | ··· | ? | ? | ? |
| 05 | ··· | ? | ? | ? |
| 06 | ··· | ? | ? | ? |
2. Exercices pratiques
Niveau Débutant — Type bac courant
Écrire une fonction premier_negatif(t) qui retourne l'indice du premier élément négatif d'un tableau, ou -1 s'il n'y en a aucun.
Voir le corrigé
def premier_negatif(t: list[int]) -> int:
for i in range(len(t)):
if t[i] < 0:
return i
return -1
print(premier_negatif([3, 7, -2, 5, -8])) # 2
print(premier_negatif([1, 2, 3])) # -1
Variante de la recherche séquentielle où la condition de match est t[i] < 0 au lieu de t[i] == cible.
Niveau Intermédiaire — Type bac difficile
Écrire une fonction toutes_les_occurrences(t, cible) qui retourne la liste de tous les indices où cible apparaît.
Voir le corrigé
def toutes_les_occurrences(t: list[int], cible: int) -> list[int]:
indices = []
for i in range(len(t)):
if t[i] == cible:
indices.append(i)
return indices
print(toutes_les_occurrences([1, 3, 5, 3, 7, 3], 3)) # [1, 3, 5]
Pourquoi pas dichotomique ? La dichotomie retourne une position arbitraire (celle du milieu trouvée en premier). Pour énumérer toutes les occurrences, il faudrait étendre l'algorithme — plus complexe. La séquentielle est ici plus naturelle.
Niveau Avancé — Hors bac (bonus)
Implémenter la recherche dichotomique en deux versions :
- Itérative (avec
Tant que). - Récursive (la fonction s'appelle elle-même).
Comparer les deux : laquelle est plus lisible, laquelle est plus efficace en mémoire ?
Voir le corrigé
Version itérative (déjà vue)
def dicho_iter(t: list[int], cible: int) -> int:
g, d = 0, len(t) - 1
while g <= d:
m = (g + d) // 2
if t[m] == cible:
return m
elif t[m] < cible:
g = m + 1
else:
d = m - 1
return -1
Version récursive
def dicho_rec(t: list[int], cible: int, g: int = 0, d: int = -1) -> int:
if d == -1:
d = len(t) - 1
if g > d:
return -1
m = (g + d) // 2
if t[m] == cible:
return m
elif t[m] < cible:
return dicho_rec(t, cible, m + 1, d)
else:
return dicho_rec(t, cible, g, m - 1)
print(dicho_rec([3, 8, 15, 22, 30, 42, 51, 65, 78], 42)) # 5
Comparaison
| Critère | Itérative | Récursive |
|---|---|---|
| Lisibilité | Plus claire pour qui débute | Plus élégante mathématiquement |
| Mémoire | Constante O(1) | O(log n) (pile d'appels) |
| Vitesse | Légèrement plus rapide | Coût des appels de fonction |
| Recommandation | À utiliser en pratique | À comprendre pour l'esprit |
Au bac : la version itérative est attendue. La récursive est un bonus, hors programme officiel mais utile à comprendre pour anticiper la suite des études.
⚠️ Erreurs fréquentes au bac
Avant le quiz, mémorisez ces pièges classiques qui font perdre des points :
- Erreur 1. Appliquer la dichotomie sur un tableau non trié → résultats faux (pas une erreur d'exécution, juste un mauvais résultat).
- Erreur 2. Initialiser
gauche = 1au lieu de0en Python. Décalage classique d'un cran. - Erreur 3. Boucle
Tant que gauche < droiteau lieu degauche ≤ droite. Rate le cas où l'élément est à l'indice où g et d se rejoignent. - Erreur 4. Oublier de retourner
-1(ou une valeur signalant l'absence) quand l'élément n'est pas trouvé.
3. Quiz de vérification
Méthodes de recherche (5 questions)
Quel est le pré-requis indispensable de la recherche dichotomique ?
Pour un tableau de 1024 éléments triés, combien d'étapes maximum pour la recherche dichotomique ?
La recherche séquentielle est en O(...) ?
Si vous devez faire UNE seule recherche dans un tableau non trié, vous choisissez :
Dans la dichotomie, comment calcule-t-on l'indice milieu ?
En résumé
- ✅ Séquentielle :
O(n), pas de pré-requis. - ✅ Dichotomique :
O(log n), tableau trié obligatoire. - ✅ Sur 1 M d'éléments : séquentielle = 1 M comparaisons vs dichotomique = 20.
- ✅ Tri préalable rentable si on fait beaucoup de recherches.
Prochaine leçon : Méthodes de tri — sélection, bulles, insertion. Comment trier pour pouvoir ensuite chercher en dichotomie.