Vous êtes sur une version archivée de lyceum.fr de l'année 2020/2021. Revenir au présent.
Programme Officiel

Contenus

Capacités attendues

Commentaires

Tris par insertion, par sélection

Écrire un algorithme de tri.

Décrire un invariant de boucle qui prouve la correction des tris par insertion, par sélection.

La terminaison de ces algorithmes est à justifier.

On montre que leur coût est quadratique dans le pire cas.

Lien vers le programme complet

Maintenant que nous disposons de tableaux pour stocker de grandes quantités de données, il faut qu'on apprenne à les classer. Il existe de nombreux algorithmes de tri plus ou moins efficaces, qui sont pour la plupart répertoriées dans The Art of Computer Programming, Volume 3, Sorting and Searching. de Knuth, Donald. E. [1998]. Le livre de chevet de tout programmeur.

Problématique

Comment ranger des données afin de faciliter leur accès futur ? C'est par exemple l'ordre alphabétique du dictionnaire, où les mots sont rangés dans un ordre logique qui permet de ne pas devoir parcourir tout l'ouvrage pour retrouver une définition. Ce peut être aussi l'ordre intuitif dans lequel un joueur de cartes va ranger son jeu afin de limiter le temps de recherche pendant le déroulement de la partie. Cette problématique permet d'introduire la notion de tri (avec plusieurs sens distincts : séparer, ordonner, choisir), puis d'étudier différents algorithmes de tri. Le tri permet essentiellement d'accélérer les recherches, grâce à l'algorithme de recherche dichotomique.

Source eduscol

Situation d'accroche

Un joueur de cartes reçoit 9 cartes lors de la donne en début de partie ; il les trie ensuite pour faciliter la lecture de son jeu.

  • Comment procède-t-il exactement pour réaliser cette opération ?
  • Y a-t-il plusieurs façons de procéder :

Vous rendre sur cette page sur laquelle vous est proposé un jeu de cartes à trier:

Réalisez les consignes suivantes dans l'ordre.

  1. Consigne n° 1: « triez les cartes » en notant le nombre d'opérations nécessaires au tri, recommencer l'opération pour voir si le nombre de tours d'algorithmes varie, et de quoi peut dépendre ce nombre. Ensuite seulement,
  2. Consigne n° 2: « décrivez par écrit la façon précise dont vous vous y êtes pris pour effectuer le tri ».
  3. En plus: imaginez d'autres méthodes qui pourraient être plus efficaces pour effectuer le tri.

Les deux types de tri «quadratiques»

Nous allons cette année voir deux algorithmes de tri pas forcément très efficaces, mais relativement simples.

Dans ces deux algorithmes, on va créer une sous-triée à gauche qui va grandir au fur et à mesure que l'algorithme «avance» jusqu'à ce que la liste soit entièrement triée. On parle de tri en place (in-place en anglais) la liste est triée sans utiliser une autre liste pour stocker les résultats.

  • Le tri par sélection consiste à créer une sous-liste triée à gauche en y ajoutant les éléments non triés dans l'ordre croissant.
  • le tri par insertion consiste à avancer dans la liste et placer la carte considérée à sa place dans la sous-liste triée de gauche.

Créer une liste de données aléatoire

On commence par créer une liste aléatoire d'entiers pour tester nos algorithmes de tri.


Entrée
# Importer le module random pour créer des nombres au hasard
import random

def genere_liste_aleatoire(N, n):
    """Génére une liste aléatoire de N éléments compris entre 0 et n"""
    # Créer une liste vide pour accueillir les nombres
    data = []
    # ajoute les éléments aléatoires dans la liste
    for i in range(N):
        data.append(random.randrange(n))
    return data

# Création d'une liste de 9 valeurs comprises entre 0 et 100
liste_aléatoire = genere_liste_aleatoire(9, 100)
print(liste_aléatoire)
Sortie
[57, 47, 40, 94, 41, 21, 10, 44, 88]

Le tri par sélection

