Algorithme du tri par sélection
Le tri par sélection est un algorithme simple qui fonctionne de la même manière quelque-soit le tableau en entrée. L'algorithme procède ainsi : à chaque itération de l'algorithme, on place à l'indice $i$ du tableau son $i$-ème plus petit élément.
On en déduit l'algorithme en pseudo-code suivant :
def sélection(T):
for i in range(len(T) - 1):
min_index = i
for j in range(i + 1, len(T)):
if T[j] < T[min_index]:
min_index = j
T[i], T[min_index] = T[min_index], T[i]
L'algorithme sélection
modifie le tableau passé en paramètre. On appelle ces algorithmes in place car ils ne rendent rien, mais modifient les données en entrées.
Fonctionnement
On vérifie que l'algorithme fonctionne pour :
- un petit tableau trié :
[1, 2, 3]
- un petit tableau non trié où le plus petit est en dernière place :
[3, 2, 1]
Preuve
Le principe de fonctionnement est clair. Il reste à prouver que c'est bien ce que l'algorithme sélection
fait.
- la boucle
for
de la ligne 4 trouve l'indice du plus petit élément du tableauT[i:]
. - la ligne 7 échange le minimum du tableau
T[i:]
avecT[i]
- comme la boucle
for
de la ligne 2 incrémente $i$, on a l'invariant de boucle :
Invariant de boucle
À la fin de chaque étape $i$ de l'algorithme les $i$ plus petites valeurs du tableau sont triées aux $i$ premiers indices du tableau.
Complexités
On suppose que la taille du tableau est $n$.
Ligne à ligne :
- début de fonction : $\mathcal{O}(1)$
- une boucle de $n-1$ itérations
- une affectation $\mathcal{O}(1)$
- une boucle de $n-i-1$ itérations ($i$ est la variable définie ligne 2)
- un test et deux valeurs d'un tableau : $\mathcal{O}(1)$
- une affectation : $\mathcal{O}(1)$
- deux affectation et quatre valeurs d'un tableau : $\mathcal{O}(1)$
Le nombre d'itérations de la boucle for de la ligne 4 n'est pas constant, mais il décroît puisque $i$ augmente à chaque itération de la boucle for
de la ligne 2. On peut alors utiliser la règle de croissance pour utiliser le maximum, $n-1$, pour le calcul de la complexité.
Ce qui donne une complexité de :
Le nombre d'itérations est constant quelque soit le tableau, on a donc :
Proposition
La complexité de l'algorithme sélection
est ($n$ est la taille du tableau passé en entrée) :
- la complexité min vaut $\mathcal{O}(n^2)$
- la complexité (max) vaut $\mathcal{O}(n^2)$
- la complexité en moyenne vaut également $\mathcal{O}(n^2)$ (car les complexités min et max sont égales)
Variantes
Sélection est identique à l'algorithme ci-dessous :
def sélection(T):
for i in range(len(T)):
for j in range(i + 1, len(T)):
if T[j] < T[i]:
T[i], T[j] = T[j], T[i]
Pourquoi ?
Et celui ci tri dans le sens opposé :
def sélection(T):
for i in range(len(T)):
for j in range(len(T)):
if T[j] < T[i]:
T[i], T[j] = T[j], T[i]
pourquoi ?