edubun
Français

À quelle vitesse ? La notation grand O

À un milliard d'étapes par seconde, une méthode en n² sur un million de valeurs prend environ 17 minutes ; une méthode en n log n prend 0.02 seconde.

La croissance compte plus que le nombre exact

Jusqu'ici, nous avons compté les étapes exactement : 45 comparaisons, 4 échanges, 20 vérifications. Les comptes exacts sont utiles pour de petits exemples, mais ils dépendent de détails, comme le fait que le tri à bulles s'arrête plus tôt ou la façon de choisir un pivot. Quand l'entrée devient grande, une chose domine tout le reste : la façon dont le compte augmente quand n augmente. Un algorithme dont le nombre d'étapes croît comme n² finira toujours par perdre face à un algorithme qui croît comme n log n, quel que soit le soin apporté au réglage du premier.

La notation grand O est le raccourci qui décrit cette croissance. Écrire qu'un algorithme est en O(n²), qu'on lit « grand O de n au carré », signifie que pour n grand son nombre d'étapes est au plus une certaine constante fois n². Deux règles la rendent facile à utiliser. On supprime les facteurs constants : 3n et n/2 sont tous deux en O(n). On ne garde que le terme qui croît le plus vite : n²/2 − n/2, les comparaisons du tri par sélection, est en O(n²), car pour n grand la partie n² représente presque tout. Le cours 6.006 du MIT utilise la même idée quand il compare des structures de données et des tris par leur temps d'exécution asymptotique.

Les ordres de croissance courants

  • O(1), constant. Le travail ne dépend pas de n : lire la première valeur d'une liste, ou une valeur à une position connue.
  • O(log n), logarithmique. Chaque étape coupe le problème en deux : la recherche dichotomique. Un million de valeurs, environ 20 étapes.
  • O(n), linéaire. Chaque valeur est traitée une fois : la recherche linéaire, trouver la plus grande valeur, additionner une liste.
  • O(n log n). Le tri fusion, et le tri rapide en moyenne. Le mieux que puisse faire un tri par comparaisons.
  • O(n²), quadratique. Chaque paire est examinée : le tri à bulles, par sélection et par insertion dans le pire cas, ou deux boucles imbriquées l'une dans l'autre.
  • O(2ⁿ), exponentiel. Le travail double à chaque valeur supplémentaire : essayer tous les sous-ensembles de n objets, ou déplacer n disques dans les tours de Hanoï.
Chargement

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

Six ordres de croissance tracés sur les mêmes axes. Fais varier n et active l'échelle log ; le tableau donne le nombre d'étapes pour ton n et la durée pour un million de valeurs à un milliard d'étapes par seconde.

Ce que les nombres signifient en secondes

Imagine un ordinateur qui effectue un milliard (10⁹) d'étapes élémentaires par seconde, un chiffre rond raisonnable pour un cœur de processeur. Voici ce que chaque ordre de croissance signifie pour un million de valeurs. O(log n) représente environ 20 étapes, bien moins d'une microseconde. O(n) représente un million d'étapes, une milliseconde. O(n log n) représente environ 20 millions d'étapes, 0.02 seconde. O(n²) représente 10¹² étapes, mille secondes, soit environ 17 minutes. O(2ⁿ) ne peut pas être terminé : 2 puissance un million est un nombre de plus de 300 000 chiffres. C'est pourquoi choisir le bon algorithme compte en général bien plus qu'acheter un ordinateur plus rapide. Une machine dix fois plus rapide transforme 17 minutes en 1.7 minute ; passer de O(n²) à O(n log n) les transforme en un cinquantième de seconde.

CroissanceÉtapes pour n = 1 000 000Durée à 10⁹ étapes par seconde
O(1)1environ une nanoseconde
O(log n)environ 20environ 20 nanosecondes
O(n)1,000,0001 milliseconde
O(n log n)environ 20 000 000environ 0.02 seconde
O(n²)1,000,000,000,000environ 17 minutes
O(2ⁿ)plus de 300 000 chiffresne se termine jamais

Lire le grand O dans le code

On peut souvent lire l'ordre de croissance directement dans la forme du code. Une seule boucle sur la liste est en O(n). Deux boucles, l'une dans l'autre, toutes deux sur la liste, sont en O(n²) : pour chacun des n tours extérieurs, la boucle intérieure fait jusqu'à n tours. Une boucle qui divise un nombre par deux à chaque fois, comme while (n > 1) n = Math.floor(n / 2), est en O(log n) : en partant de 1000, elle tourne 9 fois, en partant d'un million, 19 fois. Les étapes qui se suivent s'additionnent, et c'est le plus grand terme qui l'emporte : une boucle en O(n) suivie d'une boucle en O(n²) donne O(n²) au total.

