edubun
Français

Trier, partie 2 : tri fusion et tri rapide

Trier un million de valeurs en comparant toutes les paires demande environ 500 milliards de comparaisons ; le tri fusion en demande environ 20 millions.

Découper le problème, résoudre les moitiés

Les méthodes de l'unité précédente travaillent sur toute la liste à la fois et le paient d'environ n² comparaisons. Les deux méthodes de cette unité suivent un autre plan, appelé « diviser pour régner ». On découpe la liste en parties plus petites, on trie chaque partie avec la même méthode, puis on combine les parties triées. Le découpage continue jusqu'à ce qu'une partie ait une seule valeur ou aucune, et une liste d'une seule valeur est déjà triée. Comme la méthode s'appelle elle-même sur des listes plus petites, elle est récursive (l'unité 6 étudie la récursivité en détail).

Le tri fusion : le travail est dans la fusion

Le tri fusion coupe la liste en deux, trie la moitié gauche, trie la moitié droite, puis fusionne les deux moitiés triées en une seule. L'astuce est dans la fusion. On peut combiner deux listes triées en ne regardant que leurs valeurs de tête. On compare les deux têtes, on écrit la plus petite et on passe à la suivante. On recommence jusqu'à ce qu'une liste soit vide, puis on recopie ce qui reste de l'autre. Fusionner [1, 4, 7] et [2, 3, 8] donne 1 (1 contre 2), 2 (4 contre 2), 3 (4 contre 3), 4 (4 contre 8), 7 (7 contre 8), puis 8 est recopié : 5 comparaisons pour 6 valeurs. Une fusion de deux listes totalisant n valeurs ne demande jamais plus de n − 1 comparaisons.

function merge(left, right) {
  const out = [];
  let i = 0, j = 0;
  while (i < left.length && j < right.length) {
    if (right[j] < left[i]) out.push(right[j++]);
    else out.push(left[i++]);
  }
  return out.concat(left.slice(i), right.slice(j));
}

function mergeSort(a) {
  if (a.length <= 1) return a;          // déjà triée
  const mid = Math.floor(a.length / 2);
  return merge(mergeSort(a.slice(0, mid)), mergeSort(a.slice(mid)));
}

Pourquoi est-ce rapide ? Imagine les découpages comme des niveaux. Une liste de 8 valeurs se coupe en 2 listes de 4, puis en 4 listes de 2, puis en 8 listes de 1 : trois niveaux, car on peut couper 8 en deux 3 fois. À chaque niveau, toutes les fusions réunies touchent chaque valeur une fois : un niveau coûte donc au plus environ n comparaisons. Avec log₂ n niveaux, le total vaut environ n log₂ n. Pour un million de valeurs, cela fait environ 20 millions de comparaisons, contre environ 500 milliards pour les méthodes qui comparent paire par paire. Coupée en [38, 27, 43, 3] et [9, 82, 10], comme dans le labo, la liste [38, 27, 43, 3, 9, 82, 10] demande 14 comparaisons ; le code ci-dessus la coupe en 3 et 4 et en demande 13.

Le prix à payer, c'est la mémoire. Fusionner exige un endroit où écrire le résultat : le tri fusion utilise donc une seconde liste aussi grande que l'entrée. Le tri fusion est aussi stable : les valeurs égales gardent leur ordre d'origine, car la fusion prend dans la liste de gauche quand les têtes sont égales. Cela compte quand on trie un tableau selon une colonne puis une autre, par exemple par ville puis par nom.

Chargement

Fais glisser pour tourner. Fais défiler ou pince pour zoomer.

Le tri fusion grise la partie en cours de fusion ; le tri rapide marque le pivot en violet. Passe à 40 valeurs et compare les compteurs avec le tri par insertion.

Le tri rapide : partager autour d'un pivot

Le tri rapide (quicksort) divise la liste d'une autre façon. Il choisit une valeur, le pivot, et réorganise la liste pour que tout ce qui est plus petit que le pivot vienne avant lui et tout le reste après. Cette étape s'appelle le partitionnement. Le pivot est alors à sa place définitive, et les deux côtés peuvent être triés séparément avec la même méthode. Il n'y a rien à fusionner ensuite, car chaque valeur de gauche est déjà plus petite que chaque valeur de droite.

Le labo utilise une version de manuel courante qui prend la dernière valeur de chaque partie comme pivot. Sur [5, 1, 4, 2, 8], le pivot 8 est comparé aux quatre autres valeurs, toutes plus petites : 8 reste donc à la fin. La partie suivante, [5, 1, 4, 2], utilise le pivot 2 : seul 1 est plus petit, donc après deux échanges la liste est [1, 2, 4, 5, 8]. Une comparaison de plus règle [4, 5]. Total : 8 comparaisons et 2 échanges.

Quand le pivot tombe près du milieu, chaque partage coupe le problème en deux et le tri rapide demande environ n log₂ n comparaisons, comme le tri fusion. Il fonctionne aussi à l'intérieur de la liste d'origine, sans seconde copie. Mais un mauvais pivot fait mal. Si la liste est déjà triée et que le pivot est toujours la dernière valeur, chaque partage ne détache qu'une seule valeur, et le tri rapide retombe à environ n²/2 comparaisons : 10 pour [1, 2, 3, 4, 5], autant que le tri par sélection. Les vraies bibliothèques évitent cela en choisissant le pivot plus soigneusement, par exemple au hasard ou comme la médiane de trois valeurs prises en exemple.

ContexteLes deux méthodes ont une origine connue. Le tri fusion a été proposé par John von Neumann en 1945, à l'époque où l'on concevait les premiers ordinateurs à programme enregistré. Le tri rapide vient de Tony Hoare, un étudiant britannique de l'université d'État de Moscou, en 1959. On lui avait proposé de travailler sur la traduction automatique du russe vers l'anglais, et comme le dictionnaire était stocké sur bande magnétique, les mots de chaque phrase devaient d'abord être rangés par ordre alphabétique. Sa première idée prenait un temps proportionnel au carré de la longueur de la phrase ; la seconde est devenue le tri rapide. Il l'a publié en 1961.
MéthodeComparaisonsMémoire supplémentaire
Tri par insertionen général environ n²/4, au pire environ n²/2aucune ; stable
Tri fusionenviron n log₂ n, toujoursune seconde liste de n valeurs ; stable
Tri rapideen général environ n log₂ n, au pire environ n²/2 (mauvais pivots)peu ; les versions courantes ne sont pas stables
Un tri par comparaisons peut-il faire mieux que n log₂ n ? Non. Un tri qui n'apprend qu'en comparant des paires doit pouvoir distinguer les n! ordres de départ possibles, et chaque comparaison a deux issues : le pire cas demande donc au moins log₂(n!) comparaisons, ce qui croît comme n log₂ n. Pour 10 valeurs, cette borne vaut 22 comparaisons.
diviser pour régnerDécouper un problème, résoudre les parties de la même façon, combiner les résultats
fusionCombiner deux listes triées en prenant à chaque fois la plus petite valeur de tête
tri fusionCouper en deux, trier chaque moitié, fusionner : environ n log₂ n comparaisons
pivotLa valeur autour de laquelle le tri rapide partage la liste
partitionnementRéorganiser pour que les valeurs plus petites soient avant le pivot et les autres après
tri rapidePartitionner autour d'un pivot, puis trier chaque côté
tri stableLes valeurs égales gardent leur ordre d'origine
en placeTrie à l'intérieur de la liste d'origine avec peu de mémoire supplémentaire
  1. Combien de comparaisons faut-il pour fusionner [1, 4, 7] et [2, 3, 8] ?
  2. Combien de comparaisons faut-il pour fusionner [1, 2, 3] et [4, 5, 6] ?
  3. Une liste de 16 valeurs est coupée en deux jusqu'à ce que chaque partie ait une seule valeur. Combien y a-t-il de niveaux de découpage ?
  4. À peu près combien de comparaisons le tri fusion fait-il sur un million de valeurs ?
    • environ 20
    • environ 20 millions
    • environ 500 milliards
    • exactement un million
  5. Après le partitionnement, où est le pivot ?
    • À sa position définitive dans l'ordre trié
    • Au début
    • À la fin
    • N'importe où ; il bouge encore plus tard
  6. Le tri rapide avec la dernière valeur comme pivot s'exécute sur la liste déjà triée [1, 2, 3, 4, 5]. Combien de comparaisons fait-il ?
  7. Quelle méthode a besoin d'une seconde liste aussi grande que l'entrée ?
    • Tri fusion
    • Tri rapide
    • Tri par insertion
  8. Qui a proposé le tri fusion en 1945 ?
    • Tony Hoare
    • John von Neumann
    • Ada Lovelace
    • Euclide
  9. Quel problème a conduit Tony Hoare au tri rapide ?
    • Trier les mots d'une phrase pour un dictionnaire sur bande magnétique
    • Trier des livres de bibliothèque
    • Classer des pages web
    • Trier des chèques bancaires
  10. Pourquoi dit-on que le tri fusion est stable ?
    • Les valeurs égales gardent leur ordre d'origine
    • Il ne plante jamais
    • Il prend toujours le même temps
    • Il n'utilise pas de mémoire supplémentaire
  11. Quel est le plus petit nombre possible de comparaisons dans le pire cas pour un tri par comparaisons de 10 valeurs (log₂ 10!, arrondi à l'entier supérieur) ?
L'essentiel
  • Diviser pour régner : découper, résoudre les parties, combiner.
  • Tri fusion : toujours environ n log₂ n comparaisons, besoin de mémoire supplémentaire, stable.
  • Tri rapide : partitionner autour d'un pivot ; rapide en moyenne, environ n²/2 avec de mauvais pivots.
  • Un million de valeurs : environ 20 millions de comparaisons au lieu de 500 milliards.
  • Aucun tri par comparaisons ne peut faire mieux qu'environ n log₂ n dans le pire cas.
Sources de ce cours (11)
  • MIT OpenCourseWare 6.006 Introduction to Algorithms, Spring 2020 (Demaine, Ku, Solomon)
  • lecture notes 1 Introduction, 3 Sorting, 9 Breadth-First Search, 10 Depth-First Search (ocw.mit.edu/courses/6-006-introduction-to-algorithms-spring-2020/pages/lecture-notes) and Fall 2011 lecture 13 BFS notes (ocw.mit.edu/courses/6-006-introduction-to-algorithms-fall-2011)
  • Cormen, Leiserson, Rivest, Stein, Introduction to Algorithms (MIT Press)
  • with the CLRS-based Khan Academy algorithms unit by Thomas Cormen and Devin Balkcom of Dartmouth (khanacademy.org/computing/computer-science/algorithms: binary search, selection sort analysis, merge sort, quicksort overview and analysis)
  • MacTutor History of Mathematics, Al-Khwarizmi (mathshistory.st-andrews.ac.uk/Biographies/Al-Khwarizmi: word algorithm from the Latin title Algoritmi de numero Indorum)
  • D. E. Joyce, Euclid's Elements Book VII Propositions 1 and 2 (mathcs.clarku.edu/~djoyce/elements/bookVII)
  • Wolfram MathWorld, Merge Sort (mathworld.wolfram.com/MergeSort.html: proposed by John von Neumann in 1945, after Knuth 1998 p. 159)
  • Stanford CS "Tony Hoare: Quicksort" (cs.stanford.edu/people/eroberts/courses/soco/projects/2008-09/tony-hoare/quicksort.html: devised while a student at Moscow State University for Russian-English machine translation with a tape dictionary, programmed in Algol 60 and published 1961; the year 1959 from the Wikipedia Quicksort article and its cited sources)
  • Bodleian Libraries, Ada Lovelace (blogs.bodleian.ox.ac.uk/adalovelace: 1843 paper, Note G Bernoulli numbers)
  • Fourmilab text of Menabrea's Sketch with Lovelace's notes (fourmilab.ch/babbage/sketch.html)
  • Seven Bridges of Konigsberg (Euler 1736) and Tower of Hanoi (Edouard Lucas, 1883) checked against the Wikipedia articles and their cited sources.

Consulté le: 2026-10-17