Principe

Sur un tableau de n éléments (numérotés de 0 à n), le principe du tri par sélection est le suivant :

  • rechercher le plus petit élément du tableau, et l'échanger avec l'élément d'indice 0 ;
  • rechercher le second plus petit élément du tableau, et l'échanger avec l'élément d'indice 1 ;
  • continuer de cette façon jusqu'à ce que le tableau soit entièrement trié.

Source Wikipedia

Illustration graphique

Selection-Sort-Animation

Illustration en vidéo

Thumbnail of Youtube video Ns4TPTC8whw

Select-sort with Gypsy folk dance. Created at Sapientia University, Tirgu Mures (Marosvásárhely), Romania. Directed by Kátai Zoltán and Tóth László. In cooperation with "Maros Művészegyüttes", Tirgu Mures (Marosvásárhely), Romania.

Implémentation en python

Voici un exemple de code implémentant cet algorithme de tri présentant l'état de la liste à chaque tour avancée dans le tableau. Vous pouvez voir que le tableau est bien classé en plaçant systématiquement l'élément minimum du tableau restant à trier à la fin des éléments triés.


Entrée
# Création d'une liste de 5 valeurs comprises entre 0 et 20 à trier
data = genere_liste_aleatoire(5, 20)
print("Liste initiale: ", data)

# Calculer la taille du tableau
N = len(data)
# Parcourir le tableau jusqu'à lavant dernière valeur
# en effet la dernière valeur sera forcément la plus grande
for i in range(N - 1):
    print('-' * 80)
    print("i= ", i)
    # Stocker la valeur initiale de la case d'indice i, et son indice
    minimum = data[i]
    i_min = i
    #  Parcourir le reste du tableau pour rechercher l'élément le plus petit restant
    for j in range(i, N):
        if data[j] < minimum:
            # Stocker la valeur du minimum et son indice
            minimum = data[j]
            i_min = j
    # Intervertir la valeur initiale de la case d'indice i et le minimum trouvé
    tmp = data[i]
    data[i] = minimum
    data[i_min] = tmp
    # Affiche les états intermédiaires de la liste
    print("Etat de la liste:", data)
    print("Éléments triés: ", data[:i + 1], "Reste à trier: ", data[i + 1:N])

print("Liste triée: ", data)
Sortie
Liste initiale:  [8, 4, 17, 15, 9]
--------------------------------------------------------------------------------
i=  0
Etat de la liste: [4, 8, 17, 15, 9]
Éléments triés:  [4] Reste à trier:  [8, 17, 15, 9]
--------------------------------------------------------------------------------
i=  1
Etat de la liste: [4, 8, 17, 15, 9]
Éléments triés:  [4, 8] Reste à trier:  [17, 15, 9]
--------------------------------------------------------------------------------
i=  2
Etat de la liste: [4, 8, 9, 15, 17]
Éléments triés:  [4, 8, 9] Reste à trier:  [15, 17]
--------------------------------------------------------------------------------
i=  3
Etat de la liste: [4, 8, 9, 15, 17]
Éléments triés:  [4, 8, 9, 15] Reste à trier:  [17]
Liste triée:  [4, 8, 9, 15, 17]

Le tri par insertion

Principe

Dans l'algorithme, on parcourt le tableau à trier du début à la fin. Au moment où on considère le i-ème élément, les éléments qui le précèdent sont déjà triés. Pour faire l'analogie avec l'exemple du jeu de cartes, lorsqu'on est à la i-ème étape du parcours, le i-ème élément est la carte saisie, les éléments précédents sont la main triée et les éléments suivants correspondent aux cartes encore mélangées sur la table.

L'objectif d'une étape est d'insérer le i-ème élément à sa place parmi ceux qui précèdent. Il faut pour cela trouver où l'élément doit être inséré en le comparant aux autres, puis décaler les éléments afin de pouvoir effectuer l'insertion. En pratique, ces deux actions sont fréquemment effectuées en une passe, qui consiste à faire « remonter » l'élément au fur et à mesure jusqu'à rencontrer un élément plus petit.

