1 Algorithme de recherche dans une liste

publicité
Informatique
Cours 4.1
Le tri des listes est un des éléments qui permet d'accéder aux données rapidement.
Tri par insertion
Exemple de requêtes possibles sur des listes triées :
-
rechercher si un élément est dans un tableau (recherche d'un mot dans une liste de mots clefs pour
les métadonnées de pages internet),
-
déterminer la médiane d’une liste de nombres (exemple : dans un concours, déterminer la note qui
départage les candidats en deux groupes de même effectif),
-
sélectionner une sous-liste d’éléments consécutifs (exemple : afficher seulement les relevés
temporels compris entre l'instant 1s et l'instant 2s),
1 Algorithme de recherche dans une liste
1.1 Recherche dans une liste non triée
Algorithme Recherche de x dans L
Entrées : élément x et liste L
Sortie : s=Vrai si x est dans L et Faux sinon
n ← Nombre d'éléments de L
def recherche (L,x):
# Entrées : élément x et liste L
# Sortie : s=True si x dans L et False sinon
n = len (L)
s ← Faux
c←0
Tant que (c < n et s=Faux) Faire
Si L[c]=x alors
s ← Vrai
c ← c+1
Fin tant que
s = False
# s : Faux par défaut
c=0
# initialisation de l'indexe
while (c<n and s==False):
if L[c]==x :
s = True
c = c+1
return s
Renvoyer s
Fin de l'algorithme Recherche de x dans L
Appel de la fonction recherche:
>>> liste = [0,2,1]
>>> recherche (liste,2)
True
Complexité
Dans le pire des cas, l'élément n'est pas présent dans la liste, la complexité temporelle correspond à
C(n)=n
Pour les algorithmes de recherche dans une liste non triée on a une complexité
(comptée en nombre d'itérations).
Lycée Jules Ferry Cannes
Page 1 sur 4
linéaire
TSI2
Informatique
Cours 4.1
Tri par insertion
1.2 Complexité dans une liste triée
Algorithme Recherche dichotomique[2]
Entrées : élément x et liste L
Sortie : s=Vrai si x est dans L et Faux sinon
n ← Nombre d'éléments de L
g←0
d ← n-1
Tant que g ≠ d Faire
k ← (g+d) div 2
Si L[k]<x Alors
g ← k+1
Sinon :
Si L[k]>x Alors
d←k
Sinon :
d←k
g←k
Fin Si
Fin Tant que
Si L[g]=x Alors
s ← True
Sinon
s ← False
Fin Si
Renvoyer s
Fin de Recherche dichotomique
def Recherche_dichotomique (L,x):
# Entrée : liste L, x élément cherché
# Sortie : s=True si x dans L et False sinon
n=len(L)
g=0
# premier indice de L : 0
d=n-1
# dernier indice de L : n-1
while g!=d:
k=(g+d)//2
# dichotomie
if L[k]<x: # x est à droite du milieu
g=k+1
else:
if L[k]>x:
# x est à gauche du milieu
d=k
else:
# x est au milieu
g=k
d=k
if L[g]==x:
# Affectation de la sortie
s=True
else:
s=False
return s
Appel de la fonction Recherche_dichotomique :
>>> liste_triee=[0,1,2]
>>> Recherche_dichotomique(liste_triee,2)
True
Complexité : Dans le pire des cas, l'élément n'est pas présent dans la liste. Si m est le nombre d'éléments
restants après k itérations : ≤ <
jusqu'à m=1. Complexité
= <
+ 1 itérations.
Pour un algorithme de recherche dichotomique, on a une complexité
logarithmique
(comptée en nombre d'itérations).
1.3 Conclusion
Pour le traitement de grandes quantités de données (base de donnée internet, relevés à haute fréquence,
résultats de calculs par éléments finis…), l'algorithme a un impact important sur les durées de traitement.
Exemple pour 10 pages trouvées, un moteur de recherche internet met 0,5 s.
Pour une durée unitaire d'opération de 10ns si n=10 données :
-
Un algorithme linéaire conduit à une durée de traitement de 10s.
-
Un algorithme logarithmique log 10 ≈ 30 conduit à une durée de traitement de 300ns
Pour afficher rapidement des données nombreuses, il est donc indispensable de trier les données avant les
requêtes.
2 Tris
2.1 Principe du tri
On se donne un tableau t, dont les éléments t[0]; t[1]; t[2]; …; t[n - 1] sont comparables.
Les t[i] peuvent être : des entiers, des flottants, des lettres de l’alphabet…
Un tableau t est trié par ordre croissant si : t[0] ≤ t[1] ≤…≤ t[n-1]:
Exemple : si t = ['C','A','T','A, 'Z','U','M'], on veut transformer t en t0 = ['A','A', 'C','M','T','U', 'Z']
Lycée Jules Ferry Cannes
Page 2 sur 4
TSI2
Informatique
Cours 4.1
Tri par insertion
Trois algorithmes sont au programme : le "tri par insertion", le "tri rapide" et le "tri fusion".
D’autres algorithmes hors programme existent : "tri par sélection", "tri à bulles" . . .
Chacun de ces tris se base sur une suite de comparaisons d’éléments.
Mais ces différents algorithmes ne sont pas équivalents, ils ont des complexités différentes, c’est-à-dire que
certains nécessitent plus de comparaisons d’éléments que d’autres, ou plus d’affectations.
2.2 Tri par insertion
On insère successivement chaque élément dans l’ensemble des éléments déjà triés.
Ce tri s’effectue en place : pas besoin de créer un autre tableau que celui que l’on trie.
Le coût en mémoire est constant.
Algorithme Tri par insertion
Entrées : liste T (tableau de n nombres; n≥ 2)
Sortie : liste T triée par ordre croissant
n←nombre d'éléments de T
Pour i de 1 à n-1 faire
x←T[i]
j← i
Tant que j> 0 et T[j-1] > x faire
T[j] ←T[j-1]
j← j-1
Fin Tant que
T[j] ←x
Fin Pour
Renvoyer T
Fin de Tri par insertion
Appel de la fonction Tri_insertion :
>>> liste=[5, 8, 3, 2, 9]
>>> Tri_insertion (liste)
[2, 3, 5, 8, 9]
def Tri_insertion (T):
"""Entrée liste T à n nombres (n≥ 2)
Sortie : liste T triée (croissant)"""
n = len(T)
for i in range(1,n): # tri de T
x = T[i]
j = i # j : position triée pour x
while j>0 and T[j-1] > x :
T[j] = T[j-1] # remonter droite
j=j-1
T[j] = x
return T
i=1, x=8
3
2
T[0]=5<x
8 en 1
i=2, x=3
tout remonte x en 0
i=3, x=2
tout remonte x en 0
i=4, x=9
T[4]=8<x
9 en 5
Terminaison
Chaque boucle while se termine puisque le variant de boucle j est initialement strictement positif puis
décrémenté à chaque itération, éventuellement jusqu'à la valeur 0.
Correction[1]
L'invariant de la boucle for "P(i) : la liste T[0:i] est triée"
permet de prouver la
correction de l'algorithme.
- Initialisation : i=1
T[0:1] contient un seul élément qui est donc trié.
- Récurrence : On suppose que P(i) est vraie, montrons que P(i+1) est vraie.
Lycée Jules Ferry Cannes
Page 3 sur 4
TSI2
Informatique
Cours 4
Si P(i) est vraie alors
0! ≤
1! ≤ ⋯ ≤
Tri par insertion
# − 1!, de plus x=T[i]
# − 2! ≤
•
si # − 1! ≤ & = #! alors on sort de la boucle while et la proriété P(i+1) est vraie sans
itération sur j : 0! ≤ 1! ≤ ⋯ ≤ # − 2! ≤ # − 1! ≤ & = #!
•
si
# − 1! > & alors on réalise des itérations avec le while tant que :
o
soit T[j-1]≤ & et dans ce cas on obtient la liste
0! ≤ 1! ≤ ⋯ ≤ ' − 1! <
())))))))*))))))))+
'! = & ≤ ()
')+
≤ ⋯))
≤)))+
#!
))1!
))*)
,- ./01, 23-1 456é8
o
P(i+1) est vraie,
5,93-4é8 23-1 456é8
soit j=0 et dans ce cas tous les éléments sont remontés (donc triés) et plus grand
que x : & < ()))))))))))*)))))))))))+
1! ≤ 2! ≤ ⋯ ≤ # − 1! ≤ #! P(i+1) est vraie.
5,93-4é8 23-1 456é8 105 : 6 ,84 ;506,
- Correction : la valeur qui met fin à la boucle for est i=n. On a alors P(n) vraie : la liste T[0:n] est triée
et contient les n éléments de T donc la liste T est triée.
Complexité (en temps)
On rappelle les différentes étapes de tri sur la liste [5,8,3,2,9]
3
2
Nombre de comparaisons effectuées pour trier par insertion un tableau de longueur n :
• en tout, on fait n - 1 insertions (celle de t[1], t[2] … t[n - 1]).
• pour chaque insertion de t[i ] dans t[0 : i ], on fait
- 1 comparaison dans le meilleur des cas (déjà trié):
o Est-ce que t[i ] > t[i - 1] ?
- i comparaisons dans le pire des cas (trié en sens inverse):
o Est-ce que t[i ] > t[i - 1] ?
o Est-ce que t[i ] > t[i - 2] ?
…
o Est-ce que t[i ] > t[0] ?
o Est-ce qu’on est arrivé en bout de liste ?
Total : 1 + … + 1 = n - 1 comparaisons dans le meilleur cas (liste triée).
> -?@ A> @
1 + … + i + … + n-1 = < − 1 ∗
= <−1 ∗
-
~
<→∞
-E
comparaisons
dans
le
pire
des
cas
comparaisons
affectations
(liste triée en sens inverse).
Le tri par insertion a donc une complexité
meilleur
cas
pire
cas
n
n
n²/2
n²/2
quadratique (en O(n²)), donc médiocre.
Néanmoins le tri par insertion reste un des algorithmes les plus performants lorsque la
liste est
presque triée : complexité linéaire.
Ressources :
[1] T. Audibert et A. Oussalah, Informatique : Programmation et calcul scientifique en Python et Scilab. Ellipses.
[2] P. Beynet, « IPT-2 ». UPSTI.
Lycée Jules Ferry Cannes
Page 4 sur 4
TSI2
Téléchargement