Aller au contenu

Algorithmes de tris

Un opération que l'on veut faire couramment sur des lists est le tri. Un tri consiste à réorganiser les éléments selon un ordre.

Par exemple, si on trie la liste 1, 5, 2, 7, 8 par ordre croissant, on obtient 1, 2, 5, 7, 8.

Il y a de nombreuses raisons de vouloir trier une liste, comme par exemple avoir un affichage plus lisible pour un humain. Une autre raison est de pouvoir utiliser des algorithmes plus efficaces.

Activité : liste triée ?

Prenez les cartes du chapitre précédent (2 - 10 et l'As). Retirez le 3. Appliquez l'algorithme du chapitre précédent pour trouver le 3 (qui est absent) et comptez le nombre de fois où vous retournez une carte.

Récupérez les cartes et triez-les de la plus forte à la moins forte. Vous pouvez regarder toutes les cartes à la fois pour les trier. Laissez toujours le 3 en dehors du paquet. Disposez-les ensuite face cachée, de la moins forte (à gauche) à la plus forte (à droite). Appliquez l'algorithme suivant en comptant le nombre de cartes que vous retournez :

On commence par la carte de gauche, qui devient la *carte courante*.
(1) On retourne la *carte courante* : 
    - Si elle est le 3, on s'arrête et le 3 est présent.
    - Sinon, si elle est plus forte que le 3, on s'arrête et le 3 n'est pas présent.
    - Sinon, si elle n'a pas de carte à sa droite, on s'arrête et le 3 n'est pas présent.
    - Sinon, la carte à sa droite devient la *carte courante*, et on retourne en (1).

Si on n'exclut le temps passé pour trier les cartes, quel algorithme vous a fait retourner le moins de cartes ?

Tri de cartes

Bon c'est bien sympa, mais... Comment on trie une liste ? Et là normalement vous devez vous dire quelque chose comme :

Oueche le prof il est teubé, il nous a fait trier les cartes juste avant, on sait faire, lol !

Oui, mais rappelez-vous de les contraintes qu'on s'était fixé à la base :

On supposera les cartes posées sur la table, côte à cote sur une ligne, face cachée. On s'autorisera, au maximum, à avoir deux cartes face visible à la fois, et à ne déplacer que des cartes visibles.

Et là, vous faites moins les marioles. Allez hop, activité !

Actitivé

Proposez un algorithme qui permet de trier les cartes de la moins forte (a gauche) à la plus forte (à droite) en respectant la règle mentionnée plus haut. Vous montrerez cette méthode aux autres groupes.

Cette activité est longue et difficile ! Ne perdez pas espoir !

Essayez de trier les cartes face visible et observez comment vous faites.

Essayez de trier un petit nombre de cartes, par exemple 4 ou 5, puis passez à un grand nombre quand vous pensez avoir la solution.

Peut-être que vous aurez besoin de chercher la carte la moins forte dans une partie de la liste. N'hésitez pas à élaborer un sous-algorithme pour celà.

Essayez éventuellement de "reconstituer" une autre liste triée, à côté, en déplaçant les cartes.

Numérotons les positions des cartes de gauche à droite en partant de 0. On supposera qu'on a n cartes.

Voici un algorithme qui permet de trouver la carte la moins forte :

Si il n'y a qu'une carte, alors c'est celle-ci la moins forte et on s'arrête.

On retourne la carte la plus a gauche, face visible.
La deuxième carte en partant de la gauche devient la *carte courante*.
(1) On retourne la carte courante face visible: 
    - On retourne la carte la plus des deux cartes visibles en face cachée.
    - Si il n'y a pas de carte à droite de la *carte courante*, on va en (2)
    - Sinon, la carte à droite de la *carte courante* devient la *carte courante*.
(2) La carte la plus faible est celle qui est face visible. On s'arrête.

Voici un algorithme qui permet de trier les cartes :

Pour i allant de 0 à n - 1 (exclut):
    On trouve la carte la moins forte parmi les cartes i à n -1, et on l'échange de place avec la carte en position i.

Tri par sélection

TODO (prof) ici ajouter des étapes pour passer des cartes à l'algo ?

On peut commenser par définir un algorithme qui fait la recherche du minumum dans une partie de la liste.

(recherche indice minimum)
Entrée : une liste (ou tableau) l, de longueur n > 0, un entier i < n
Sortie : m est l'indice de la plus petite valeur dans l à partir de la position i inclus

m = i
pour j allant de i + 1 à n (exclut):
    si l[j] < l[m]:
        m = j

Le tri par sélection est alors :

(tri par sélection)
Entrée : une liste (ou tableau) l, de longueur n
Sortie : la liste (ou tableau) l est triée en ordre croissant

pour i allant de 0 à n - 1 (exclut):
    rechercher l'indice m de la plus petite valeur de l à partir de l'indice i.
    echanger l[i] et l[m]

D'un seul bloc, le pseudocode du tri par sélection est:

(tri par sélection)
Entrée : une liste (ou tableau) l, de longueur n
Sortie : la liste (ou tableau) l est triée en ordre croissant

pour i allant de 0 à n - 1 (exclut):
    m = i
    pour j allant de i + 1 à n (exclut):
        si l[j] < l[m]:
            m = j 
    echanger l[i] et l[m]

Tri par insertion

Activité : insertion triée

Retirez deux cartes au hasard de votre paquet, sans les regarder. Triez les cartes restantes comme vous le souhaitez, puis disposez les dans l'ordre fache cachée, côte à côte.

Toujours en respectant les contraintes précédentes, proposez un algorithme qui permet d'ajouter une carte à votre liste de carte face cachée. A la fin de votre ajout, votre liste de carte doit être triée.

Attention, vous ne pouvez déplacer que des cartes face visible !

Voici un algorithme possible :

On ajoute la carte à insérer toute à droite de la liste (donc du côté de la carte la plus forte), face visible.  

tant que la carte à insérer a une carte à sa gauche : 
    on retourne la carte à sa gauche face visible. 
    Si la carte à insérer est moins forte que la carte à sa gauche, on les échange de place, puis on retourne en face cachée la carte à la gauche de la carte à insérer.
    Si la carte à insérer est plus forte ou aussi forte que la carte à sa gauche, on s'arrête.

On pose la carte à un des deux bouts de la liste. Puis on trie la liste.

Activité : tri par insertion

Proposez un algorithme qui utilise l'insertion triée dans une liste de cartes pour trier une liste de cartes.

Essayez d'abord en recréant une nouvelle liste triée.

Numérotons les cartes de 0 à n-1.

Pour chaque i de 0 position 0 à n-1:
    On insère la carte en position i dans la liste de carte qui couvre les positions de 0 à i-1.

L'algorithme de sélection peut donc être décrit comme suit :

(insertion triée)
Entree : une liste l de n éléments, i un entier < n. les i-1 premiers éléments de l sont triés en ordre croissant.
Sortie : Les i premiers éléments de l sont triés en ordre croissant.

j = i
tant que j > 0 et l[j] < l[j-1]:
    echanger l[j] et l[j-1] 
    j = j - 1
(tri par insertion)
Entrée : une liste (ou tableau) l, de longueur n
Sortie : la liste (ou tableau) l est triée en ordre croissant

pour i allant de 1 à n - 1 (inclus):
    on fait une insertion triée avec l et i

D'un seul bloc, le pseudocode du tri par insertion donne :

Entrée : une liste (ou tableau) l, de longueur n
Sortie : la liste (ou tableau) l est triée en ordre croissant

pour i allant de 1 à n - 1 (inclus):
    j = i
    tant que j > 0 et l[j] < l[j-1]:
        echanger l[j] et l[j-1] 
        j = j - 1

Comparateur

En fait, parfois on veut pouvoir trier de plusieurs manières différentes : ordre croissant, ordre décroissant, ...

Activité : ordre des cartes

Proposez au moins 3 manières différentes d'ordonner les cartes.

  • Par "force", sans regarder les couleurs
  • Par "numéros", en considérant J = 11, Q = 12, K = 13 et A = 1
  • Par "couleurs puis force", c'est à dire d'abord par couleur (trefle < pique < carreau < coeur), puis dans chaque couleur par "force".

En fait, pour trier, seul l'ordre change, et non le principe de l'algorithme de tri. Dans notre tri par sélection plus haut, l'ordre est donné par le comparateur <.

TODO (prof) continuer ici