Exercice 1 : Recherche séquentielle et coût au pire
On travaille sur le tableau t = [7, 2, 9, 4, 1, 8, 3], qui n'est pas trié.
def recherche(t, x):
for i in range(len(t)):
if t[i] == x:
return i
return -1- a) Que renvoie recherche(t, 4) ? Et recherche(t, 5) ? Justifiez le choix de -1 comme valeur de retour.
- b) Combien de comparaisons effectue la fonction pour chercher 7 ? Pour chercher 3 ? Pour chercher une valeur absente ?
- c) Donnez le nombre de comparaisons dans le meilleur cas, dans le pire cas, et en moyenne pour un tableau de éléments contenant la valeur cherchée.
- d) Modifiez la fonction pour qu'elle renvoie la LISTE de tous les indices où x apparaît. Que devient alors le coût au pire ?
- e) Pourquoi ne peut-on pas utiliser la recherche dichotomique sur ce tableau ?
Voir la correction
a) recherche(t, 4) renvoie 3, car t[3] vaut 4. recherche(t, 5) renvoie -1 : la valeur est absente. On choisit -1 parce que c'est un indice IMPOSSIBLE en parcours normal, ce qui permet à l'appelant de distinguer sans ambiguïté l'échec du succès. Renvoyer 0 serait une faute grave, puisque 0 est un indice valide.
b) Pour 7 : une seule comparaison, il est en tête. Pour 3 : sept comparaisons, il est en dernière position. Pour une valeur absente : sept comparaisons également, la boucle va jusqu'au bout.
c) Meilleur cas : 1 comparaison, l'élément est en première position. Pire cas : comparaisons, l'élément est en dernier ou absent. En moyenne, si la valeur est présente et que toutes les positions sont équiprobables, on effectue comparaisons, soit environ la moitié du tableau. Dans les trois cas le coût est proportionnel à : la recherche séquentielle est de complexité linéaire, .
d) Il faut supprimer le return anticipé et accumuler les indices, donc parcourir tout le tableau. Le coût devient exactement comparaisons dans TOUS les cas, y compris le meilleur : on perd la possibilité de s'arrêter tôt. C'est le prix à payer pour une réponse exhaustive.
e) Parce que le tableau n'est pas trié. La dichotomie repose entièrement sur le fait que comparer la valeur cherchée à l'élément du milieu permet d'éliminer une moitié entière ; si le tableau est en désordre, cette comparaison n'apprend rien sur la position des autres éléments. Trier d'abord coûte plus cher qu'une seule recherche séquentielle : cela ne vaut la peine que si l'on prévoit de nombreuses recherches sur le même tableau.
def tous_les_indices(t, x):
resultat = []
for i in range(len(t)):
if t[i] == x:
resultat.append(i)
return resultat # cout : n comparaisons, toujours