Source Wikipedia

Illustration graphique

Insertion-sort-example-300px.gif
"Insertion-sort-example-300px" by Swfung8 - Own work. Licensed under CC BY-SA 3.0 via Wikimedia Commons.

Illustration en vidéo

Thumbnail of Youtube video ROalU379l3U

Insert-sort with Romanian folk dance. Created at Sapientia University, Tirgu Mures (Marosvásárhely), Romania. Directed by Kátai Zoltán and Tóth László. In cooperation with "Maros Művészegyüttes", Tirgu Mures (Marosvásárhely), Romania.

Implémentation en python

Voici un exemple d'implémentation ou le tableau est parcouru de la gauche vers la droite, observer bien ou est placée la valeur à insérer à chaque tour de la boucle.


Entrée
# Création d'une liste de 5 valeurs comprises entre 0 et 20 à trier
data = genere_liste_aleatoire(5, 100)
print("Liste initiale: ", data)

# Calculer la taille du tableau
N = len(data)
# Parcourir l'ensemble de la liste à partir de la deuxième case
# en effet un tableau de 1 case est forcément trié
for i in range(1, N):
    print('-' * 80)
    print("i= ", i)
    # Stocker la valeur à "insérer"
    val = data[i]
    print("Valeur à insérer:", val)
    # Parcourir le tableau déjà trié de dimension i-1 vers la gauche
    # jusqu'à rencontrer une valeur inférieure à notre valeur à insérer
    j = i - 1
    while data[j] > val and j >= 0:
        # Intervertir  les valeurs aux indices j et j+1
        data[j + 1], data[j] = data[j], data[j + 1]
        # Diminuer j de 1 pour la prochaine comparaison
        j = j - 1
        print("On remonte la valeur <-", data)
    print("Etat intérmédiaire de la liste: ", data)
# Afficher le résultat
print('\nListe triée:')
print(data)
Sortie
Liste initiale:  [18, 70, 92, 6, 9]
--------------------------------------------------------------------------------
i=  1
Valeur à insérer: 70
Etat intérmédiaire de la liste:  [18, 70, 92, 6, 9]
--------------------------------------------------------------------------------
i=  2
Valeur à insérer: 92
Etat intérmédiaire de la liste:  [18, 70, 92, 6, 9]
--------------------------------------------------------------------------------
i=  3
Valeur à insérer: 6
On remonte la valeur <- [18, 70, 6, 92, 9]
On remonte la valeur <- [18, 6, 70, 92, 9]
On remonte la valeur <- [6, 18, 70, 92, 9]
Etat intérmédiaire de la liste:  [6, 18, 70, 92, 9]
--------------------------------------------------------------------------------
i=  4
Valeur à insérer: 9
On remonte la valeur <- [6, 18, 70, 9, 92]
On remonte la valeur <- [6, 18, 9, 70, 92]
On remonte la valeur <- [6, 9, 18, 70, 92]
Etat intérmédiaire de la liste:  [6, 9, 18, 70, 92]

Liste triée:
[6, 9, 18, 70, 92]

Autres algorithmes

Ces deux algorithmes ne sont que des exemples d'algorithmes de tri, et il en existe bien d'autres plus efficace comme le fameux quicksort, ou le timsort utilisé comme algorithme par défaut en Python.

La littérature ne manque pas sur ce sujet car il s'agit d'une introduction de choix à de nombreux concepts clés de l'algorithmique:

  • la complexité: l'étude du temps et de la mémoire nécessité par l'algorithme.
  • les cas extremes ou edge cases: que se passe-t-il dans le cas ou la liste est déjà triée, ou au contraire si elle est en ordre inversé.
  • la correction de l'algorithme: comment prouver que l'algorithme donne le bon résultat en toute occasion par une méthode de récurrence mathématique.

Vous pouvez consulter cet article du site interstices.info pour en savoir plus.