Recherche linéaire (Linear Search)
La recherche linéaire (ou recherche séquentielle) est l'algorithme de recherche le plus simple. Elle consiste à parcourir un tableau élément par élément jusqu'à trouver la valeur recherchée ou atteindre la fin du tableau.
C'est une méthode universelle qui fonctionne sur tout type de tableau, qu'il soit trié ou non.
Principe de l'algorithme
La recherche linéaire est intuitive : on parcourt le tableau du premier au dernier élément, en comparant chaque élément avec la valeur recherchée.
- Commencer par le premier élément du tableau (indice 0).
- Comparer l'élément courant avec la valeur recherchée x.
- Si l'élément courant est égal à x, retourner son indice (succès).
- Si l'élément courant est différent, passer à l'élément suivant.
- Si on atteint la fin du tableau sans avoir trouvé x, retourner -1 (échec).
Cette approche ne fait aucune hypothèse sur l'ordre des éléments. Elle fonctionne aussi bien sur des tableaux triés que non triés.
Implémentations de la recherche linéaire
Version simple
FONCTION RechercheLineaire(tab, n, x):
POUR i DE 0 À n-1 FAIRE
SI tab[i] == x ALORS
RETOURNER i // Élément trouvé à l'indice i
FINSI
FINPOUR
RETOURNER -1 // Élément non trouvé
FINFONCTIONdef recherche_lineaire(tab, x):
"""
Recherche linéaire d'un élément x dans un tableau.
Paramètres:
tab: tableau quelconque (trié ou non)
x: élément recherché
Retourne:
L'indice de l'élément s'il est trouvé, -1 sinon
"""
for i in range(len(tab)):
if tab[i] == x:
return i
return -1
# Test
tab = [5, 2, 8, 3, 9, 1, 4, 7, 6]
x = 8
resultat = recherche_lineaire(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")#include <stdio.h>
int recherche_lineaire(int tab[], int n, int x) {
for (int i = 0; i < n; i++) {
if (tab[i] == x) {
return i; // Élément trouvé à l'indice i
}
}
return -1; // Élément non trouvé
}
int main() {
int tab[] = {5, 2, 8, 3, 9, 1, 4, 7, 6};
int n = sizeof(tab) / sizeof(tab[0]);
int x = 8;
int resultat = recherche_lineaire(tab, n, x);
if (resultat != -1) {
printf("L'élément %d est présent à l'indice %d\n", x, resultat);
} else {
printf("L'élément %d n'est pas présent dans le tableau\n", x);
}
return 0;
}L'élément 8 est présent à l'indice 2
Version avec sentinelle (optimisation)
Une optimisation classique consiste à utiliser une sentinelle pour éviter de vérifier à chaque itération si on a atteint la fin du tableau. On place la valeur recherchée à la fin du tableau (en supposant qu'il y a de la place), ce qui garantit que la recherche trouvera toujours la valeur (soit la vraie, soit la sentinelle).
FONCTION RechercheLineaireSentinelle(tab, n, x):
// Supposons que tab a une taille suffisante
dernier = tab[n-1]
tab[n-1] = x // Placer la sentinelle
i = 0
TANT QUE tab[i] != x FAIRE
i = i + 1
FINTANTQUE
tab[n-1] = dernier // Restaurer la valeur originale
SI i < n-1 OU tab[n-1] == x ALORS
RETOURNER i
SINON
RETOURNER -1
FINSI
FINFONCTIONdef recherche_lineaire_sentinelle(tab, x):
"""
Recherche linéaire avec sentinelle (optimisation).
Note: Cette version modifie temporairement le tableau.
"""
n = len(tab)
dernier = tab[n-1]
tab[n-1] = x # Placer la sentinelle
i = 0
while tab[i] != x:
i += 1
tab[n-1] = dernier # Restaurer la valeur originale
if i < n-1 or tab[n-1] == x:
return i
return -1
# Test
tab = [5, 2, 8, 3, 9, 1, 4, 7, 6]
x = 8
resultat = recherche_lineaire_sentinelle(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
La version avec sentinelle élimine une comparaison par itération (celle de la fin de boucle), ce qui peut améliorer les performances d'environ 10-20% pour de grands tableaux.
Exemples d'exécution pas à pas
Exemple n°1 : Recherche de 8 dans [5, 2, 8, 3, 9, 1, 4, 7, 6]
| Étape | Indice | Valeur | Comparaison |
|---|---|---|---|
| 1 | 0 | 5 | 5 ≠ 8 → continuer |
| 2 | 1 | 2 | 2 ≠ 8 → continuer |
| 3 | 2 | 8 | 8 = 8 → trouvé ! |
Exemple n°2 : Recherche de 10 dans le même tableau (non trouvé)
| Étape | Indice | Valeur | Comparaison |
|---|---|---|---|
| 1 | 0 | 5 | 5 ≠ 10 |
| 2 | 1 | 2 | 2 ≠ 10 |
| 3 | 2 | 8 | 8 ≠ 10 |
| 4 | 3 | 3 | 3 ≠ 10 |
| 5 | 4 | 9 | 9 ≠ 10 |
| 6 | 5 | 1 | 1 ≠ 10 |
| 7 | 6 | 4 | 4 ≠ 10 |
| 8 | 7 | 7 | 7 ≠ 10 |
| 9 | 8 | 6 | 6 ≠ 10 |
| Fin du tableau → élément non trouvé | |||
Analyse de complexité
| Cas | Nombre de comparaisons | Complexité | Description |
|---|---|---|---|
| Meilleur cas | 1 | O(1) | L'élément recherché est le premier élément du tableau |
| Cas moyen | n/2 | O(n) | En moyenne, on parcourt la moitié du tableau |
| Pire cas | n | O(n) | L'élément est le dernier ou absent → on parcourt tout le tableau |
La recherche linéaire utilise un espace mémoire constant : O(1) (quelques variables de contrôle, quel que soit n).
Avantages et inconvénients
- Simplicité : Très facile à comprendre et à implémenter
- Universalité : Fonctionne sur tout type de tableau (trié ou non)
- Pas de prérequis : Ne nécessite pas de tri préalable
- Espace mémoire : Utilise très peu de mémoire (O(1))
- Petits tableaux : Efficace pour n < 50
- Recherches uniques : Idéal pour des recherches ponctuelles
- Lenteur : Complexité O(n) – peut être très lent pour de grands tableaux
- Pas d'optimisation : Ne tire pas parti d'un éventuel tri
- Comparaisons : Nombre de comparaisons proportionnel à n
- Recherches multiples : Inefficace si on doit faire plusieurs recherches
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) |
| Performance pour n = 1000 | Jusqu'à 1000 comparaisons | Environ 10 comparaisons |
| Performance pour n = 1 000 000 | Jusqu'à 1 million comparaisons | Environ 20 comparaisons |
- Pour de petits tableaux (n < 50) où le coût de tri serait supérieur au gain
- Lorsque le tableau n'est pas trié et qu'on ne veut pas le trier
- Pour des recherches ponctuelles sur des données non triées
- Dans les langages/structures où l'accès indexé n'est pas possible (listes chaînées)
- Pour sa simplicité d'implémentation dans des contextes pédagogiques
Variantes et extensions
Recherche de toutes les occurrences
def rechercher_toutes_occurrences(tab, x):
"""
Retourne une liste de tous les indices où x apparaît.
"""
indices = []
for i in range(len(tab)):
if tab[i] == x:
indices.append(i)
return indices
# Test
tab = [5, 2, 8, 3, 8, 1, 8, 7, 6]
x = 8
print(f"Indices de {x} : {rechercher_toutes_occurrences(tab, x)}")Indices de 8 : [2, 4, 6]
Recherche linéaire dans une liste chaînée
class Noeud:
def __init__(self, valeur):
self.valeur = valeur
self.suivant = None
def rechercher_liste_chainee(tete, x):
"""
Recherche linéaire dans une liste chaînée.
"""
courant = tete
position = 0
while courant is not None:
if courant.valeur == x:
return position
courant = courant.suivant
position += 1
return -1
# Création d'une liste chaînée : 5 → 2 → 8 → 3
tete = Noeud(5)
tete.suivant = Noeud(2)
tete.suivant.suivant = Noeud(8)
tete.suivant.suivant.suivant = Noeud(3)
print(f"Position de 8 : {rechercher_liste_chainee(tete, 8)}")Position de 8 : 2
Recherche linéaire récursive
def recherche_lineaire_recursive(tab, x, i=0):
"""
Version récursive de la recherche linéaire.
"""
if i >= len(tab):
return -1
if tab[i] == x:
return i
return recherche_lineaire_recursive(tab, x, i + 1)
# Test
tab = [5, 2, 8, 3, 9, 1, 4, 7, 6]
x = 8
print(f"Indice de {x} : {recherche_lineaire_recursive(tab, x)}")Indice de 8 : 2
- La recherche linéaire est l'algorithme de recherche le plus simple : parcourir le tableau élément par élément.
- Elle fonctionne sur tout type de tableau, trié ou non trié.
- Complexité temporelle : O(n) dans le pire cas – linéaire par rapport à la taille du tableau.
- Complexité spatiale : O(1) – très économique en mémoire.
- Deux implémentations possibles : itérative (recommandée) et récursive (pédagogique).
- Une optimisation possible avec une sentinelle pour réduire le nombre de comparaisons.
- Idéale pour les petits tableaux (n < 50) ou les recherches ponctuelles sur données non triées.
- Pour de grands tableaux, préférer la recherche dichotomique si les données sont triées.
En Python, l'opérateur in et la méthode list.index() implémentent une recherche linéaire optimisée. Pour de grands ensembles de données, envisagez d'utiliser un set ou un dict pour des recherches en O(1).
Discussion (0)
Soyez le premier à laisser un commentaire !
Laisser un commentaire
Votre commentaire sera visible après modération.