Chapitre 13 — Algorithmes de recherche
Localiser efficacement une valeur dans un ensemble de données
Fiche pédagogique du chapitre
Objectifs d’apprentissage
À la fin de ce chapitre, l’étudiant devra être capable de :
- définir le problème de recherche d’une valeur dans un tableau ;
- distinguer la présence, la position et le nombre d’occurrences d’une valeur ;
- concevoir une recherche séquentielle avec ou sans arrêt anticipé ;
- rechercher toutes les occurrences d’une valeur ;
- construire et tracer une recherche dichotomique ;
- expliquer pourquoi la recherche dichotomique exige un tableau trié ;
- calculer correctement l’indice du milieu ;
- mettre à jour les bornes gauche et droite sans perdre de valeur possible ;
- écrire les versions itérative et récursive de la recherche dichotomique ;
- comparer les méthodes selon le nombre d’opérations, la taille des données et leur organisation ;
- identifier les cas favorables, moyens et défavorables ;
- choisir la méthode de recherche adaptée à une situation donnée ;
- élaborer des jeux d’essai et détecter les erreurs de bornes.
Prérequis
- maîtriser les variables, conditions et boucles ;
- savoir déclarer et parcourir un tableau à une dimension ;
- connaître les fonctions, les paramètres et les valeurs de retour ;
- comprendre la division entière ;
- savoir construire une table de trace ;
- connaître le principe d’un appel récursif.
Plan du chapitre
13.1 Recherche séquentielle
13.2 Recherche dichotomique
13.3 Comparaison des méthodes
Applications, tables de trace, travaux dirigés, corrigés et synthèse
Organisation pédagogique indicative
Activité | Durée indicative | Objectif principal |
|---|---|---|
| Cours | 3 h | Comprendre les deux méthodes et leurs conditions d’utilisation. |
| Travaux dirigés | 3 h | Tracer les recherches et corriger les erreurs de bornes. |
| Travaux pratiques | 3 h | Implémenter, tester et comparer les algorithmes. |
| Travail personnel | 2 h | Construire des jeux d’essai et analyser le nombre de comparaisons. |
| Idée centrale : une recherche efficace ne dépend pas seulement de l’algorithme. Elle dépend aussi de l’organisation des données, notamment du fait que le tableau soit trié ou non. |
Introduction aux algorithmes de recherche
Rechercher une information est une opération fondamentale en informatique. Un programme peut avoir besoin de vérifier l’existence d’un identifiant, de retrouver une note, de localiser un produit, de déterminer la position d’un nom ou de compter le nombre d’apparitions d’une valeur.
Le problème étudié dans ce chapitre consiste à rechercher une valeur appelée clé dans un tableau. Selon le besoin, l’algorithme peut retourner un booléen, l’indice de la première occurrence, la liste de toutes les positions ou le nombre d’occurrences.
Question posée | Résultat attendu | Exemple |
|---|---|---|
| La valeur existe-t-elle ? | Vrai ou Faux | La note 15 est-elle présente ? |
| Où se trouve la valeur ? | Un indice ou -1 | À quel indice se trouve « Sara » ? |
| Combien de fois apparaît-elle ? | Un compteur | Combien de notes égales à 10 ? |
| Où sont toutes ses occurrences ? | Une collection d’indices | Positions de toutes les valeurs 0. |
Deux stratégies seront étudiées. La recherche séquentielle examine les éléments dans leur ordre de stockage et fonctionne sur tout tableau. La recherche dichotomique élimine la moitié de la zone restante à chaque étape, mais elle n’est correcte que si les données sont triées selon un ordre compatible avec les comparaisons.
| Convention utilisée : les indices commencent à 0. Un résultat égal à -1 signifie que la valeur recherchée n’a pas été trouvée. |
13.1 Recherche séquentielle
13.1.1 Principe
La recherche séquentielle, également appelée recherche linéaire, consiste à comparer la clé recherchée avec les éléments du tableau, l’un après l’autre. Le parcours commence généralement au premier élément et avance jusqu’à la découverte de la valeur ou jusqu’à la fin du tableau.
Cette méthode ne suppose aucun ordre particulier. Elle peut donc être appliquée à un tableau trié, non trié, partiellement rempli ou contenant des doublons.
Étape | Action |
|---|---|
| 1 | Initialiser l’indice au début du tableau. |
| 2 | Comparer l’élément courant à la valeur recherchée. |
| 3 | Si les valeurs sont égales, signaler la réussite. |
| 4 | Sinon, passer à l’élément suivant. |
| 5 | Si la fin est atteinte, signaler l’absence de la valeur. |
13.1.2 Parcours complet du tableau
Un parcours complet examine tous les éléments. Il est nécessaire lorsque l’objectif est de compter les occurrences, de trouver toutes les positions ou de vérifier une propriété portant sur l’ensemble du tableau.
Recherche de l’existence par parcours complet
| Fonction Existe(T : Tableau, n : Entier, x : Réel) : Booléen Variables i : Entier trouve : Booléen Début trouve ← Faux Pour i allant de 0 à n - 1 Faire Si T[i] = x Alors trouve ← Vrai FinSi FinPour Retourner trouve Fin |
Cette version reste correcte, mais elle continue à comparer les éléments après avoir trouvé la valeur. Lorsque seule l’existence ou la première position est demandée, un arrêt anticipé évite des opérations inutiles.
13.1.3 Arrêt dès que l’élément est trouvé
L’arrêt anticipé termine la recherche à la première occurrence. Il améliore le comportement dans les cas favorables, notamment lorsque la valeur se trouve près du début du tableau.
Version avec boucle TantQue
| Fonction RechercherPremier(T : Tableau, n : Entier, x : Réel) : Entier Variables i : Entier Début i ← 0 TantQue i < n ET T[i] ≠ x Faire i ← i + 1 FinTantQue Si i < n Alors Retourner i Sinon Retourner -1 FinSi Fin |
| Ordre de la condition : il faut vérifier i < n avant d’accéder à T[i]. Lorsque i = n, l’indice est en dehors du tableau. |
Tableau T | Clé x | Comparaisons | Résultat |
|---|---|---|---|
| [8, 3, 12, 5, 9] | 8 | 1 | 0 |
| [8, 3, 12, 5, 9] | 5 | 4 | 3 |
| [8, 3, 12, 5, 9] | 9 | 5 | 4 |
| [8, 3, 12, 5, 9] | 7 | 5 | -1 |
| [] | 7 | 0 | -1 |
13.1.4 Table de trace détaillée
Considérons T = [14, 7, 22, 7, 31] et x = 22. La boucle s’arrête lorsque l’indice 2 est atteint.
Itération | i avant test | i < n | T[i] ≠ 22 | Action |
|---|---|---|---|---|
| 1 | 0 | Vrai | 14 ≠ 22 : Vrai | i ← 1 |
| 2 | 1 | Vrai | 7 ≠ 22 : Vrai | i ← 2 |
| 3 | 2 | Vrai | 22 ≠ 22 : Faux | Sortie de la boucle |
| Après la boucle | 2 | 2 < 5 : Vrai | — | Retourner 2 |
La valeur 7 apparaît deux fois, mais une recherche de la première occurrence retourne l’indice 1 et ne poursuit pas jusqu’à l’indice 3.
13.1.5 Recherche de toutes les occurrences
Lorsque le tableau peut contenir des doublons, la première occurrence ne suffit pas toujours. Il faut alors parcourir tout le tableau et traiter chaque égalité.
Afficher toutes les positions
| Procédure AfficherOccurrences(T : Tableau, n : Entier, x : Réel) Variables i, compteur : Entier Début compteur ← 0 Pour i allant de 0 à n - 1 Faire Si T[i] = x Alors Afficher("Occurrence à l’indice ", i) compteur ← compteur + 1 FinSi FinPour Si compteur = 0 Alors Afficher("Valeur absente") Sinon Afficher("Nombre d’occurrences : ", compteur) FinSi Fin |
Indice | 0 | 1 | 2 | 3 | 4 | 5 |
|---|---|---|---|---|---|---|
T | 4 | 9 | 4 | 2 | 4 | 7 |
T[i] = 4 ? | Oui | Non | Oui | Non | Oui | Non |
Les occurrences de 4 se trouvent aux indices 0, 2 et 4. Le compteur final vaut 3.
13.1.6 Retourner les positions dans un tableau
Si les positions doivent être réutilisées, elles peuvent être enregistrées dans un second tableau. Celui-ci possède au maximum n éléments, puisque chaque case du tableau d’origine peut correspondre à une occurrence.
Construire le tableau des positions
| Fonction Positions(T : Tableau, n : Entier, x : Réel, P : Tableau) : Entier Variables i, k : Entier Début k ← 0 Pour i allant de 0 à n - 1 Faire Si T[i] = x Alors P[k] ← i k ← k + 1 FinSi FinPour Retourner k Fin // Les positions valides sont P[0] à P[k - 1]. |
| Remarque : la fonction retourne le nombre de positions écrites. Ce nombre permet de distinguer la partie utile du tableau P de sa capacité totale. |
13.1.7 Recherche à partir d’une position
Dans certaines applications, on souhaite chercher la prochaine occurrence après une position donnée. Le point de départ devient alors un paramètre.
Rechercher à partir de debut
| Fonction RechercherDepuis(T : Tableau, n : Entier, x : Réel, debut : Entier) : Entier Variables i : Entier Début Si debut < 0 OU debut > n Alors Retourner -1 FinSi i ← debut TantQue i < n ET T[i] ≠ x Faire i ← i + 1 FinTantQue Si i < n Alors Retourner i Sinon Retourner -1 FinSi Fin |
Cette fonction peut être appelée plusieurs fois afin de parcourir les occurrences successives sans recommencer systématiquement à l’indice 0.
13.1.8 Recherche avec sentinelle
La technique de la sentinelle place temporairement la valeur recherchée dans une case supplémentaire située après la partie utile du tableau. Elle simplifie la condition de boucle, mais elle exige une capacité disponible et la restauration éventuelle de la case utilisée.
Principe de la sentinelle
| Fonction RechercheSentinelle(T : Tableau, n : Entier, x : Réel) : Entier Variables i : Entier Début T[n] ← x // Une case supplémentaire doit exister. i ← 0 TantQue T[i] ≠ x Faire i ← i + 1 FinTantQue Si i < n Alors Retourner i Sinon Retourner -1 FinSi Fin |
Cette variante est présentée pour la culture algorithmique. Dans un programme réel, elle doit être utilisée avec prudence afin de ne pas écrire en dehors de la capacité du tableau.
13.1.9 Version récursive
Une recherche séquentielle peut aussi être formulée récursivement. Le paramètre i indique la prochaine case à examiner.
Recherche séquentielle récursive
| Fonction RechercheSeqRec(T : Tableau, n : Entier, x : Réel, i : Entier) : Entier Début Si i = n Alors Retourner -1 SinonSi T[i] = x Alors Retourner i Sinon Retourner RechercheSeqRec(T, n, x, i + 1) FinSi Fin // Appel initial : RechercheSeqRec(T, n, x, 0) |
Cette version réalise les mêmes comparaisons que la version itérative, mais elle utilise un appel de fonction par élément examiné. La boucle est généralement plus adaptée à ce problème simple.
13.1.10 Cas particuliers et validation
Situation | Comportement attendu |
|---|---|
| Tableau vide | Retourner -1, Faux ou 0 selon le résultat demandé. |
| Valeur au premier indice | Arrêt après une seule comparaison. |
| Valeur au dernier indice | Examen de toutes les cases. |
| Valeur absente | Examen de toutes les cases. |
| Plusieurs occurrences | Préciser si l’on cherche la première, la dernière ou toutes. |
| n supérieur à la capacité | Entrée incorrecte à refuser. |
| Types incompatibles | La comparaison doit être définie pour les valeurs concernées. |
| Contrat recommandé : 0 ≤ n ≤ capacité du tableau. La valeur x doit être comparable aux éléments de T. |
13.2 Recherche dichotomique
13.2.1 Principe de division de l’espace de recherche
La recherche dichotomique, aussi appelée recherche binaire, exploite l’ordre des données. Elle compare la clé à l’élément situé au milieu de la zone encore possible. Selon le résultat, elle conserve la moitié gauche ou la moitié droite et élimine l’autre moitié.
L’espace de recherche est donc approximativement divisé par deux à chaque étape. Une grande quantité de données peut être éliminée après très peu de comparaisons.
Comparaison avec T[milieu] | Conclusion | Nouvelle zone |
|---|---|---|
| x = T[milieu] | La valeur est trouvée. | Arrêt |
| x < T[milieu] | x ne peut pas être à droite. | gauche à milieu - 1 |
| x > T[milieu] | x ne peut pas être à gauche. | milieu + 1 à droite |
13.2.2 Condition indispensable : tableau trié
La décision d’éliminer une moitié repose sur l’ordre du tableau. Dans un tableau trié par ordre croissant, toutes les valeurs situées à gauche du milieu sont inférieures ou égales à l’élément central, tandis que celles de droite sont supérieures ou égales.
Si le tableau n’est pas trié, une valeur plus petite que l’élément central peut se trouver à droite. L’élimination d’une moitié n’est alors plus justifiée et l’algorithme peut conclure à tort que la valeur est absente.
Tableau | Trié ? | Recherche dichotomique correcte ? |
|---|---|---|
| [2, 5, 8, 12, 19, 24] | Oui, croissant | Oui |
| [24, 19, 12, 8, 5, 2] | Oui, décroissant | Oui, avec comparaisons adaptées |
| [2, 19, 5, 24, 8, 12] | Non | Non |
| [3, 3, 4, 4, 4, 9] | Oui, avec doublons | Oui, mais l’occurrence trouvée n’est pas forcément la première |
| Point essentiel : trier uniquement pour effectuer une seule petite recherche peut coûter plus cher qu’une recherche séquentielle. Le tri devient intéressant lorsque les données restent ordonnées ou lorsque de nombreuses recherches sont prévues. |
13.2.3 Bornes de la zone de recherche
La version présentée utilise un intervalle fermé : les indices gauche et droite appartiennent tous les deux à la zone encore possible. Au départ, gauche = 0 et droite = n - 1. La zone est vide lorsque gauche > droite.
Variable | Signification | Valeur initiale |
|---|---|---|
| gauche | Premier indice encore possible | 0 |
| droite | Dernier indice encore possible | n - 1 |
| milieu | Indice central de la zone | (gauche + droite) DIV 2 |
Il existe aussi des formulations utilisant un intervalle semi-ouvert [gauche, droite[. Elles sont correctes si les conditions et mises à jour restent cohérentes. Mélanger les deux conventions produit fréquemment des erreurs.
13.2.4 Calcul de l’indice du milieu
Avec des indices entiers, le milieu est calculé par division entière. La formule simple est : milieu ← (gauche + droite) DIV 2.
Formule recommandée dans les langages à entiers bornés
| milieu ← gauche + (droite - gauche) DIV 2 |
Cette seconde écriture évite que l’addition gauche + droite dépasse la valeur maximale du type entier lorsque les indices sont très grands. Dans le cadre des exercices, les deux formules donnent le même indice.
gauche | droite | (gauche + droite) DIV 2 | Zone |
|---|---|---|---|
| 0 | 8 | 4 | 9 éléments |
| 0 | 7 | 3 | 8 éléments |
| 4 | 9 | 6 | 6 éléments |
| 5 | 5 | 5 | 1 élément |
13.2.5 Mise à jour des bornes
Après une comparaison infructueuse, l’élément du milieu est exclu de la nouvelle zone, puisqu’il vient d’être vérifié. Il faut donc utiliser milieu - 1 ou milieu + 1. Réutiliser milieu sans le dépasser peut empêcher la zone de diminuer et provoquer une boucle infinie.
Règles de mise à jour
| Si x < T[milieu] Alors droite ← milieu - 1 Sinon gauche ← milieu + 1 FinSi |
| Erreur fréquente : écrire droite ← milieu ou gauche ← milieu peut conserver exactement la même zone lorsque deux indices seulement restent à examiner. |
13.2.6 Version itérative
Recherche dichotomique itérative
| Fonction RechercheDichotomique(T : Tableau, n : Entier, x : Réel) : Entier Variables gauche, droite, milieu : Entier Début gauche ← 0 droite ← n - 1 TantQue gauche ≤ droite Faire milieu ← gauche + (droite - gauche) DIV 2 Si T[milieu] = x Alors Retourner milieu SinonSi x < T[milieu] Alors droite ← milieu - 1 Sinon gauche ← milieu + 1 FinSi FinTantQue Retourner -1 Fin |
Le retour immédiat simplifie la lecture : dès que l’égalité est rencontrée, aucune autre comparaison n’est nécessaire. Si la boucle se termine, la zone est vide et la valeur est absente.
13.2.7 Traçage d’une recherche réussie
Considérons le tableau trié T = [3, 6, 9, 12, 15, 18, 21, 24, 27] et la recherche de x = 21.
Étape | gauche | droite | milieu | T[milieu] | Décision |
|---|---|---|---|---|---|
| 1 | 0 | 8 | 4 | 15 | 21 > 15 : gauche ← 5 |
| 2 | 5 | 8 | 6 | 21 | Valeur trouvée à l’indice 6 |
Seules deux comparaisons principales sont nécessaires, alors qu’une recherche séquentielle depuis le début aurait examiné sept éléments.
13.2.8 Traçage d’une recherche infructueuse
Recherchons maintenant x = 20 dans le même tableau.
Étape | gauche | droite | milieu | T[milieu] | Décision |
|---|---|---|---|---|---|
| 1 | 0 | 8 | 4 | 15 | 20 > 15 : gauche ← 5 |
| 2 | 5 | 8 | 6 | 21 | 20 < 21 : droite ← 5 |
| 3 | 5 | 5 | 5 | 18 | 20 > 18 : gauche ← 6 |
| Fin | 6 | 5 | — | — | gauche > droite : retourner -1 |
L’intervalle devient vide sans que toutes les cases soient examinées. L’ordre du tableau permet de conclure que 20 ne peut se trouver ailleurs.
13.2.9 Version récursive
La version récursive reçoit les bornes de la zone courante. Son cas de base d’échec correspond à gauche > droite. Chaque appel réduit la taille de l’intervalle.
Recherche dichotomique récursive
| Fonction RechercheDichoRec(T : Tableau, x : Réel, gauche, droite : Entier) : Entier Variables milieu : Entier Début Si gauche > droite Alors Retourner -1 FinSi milieu ← gauche + (droite - gauche) DIV 2 Si T[milieu] = x Alors Retourner milieu SinonSi x < T[milieu] Alors Retourner RechercheDichoRec(T, x, gauche, milieu - 1) Sinon Retourner RechercheDichoRec(T, x, milieu + 1, droite) FinSi Fin // Appel initial : RechercheDichoRec(T, x, 0, n - 1) |
Élément récursif | Interprétation |
|---|---|
| Cas de base | gauche > droite : la zone est vide. |
| Cas de réussite | T[milieu] = x. |
| Progression à gauche | La borne droite devient milieu - 1. |
| Progression à droite | La borne gauche devient milieu + 1. |
| Mesure qui diminue | Nombre d’indices compris entre gauche et droite. |
13.2.10 Tableau contenant des doublons
Une recherche dichotomique classique retourne une occurrence quelconque. Pour trouver la première occurrence, il faut continuer la recherche dans la moitié gauche même après une égalité. Pour trouver la dernière, on continue dans la moitié droite.
Première occurrence par recherche dichotomique
| Fonction PremiereOccurrence(T : Tableau, n : Entier, x : Réel) : Entier Variables gauche, droite, milieu, resultat : Entier Début gauche ← 0 droite ← n - 1 resultat ← -1 TantQue gauche ≤ droite Faire milieu ← gauche + (droite - gauche) DIV 2 Si T[milieu] = x Alors resultat ← milieu droite ← milieu - 1 SinonSi x < T[milieu] Alors droite ← milieu - 1 Sinon gauche ← milieu + 1 FinSi FinTantQue Retourner resultat Fin |
Tableau | x | Recherche classique | Première occurrence |
|---|---|---|---|
| [2, 4, 4, 4, 7, 9] | 4 | Peut retourner 2 ou un autre indice égal | Retourne 1 |
| [1, 1, 1, 1] | 1 | Occurrence quelconque | Retourne 0 |
| [2, 4, 6] | 5 | -1 | -1 |
13.2.11 Recherche dans un tableau trié décroissant
La méthode reste applicable à un tableau trié par ordre décroissant, mais les décisions doivent être inversées. Si x est inférieur à T[milieu], il faut chercher à droite, là où se trouvent les valeurs plus petites.
Règle pour un ordre décroissant
| Si T[milieu] = x Alors Retourner milieu SinonSi x < T[milieu] Alors gauche ← milieu + 1 Sinon droite ← milieu - 1 FinSi |
| Cohérence de l’ordre : la fonction de comparaison utilisée par la recherche doit être la même que celle utilisée pour trier le tableau. |
13.2.12 Erreurs fréquentes
Erreur | Conséquence | Correction |
|---|---|---|
| Appliquer l’algorithme à un tableau non trié | Résultat incorrect possible. | Vérifier ou garantir le tri. |
| Initialiser droite à n | Accès possible à T[n], hors limites. | Utiliser droite ← n - 1 pour un intervalle fermé. |
| Utiliser gauche < droite | La dernière case peut ne pas être testée. | Utiliser gauche ≤ droite. |
| Ne pas exclure milieu | La zone peut ne plus diminuer. | Employer milieu - 1 ou milieu + 1. |
| Mélanger ordre croissant et décroissant | Mauvaise moitié conservée. | Adapter les comparaisons à l’ordre. |
| Supposer que l’occurrence trouvée est la première | Résultat insuffisant avec doublons. | Utiliser une variante dédiée. |
13.3 Comparaison des méthodes
13.3.1 Nombre d’opérations
L’opération principale est la comparaison entre la clé et un élément du tableau. Le nombre de comparaisons dépend de la position de la valeur, de son absence éventuelle et de la méthode utilisée.
Méthode | Cas favorable | Cas défavorable | Idée de croissance |
|---|---|---|---|
| Recherche séquentielle | 1 comparaison | n comparaisons | Le travail peut croître proportionnellement à n. |
| Recherche dichotomique | 1 comparaison | Environ log₂(n) + 1 comparaisons | La zone est divisée par deux. |
La notation O(n) pour la recherche séquentielle et O(log n) pour la recherche dichotomique sera approfondie dans le chapitre consacré à la complexité. À ce stade, il suffit de retenir que doubler la taille double approximativement le pire travail séquentiel, tandis qu’il ajoute environ une étape à la recherche dichotomique.
Nombre d’éléments n | Maximum séquentiel | Maximum dichotomique approximatif |
|---|---|---|
| 8 | 8 | 4 |
| 16 | 16 | 5 |
| 32 | 32 | 6 |
| 1 024 | 1 024 | 11 |
| 1 000 000 | 1 000 000 | Environ 20 |
13.3.2 Influence de la taille des données
Pour un très petit tableau, la simplicité de la recherche séquentielle peut être suffisante. Lorsque le nombre d’éléments devient important et que le tableau est déjà trié, la recherche dichotomique réduit fortement le nombre de comparaisons.
La taille ne doit toutefois pas être considérée seule. Le coût de préparation des données, leur fréquence de modification et le nombre de recherches prévues influencent le choix.
Situation | Analyse |
|---|---|
| Petit tableau, une seule recherche | La recherche séquentielle est souvent suffisante. |
| Grand tableau déjà trié | La recherche dichotomique est très avantageuse. |
| Grand tableau non trié, une seule recherche | Parcourir séquentiellement évite le coût d’un tri préalable. |
| Grand tableau, nombreuses recherches | Trier une fois puis utiliser la dichotomie peut être rentable. |
| Tableau modifié fréquemment | Maintenir l’ordre peut entraîner un coût d’insertion ou de tri. |
13.3.3 Tableau trié ou non trié
Caractéristique des données | Recherche séquentielle | Recherche dichotomique |
|---|---|---|
| Tableau non trié | Applicable | Non applicable correctement |
| Tableau trié croissant | Applicable | Applicable |
| Tableau trié décroissant | Applicable | Applicable avec comparaisons adaptées |
| Données avec doublons | Trouve facilement toutes les occurrences | Variante nécessaire pour première ou dernière occurrence |
| Ordre inconnu | Choix sûr | Le tri doit être garanti avant utilisation |
| Règle de choix : en l’absence de garantie sur l’ordre, la recherche séquentielle est la méthode correcte par défaut. |
13.3.4 Cas favorable et cas défavorable
Méthode | Cas favorable | Cas défavorable |
|---|---|---|
| Séquentielle | La valeur est en première position. | La valeur est absente ou en dernière position. |
| Dichotomique | La valeur se trouve immédiatement au milieu. | La valeur est atteinte au dernier niveau ou est absente. |
Le cas moyen dépend de la distribution des recherches et de la probabilité que chaque élément soit demandé. Dans un tableau non trié où toutes les positions sont aussi probables, une recherche séquentielle réussie examine en moyenne environ la moitié des éléments.
13.3.5 Mémoire utilisée
Les versions itératives utilisent seulement quelques variables supplémentaires : un indice pour la recherche séquentielle et trois indices pour la recherche dichotomique. Leur mémoire auxiliaire reste donc constante.
Les versions récursives créent une pile d’appels. Une recherche séquentielle récursive peut empiler jusqu’à n appels, tandis qu’une recherche dichotomique récursive n’en empile qu’un nombre proportionnel au nombre de divisions successives.
Version | Mémoire auxiliaire qualitative |
|---|---|
| Séquentielle itérative | Constante |
| Séquentielle récursive | Peut croître jusqu’au nombre d’éléments |
| Dichotomique itérative | Constante |
| Dichotomique récursive | Croît lentement avec le nombre de divisions |
13.3.6 Coût global : trier puis rechercher
La recherche dichotomique ne doit pas être évaluée isolément lorsque les données sont initialement non triées. Il faut aussi considérer le coût du tri. Pour une seule recherche, trier tout le tableau peut être inutile. Pour des centaines de recherches sur les mêmes données, le tri initial peut être amorti.
Scénario | Stratégie raisonnable |
|---|---|
| Une recherche dans des données non triées | Recherche séquentielle. |
| Plusieurs recherches, données rarement modifiées | Trier puis utiliser la recherche dichotomique. |
| Données ajoutées en permanence sans maintien de l’ordre | Recherche séquentielle ou structure spécialisée. |
| Données maintenues triées à chaque insertion | Recherche dichotomique, en tenant compte du coût des insertions. |
13.3.7 Tableau de décision
Question | Oui | Non |
|---|---|---|
| Le tableau est-il garanti trié ? | Examiner la dichotomie. | Utiliser la recherche séquentielle ou trier. |
| Une seule recherche est-elle prévue ? | La simplicité peut primer. | Le coût d’organisation peut être amorti. |
| Faut-il toutes les occurrences ? | Prévoir une variante ou un parcours complémentaire. | La première occurrence peut suffire. |
| Les données changent-elles souvent ? | Évaluer le coût de maintien du tri. | Le tri initial reste durable. |
| Le tableau est-il très grand ? | L’écart entre les méthodes devient important. | Les deux méthodes peuvent convenir. |
Applications guidées
Application 1 — Rechercher un étudiant par matricule
Un tableau Matricules contient les identifiants des étudiants dans l’ordre d’inscription, sans garantie de tri. Concevoir une fonction qui retourne l’indice d’un matricule demandé.
Solution adaptée
| Fonction ChercherMatricule(Matricules : Tableau, n : Entier, cible : Chaîne) : Entier Variables i : Entier Début i ← 0 TantQue i < n ET Matricules[i] ≠ cible Faire i ← i + 1 FinTantQue Si i < n Alors Retourner i Sinon Retourner -1 FinSi Fin |
La recherche séquentielle est choisie parce que le tableau n’est pas garanti trié.
Application 2 — Rechercher une note dans une liste triée
Les notes ont été classées par ordre croissant. On souhaite déterminer rapidement si la note 14,5 est présente.
Solution adaptée
| position ← RechercheDichotomique(NotesTriees, n, 14.5) Si position = -1 Alors Afficher("Note absente") Sinon Afficher("Note trouvée à l’indice ", position) FinSi |
La recherche dichotomique est pertinente, car l’ordre est connu et permet d’éliminer une moitié à chaque étape.
Application 3 — Compter les absences
Un tableau de caractères contient P pour présent et A pour absent. Il faut compter toutes les absences. Un arrêt à la première occurrence serait incorrect.
Parcours complet
| Fonction CompterAbsences(Presences : Tableau, n : Entier) : Entier Variables i, nombre : Entier Début nombre ← 0 Pour i allant de 0 à n - 1 Faire Si Presences[i] = 'A' Alors nombre ← nombre + 1 FinSi FinPour Retourner nombre Fin |
Application 4 — Première et dernière occurrence
Dans T = [1, 2, 2, 2, 2, 5, 9], déterminer les indices de la première et de la dernière occurrence de 2. Deux recherches dichotomiques modifiées permettent d’obtenir les bornes du bloc de doublons.
Dernière occurrence
| Fonction DerniereOccurrence(T : Tableau, n : Entier, x : Réel) : Entier Variables g, d, m, resultat : Entier Début g ← 0 d ← n - 1 resultat ← -1 TantQue g ≤ d Faire m ← g + (d - g) DIV 2 Si T[m] = x Alors resultat ← m g ← m + 1 SinonSi x < T[m] Alors d ← m - 1 Sinon g ← m + 1 FinSi FinTantQue Retourner resultat Fin |
La première occurrence vaut 1 et la dernière vaut 4. Le nombre d’occurrences est donc 4 - 1 + 1 = 4.
Application 5 — Point d’insertion dans un tableau trié
Même lorsque x est absent, la dichotomie peut déterminer l’indice où x devrait être inséré afin de préserver l’ordre. À la fin de la boucle, la borne gauche indique cette position.
Indice d’insertion
| Fonction PositionInsertion(T : Tableau, n : Entier, x : Réel) : Entier Variables gauche, droite, milieu : Entier Début gauche ← 0 droite ← n - 1 TantQue gauche ≤ droite Faire milieu ← gauche + (droite - gauche) DIV 2 Si T[milieu] < x Alors gauche ← milieu + 1 Sinon droite ← milieu - 1 FinSi FinTantQue Retourner gauche Fin |
T | x | Position retournée |
|---|---|---|
| [3, 8, 12, 20] | 1 | 0 |
| [3, 8, 12, 20] | 10 | 2 |
| [3, 8, 12, 20] | 12 | 2 |
| [3, 8, 12, 20] | 25 | 4 |
Méthode de résolution et de traçage
Méthode pour une recherche séquentielle
1. Préciser le résultat demandé : existence, position, compteur ou toutes les positions.
2. Déterminer si un arrêt anticipé est autorisé.
3. Initialiser l’indice et les éventuels compteurs.
4. Contrôler la borne avant chaque accès au tableau.
5. Comparer l’élément courant à la clé.
6. Mettre à jour l’indice ou le résultat.
7. Traiter clairement le cas où la valeur est absente.
Méthode pour une recherche dichotomique
1. Vérifier que le tableau est trié et connaître le sens du tri.
2. Choisir une convention d’intervalle et la conserver.
3. Initialiser gauche et droite.
4. Calculer le milieu par division entière.
5. Comparer la clé à l’élément central.
6. Exclure le milieu et conserver une seule moitié.
7. Répéter tant que la zone n’est pas vide.
8. Tester les cas à zéro, un et deux éléments.
Erreurs fréquentes et bonnes pratiques
Erreur fréquente | Pourquoi elle est problématique | Bonne pratique |
|---|---|---|
| Ne pas préciser le résultat recherché | Première occurrence et toutes les occurrences exigent des algorithmes différents. | Écrire le contrat avant le pseudo-code. |
| Accéder à T[i] avant de tester i < n | Risque d’accès hors limites. | Tester la borne en premier dans une conjonction. |
| Continuer après une première occurrence inutilement | Comparaisons supplémentaires. | Utiliser un arrêt anticipé. |
| Arrêter lors du comptage des occurrences | Le compteur devient incomplet. | Parcourir tout le tableau. |
| Utiliser la dichotomie sans tri garanti | Résultat potentiellement faux. | Documenter la précondition de tri. |
| Mauvaise initialisation de droite | La zone inclut un indice inexistant. | Avec un intervalle fermé, droite = n - 1. |
| Mise à jour qui conserve le milieu | Boucle infinie possible. | Exclure le milieu déjà comparé. |
| Oublier les doublons | L’indice obtenu peut ne pas être la première occurrence. | Utiliser la variante adaptée. |
Travaux dirigés
Pour chaque exercice, préciser les préconditions, le résultat retourné, le pseudo-code et au moins quatre jeux d’essai incluant un cas limite.
Exercice 1 — Présence et position
Écrire deux fonctions de recherche séquentielle dans un tableau d’entiers : la première retourne un booléen indiquant si x existe ; la seconde retourne l’indice de sa première occurrence ou -1.
Exercice 2 — Dernière occurrence séquentielle
Écrire une fonction qui retourne la dernière occurrence de x dans un tableau non trié. Proposer une version parcourant le tableau de gauche à droite, puis une version partant de la fin.
Exercice 3 — Toutes les positions
Construire un tableau P contenant les indices de toutes les occurrences de x dans T. La fonction retourne le nombre d’indices écrits dans P.
Exercice 4 — Recherche parmi des noms
Un tableau contient des noms. Écrire une recherche qui ne distingue pas les majuscules des minuscules. Exemple : « AMAL » et « Amal » doivent être considérés comme égaux.
Exercice 5 — Trace dichotomique
Tracer la recherche des valeurs 4, 26 et 17 dans le tableau trié [2, 4, 7, 11, 15, 18, 21, 26, 30]. Indiquer gauche, droite, milieu et décision à chaque étape.
Exercice 6 — Corriger les bornes
L’algorithme suivant contient plusieurs erreurs. Les identifier et proposer une version correcte.
| gauche ← 0 droite ← n TantQue gauche < droite Faire milieu ← (gauche + droite) DIV 2 Si T[milieu] = x Alors Retourner milieu SinonSi x < T[milieu] Alors droite ← milieu Sinon gauche ← milieu FinSi FinTantQue Retourner -1 |
Exercice 7 — Première occurrence dichotomique
Écrire et tracer une fonction qui retourne la première occurrence de x dans un tableau trié contenant des doublons.
Exercice 8 — Nombre d’occurrences par deux recherches
Dans un tableau trié, calculer le nombre d’occurrences de x à partir de sa première et de sa dernière occurrence. Éviter un parcours complet du bloc de doublons.
Exercice 9 — Comparaison expérimentale
Pour des tableaux de tailles 8, 16, 32 et 64, compter les comparaisons réalisées par les deux méthodes lorsque la valeur est absente. Présenter les résultats dans un tableau et commenter leur évolution.
Exercice 10 — Choix de méthode
Choisir et justifier une méthode pour chacune des situations suivantes : une liste non triée de 20 noms ; un annuaire trié de 100 000 noms ; une seule recherche dans un fichier non trié ; 10 000 recherches dans une liste stable ; comptage de toutes les valeurs égales à 0.
Corrigés indicatifs
Corrigé 1 — Présence et position
| Fonction ExisteSeq(T : Tableau, n, x : Entier) : Booléen Début Retourner RecherchePremierSeq(T, n, x) ≠ -1 Fin Fonction RecherchePremierSeq(T : Tableau, n, x : Entier) : Entier Variables i : Entier Début i ← 0 TantQue i < n ET T[i] ≠ x Faire i ← i + 1 FinTantQue Si i < n Alors Retourner i Sinon Retourner -1 FinSi Fin |
Corrigé 2 — Dernière occurrence séquentielle
Version depuis la fin
| Fonction DerniereSeq(T : Tableau, n, x : Entier) : Entier Variables i : Entier Début i ← n - 1 TantQue i ≥ 0 ET T[i] ≠ x Faire i ← i - 1 FinTantQue Retourner i Fin |
Lorsque la valeur est absente, i devient -1. Le parcours depuis la fin permet un arrêt dès que la dernière occurrence est rencontrée.
Corrigé 3 — Toutes les positions
| Fonction ToutesPositions(T : Tableau, n, x : Entier, P : Tableau) : Entier Variables i, k : Entier Début k ← 0 Pour i allant de 0 à n - 1 Faire Si T[i] = x Alors P[k] ← i k ← k + 1 FinSi FinPour Retourner k Fin |
Corrigé 4 — Recherche parmi des noms
| Fonction ChercherNom(Noms : Tableau, n : Entier, cible : Chaîne) : Entier Variables i : Entier cibleNormalisee : Chaîne Début cibleNormalisee ← Minuscules(cible) i ← 0 TantQue i < n ET Minuscules(Noms[i]) ≠ cibleNormalisee Faire i ← i + 1 FinTantQue Si i < n Alors Retourner i Sinon Retourner -1 FinSi Fin |
Dans une application réelle, il est souvent préférable de normaliser les noms une seule fois au moment du stockage plutôt qu’à chaque comparaison.
Corrigé 5 — Trace dichotomique
Valeur | Étapes principales | Résultat |
|---|---|---|
| 4 | m=4 → 15 ; m=1 → 4 | Indice 1 |
| 26 | m=4 → 15 ; m=6 → 21 ; m=7 → 26 | Indice 7 |
| 17 | m=4 → 15 ; m=6 → 21 ; m=5 → 18 ; zone vide | -1 |
Corrigé 6 — Corriger les bornes
Les erreurs sont : droite initialisée à n au lieu de n - 1, condition gauche < droite qui peut ignorer la dernière case et mises à jour qui peuvent conserver le milieu.
Version corrigée
| gauche ← 0 droite ← n - 1 TantQue gauche ≤ droite Faire milieu ← gauche + (droite - gauche) DIV 2 Si T[milieu] = x Alors Retourner milieu SinonSi x < T[milieu] Alors droite ← milieu - 1 Sinon gauche ← milieu + 1 FinSi FinTantQue Retourner -1 |
Corrigé 7 — Première occurrence dichotomique
| Fonction PremiereDicho(T : Tableau, n, x : Entier) : Entier Variables g, d, m, resultat : Entier Début g ← 0 d ← n - 1 resultat ← -1 TantQue g ≤ d Faire m ← g + (d - g) DIV 2 Si T[m] = x Alors resultat ← m d ← m - 1 SinonSi x < T[m] Alors d ← m - 1 Sinon g ← m + 1 FinSi FinTantQue Retourner resultat Fin |
Corrigé 8 — Nombre d’occurrences
| premiere ← PremiereDicho(T, n, x) Si premiere = -1 Alors Retourner 0 Sinon derniere ← DerniereOccurrence(T, n, x) Retourner derniere - premiere + 1 FinSi |
La formule est valable parce que les occurrences d’une même valeur sont contiguës dans un tableau trié.
Corrigé 9 — Comparaison expérimentale
n | Séquentielle, valeur absente | Dichotomique, maximum approximatif |
|---|---|---|
| 8 | 8 comparaisons | 4 comparaisons |
| 16 | 16 comparaisons | 5 comparaisons |
| 32 | 32 comparaisons | 6 comparaisons |
| 64 | 64 comparaisons | 7 comparaisons |
Quand n double, le pire cas séquentiel double. Pour la dichotomie, une seule étape supplémentaire suffit approximativement.
Corrigé 10 — Choix de méthode
Situation | Choix | Justification |
|---|---|---|
| 20 noms non triés | Séquentielle | Petit tableau et absence de tri. |
| 100 000 noms triés | Dichotomique | Ordre garanti et grand volume. |
| Une seule recherche non triée | Séquentielle | Évite de trier tout le tableau. |
| 10 000 recherches, liste stable | Trier puis dichotomie | Le coût du tri est amorti. |
| Compter toutes les valeurs 0 | Parcours complet | Toutes les occurrences doivent être examinées, sauf variante sur tableau trié. |
Synthèse du chapitre
La recherche séquentielle est universelle et simple : elle examine les éléments dans leur ordre de stockage. Elle est adaptée aux données non triées, aux petits tableaux et aux traitements qui nécessitent toutes les occurrences. La recherche dichotomique est beaucoup plus rapide sur les grandes données triées, car elle divise la zone possible par deux à chaque étape.
Notion | À retenir |
|---|---|
| Clé de recherche | Valeur que l’on souhaite localiser. |
| Recherche séquentielle | Parcours élément par élément, sans précondition de tri. |
| Arrêt anticipé | Possible lorsque la première occurrence suffit. |
| Toutes les occurrences | Exigent généralement un parcours complet. |
| Recherche dichotomique | Division répétée d’un intervalle trié. |
| Bornes | gauche et droite délimitent la zone encore possible. |
| Milieu | Indice utilisé pour choisir la moitié à conserver. |
| Condition de tri | Indispensable pour justifier l’élimination d’une moitié. |
| Doublons | Une variante est nécessaire pour la première ou la dernière occurrence. |
| Choix de méthode | Dépend de l’ordre, de la taille, des modifications et du nombre de recherches. |
Checklist de conception
1. Définir précisément ce que doit retourner la recherche.
2. Identifier la taille utile du tableau et valider les bornes.
3. Vérifier si l’ordre des données est garanti.
4. Choisir entre parcours complet et arrêt anticipé.
5. Traiter explicitement le tableau vide et la valeur absente.
6. Pour la dichotomie, fixer une convention d’intervalle.
7. Exclure le milieu après chaque comparaison infructueuse.
8. Tester une zone de un puis de deux éléments.
9. Traiter les doublons selon le besoin.
10. Comparer le coût global, y compris un éventuel tri préalable.
Glossaire
Terme | Définition |
|---|---|
| Clé | Valeur recherchée dans un ensemble de données. |
| Occurrence | Apparition d’une valeur dans le tableau. |
| Recherche séquentielle | Méthode examinant successivement les éléments. |
| Arrêt anticipé | Fin de l’algorithme dès que le résultat suffisant est obtenu. |
| Recherche dichotomique | Méthode divisant une zone triée en deux parties. |
| Borne gauche | Premier indice encore susceptible de contenir la clé. |
| Borne droite | Dernier indice encore susceptible de contenir la clé. |
| Milieu | Indice central de la zone de recherche. |
| Tableau trié | Tableau dont les éléments respectent un ordre défini. |
| Sentinelle | Valeur placée temporairement pour simplifier une condition d’arrêt. |
Auto-évaluation
Compétence | Acquise | À renforcer |
|---|---|---|
| Je sais écrire une recherche séquentielle avec arrêt anticipé. | □ | □ |
| Je sais compter et enregistrer toutes les occurrences. | □ | □ |
| Je sais expliquer pourquoi la dichotomie exige un tableau trié. | □ | □ |
| Je sais initialiser et mettre à jour les bornes. | □ | □ |
| Je sais tracer une recherche dichotomique. | □ | □ |
| Je sais écrire les versions itérative et récursive. | □ | □ |
| Je sais gérer les doublons. | □ | □ |
| Je sais choisir la méthode adaptée à une situation. | □ | □ |
| Conclusion : un bon algorithme de recherche repose sur un contrat clair, des bornes correctes et une méthode compatible avec l’organisation des données. |