
2Chapitre 1. Algorithmes de tri élémentaires
4n = len(l)
5for iin range (n -1):
6imin = c her ch e_ in d_m in (l ,i , n )
7l[i ], l[ imin ] = l[ imin ], l [i]
Rappelons que, lors de l’écriture d’un algorithme, on doit être en mesure du justifier sa terminaison
et sa correction.
La terminaison est ici évidente car on utilise une boucle inconditionnelle (boucle for), qui se termine
toujours (contrairement au cas d’une boucle while).
Pour justifier la correction de l’algorithme (il fait bien ce pour quoi il a été conçu), démontrons que
la propriété suivante est vraie :
«À l’issue du passage d’indice idans la boucle, la plage `[0..i + 1[ est triée et elle contient les i+ 1
plus petits éléments.»
– Lors du premier passage dans la boucle, on identifie le plus petit élément du tableau, que l’on place
en tête (par permutation de deux éléments). À l’issue de ce passage d’indice i= 0, la plage `[0..1[
est triée (elle contient un unique élément) et elle contient les i+ 1 = 1 plus petits éléments.
– Supposons que la propriété soit vraie après le passage d’indice i. Lors du passage d’indice i+ 1, on
détermine le plus petit élément de la plage `[i+ 1..n[(qui est par hypothèse supérieur à tous les `k
pour k6i), que l’on échange avec celui d’indice i+1. À l’issue de ce passage d’indice i+ 1, la plage
`[0..i + 2[ est encore triée et elle contient les i+ 2 plus petits éléments.
Par récurrence finie, la propriété est encore vérifiée après le dernier passage, i.e. celui d’indice i=n−2.
À l’issue de ce passage, la plage `[0..n −1[ est donc triée, et elle contient les n−1plus petits éléments de
la liste. Par suite, le dernier élément `n−1est supérieur à tous les précédents, donc la totalité de la liste
est triée.
Remarque 1. Une telle propriété (que nous avons démontrée par récurrence) est appelée un invariant de
boucle. C’est en général en exhibant un tel invariant que l’on prouve la correction des algorithmes.
1.1.3 Stabilité
Lorsque les données à trier sont distinctes des clés utilisées pour trier la liste (par exemple, un élève
n’est pas égal à sa moyenne), on peut s’intéresser à ce qui arrive à deux éléments ayant la même clé (deux
élèves ayant la même moyenne) : après le tri, ces deux éléments sont-ils dans la même position relative
l’un par rapport à l’autre qu’avant le tri ? Lorsque c’est le cas, on dit que le tri est stable.
La stabilité d’un tri est un élément intéressant lorsque l’on veut trier des données suivant un critère
prioritaire, puis un critère secondaire. Par exemple, si les données sont des couples (nom, prénom), on
peut chercher à trier par nom (critère prioritaire) puis, en cas d’égalité des noms, par prénom (critère
secondaire). Si l’on dispose d’un tri stable, on peut réaliser ce tri de la façon suivante :
– commencer par trier selon le critère secondaire ;
– trier ensuite selon le critère prioritaire.
Les données seront alors triées selon le critère prioritaire. En cas d’égalité des clés associées (le nom dans
notre exemple), les données seront rangées, après ce second tri, dans le même ordre qu’après le premier
tri, i.e. classées selon le critère secondaire (le prénom).
Le tri par sélection n’est pas stable : par exemple, si les données sont A,Bet C, et que les clés attachées
sont 1,1et 0(ce que l’on notera pas A1,B1,C0), le tri par sélection transforme la liste [A1, B1, C0]en
[C0, B1, A1](les éléments Aet B, de même clé, ont été permutés).
1.1.4 Complexité
Lorsque l’on cherche à évaluer la complexité d’un algorithme, on distingue en général la complexité
– spatiale (l’espace mémoire qui est nécessaire pour exécuter l’algorithme) ;
– temporelle (le temps nécessaire à son exécution).
Nous n’étudierons ici que la complexité temporelle des algorithmes.
Il est évidemment impossible de dire quelle durée prendra l’exécution d’un algorithme : cela dépend en
particulier de la vitesse de la machine sur lequel il est exécuté. Pour évaluer cette complexité temporelle,
nous chercherons à compter le nombre d’opérations élémentaires effectuées par l’algorithme. Ceci est en
général impossible à faire de façon exacte, aussi simplifions-nous le problème en choisissant de compter
uniquement les opérations «significatives». On cherche par ailleurs à obtenir une estimation asymptotique