// O(n) : un seul passage
let total = 0;
for (const x of list) total += x;

// O(n²) : toutes les paires
for (let i = 0; i < list.length; i++)
  for (let j = i + 1; j < list.length; j++)
    if (list[i] === list[j]) console.log("duplicate", list[i]);

// O(log n) : divisions par deux
let k = list.length, rounds = 0;
while (k > 1) { k = Math.floor(k / 2); rounds++; }

Meilleur cas, cas moyen et pire cas

Un même algorithme peut se comporter très différemment selon les entrées. Le tri par insertion est en O(n) sur une liste déjà triée et en O(n²) sur une liste inversée. Le tri rapide est en O(n log n) en moyenne et en O(n²) avec des pivots toujours mauvais. Quand on cite un seul grand O sans préciser le cas, on parle en général du pire cas, car c'est une garantie : l'algorithme ne fera jamais pire. Le grand O laisse aussi des choses de côté. Il ignore les facteurs constants : pour de petites entrées, une méthode en O(n²) aux étapes très simples peut battre une méthode en O(n log n). C'est pourquoi beaucoup de vraies fonctions de tri passent au tri par insertion pour les petits morceaux de la liste.

Le grand O peut décrire la mémoire aussi bien que le temps. Le tri fusion utilise O(n) de mémoire supplémentaire pour sa seconde liste ; le tri par insertion utilise O(1) de mémoire supplémentaire, juste quelques variables.
Grand OComment le nombre d'étapes croît avec n, sans tenir compte des facteurs constants
O(1)Constant : le même travail quel que soit n
O(log n)Logarithmique : division par deux à chaque étape, comme dans la recherche dichotomique
O(n)Linéaire : un passage sur l'entrée
O(n log n)Le tri fusion ; le mieux pour un tri par comparaisons
O(n²)Quadratique : toutes les paires, deux boucles imbriquées
O(2ⁿ)Exponentiel : double à chaque élément supplémentaire
pire casUne garantie : l'algorithme ne fait jamais plus que cela
  1. Comment s'écrit 3n² + 5n + 2 en notation grand O ?
    • O(n)
    • O(n²)
    • O(3n²)
    • O(n² + n)
  2. Deux boucles imbriquées l'une dans l'autre, chacune sur n valeurs. Grand O ?
    • O(n)
    • O(2n)
    • O(n²)
    • O(log n)
  3. La recherche dichotomique est en
    • O(1)
    • O(log n)
    • O(n)
    • O(n log n)
  4. Une méthode en O(n²) prend 2 secondes pour 1000 valeurs. Environ combien de secondes pour 10 000 valeurs ?
  5. Une méthode en O(n) prend 2 secondes pour 1000 valeurs. Environ combien de secondes pour 10 000 valeurs ?
  6. À 10⁹ étapes par seconde, combien de secondes prennent 10¹² étapes (une méthode en n² sur un million de valeurs) ?
  7. Combien de fois while (n > 1) n = Math.floor(n / 2) tourne-t-elle quand n vaut 64 au départ ?
  8. Un programme exécute une boucle en O(n) puis une boucle en O(n²). Au total, il est en
    • O(n)
    • O(n²)
    • O(n³)
    • O(n + 2)
  9. Le tri par insertion sur une liste déjà triée est en
    • O(1)
    • O(n)
    • O(n log n)
    • O(n²)
  10. Pourquoi une méthode en O(n²) peut-elle battre une méthode en O(n log n) sur de petites entrées ?
    • Le grand O ignore les facteurs constants, et la méthode la plus simple peut faire moins de travail par étape
    • Le grand O est faux pour les petits n
    • n² est plus petit que n log n pour tout n
    • Les petites entrées sont toujours triées
  11. La mémoire supplémentaire du tri fusion est en
    • O(1)
    • O(log n)
    • O(n)
    • O(n²)
  12. Range ces ordres de croissance du plus lent au plus rapide.
L'essentiel
  • Le grand O décrit comment le nombre d'étapes croît avec n, sans tenir compte des facteurs constants ni des termes plus petits.
  • Ordres courants : 1, log n, n, n log n, n², 2ⁿ.
  • Un million de valeurs à 10⁹ étapes/s : n log n environ 0.02 s, n² environ 17 minutes.
  • Une boucle est en O(n) ; deux boucles imbriquées en O(n²) ; des divisions par deux en O(log n).
  • Un grand O cité seul désigne en général 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