Aller au contenu principal

Diviser pour régner

Ce que ce chapitre apporte

  • Mesurer au compteur de pas l'écart entre une recherche linéaire et une recherche dichotomique.
  • Expliquer pourquoi diviser par deux à chaque étape change l'ordre de grandeur du coût.
  • Écrire une recherche dichotomique correcte, dans sa version itérative et dans sa version récursive.
  • Écrire et employer une fonction Tranche qui extrait une portion de tableau.
  • Reconnaître le prix de la dichotomie, et les cas où il n'est pas payable.

Chercher une valeur dans un relevé de quarante-huit mesures coûte quarante-huit examens si l'on procède case par case. Il en coûte cinq si le relevé est trié et que chaque essai élimine la moitié des candidats. Ces deux nombres ne sont pas une estimation : ils se relèvent au compteur de pas de la page, sur le même tableau et la même valeur cherchée. Ce chapitre montre d'où vient l'écart, ce qu'il devient quand les données grandissent, et ce qu'il faut payer pour l'obtenir.

Le chapitre précédent a montré une récursivité qui réduit le problème d'un cran à chaque appel : une case de moins, un chiffre de moins, une unité d'exposant de moins. La réduction était réelle mais avare, et le nombre d'appels restait proportionnel à la taille des données. Il existe une autre façon de réduire, qui consiste à couper le problème en deux à chaque étape. Le nombre d'étapes s'effondre alors, et c'est cet effondrement qui fait la valeur de la méthode.

Deux recherches, deux comptes de pas

Soit un relevé de quarante-huit mesures rangées par ordre croissant, et la valeur 209 à retrouver. Elle se trouve en quarante-septième position, mais l'algorithme ne le sait pas. Voici d'abord la recherche apprise au chapitre sur les tableaux, qui examine les cases une par une.

Algorithme
pas 1 / 97
Fonction RechercheLineaire(t, cible)
Pour i de 1 à longueur(t)
Si t[i] = cible Alors
Retourner i
FinSi
FinPour
Retourner 0
FinFonction
Début
mesures [3, 8, 12, 17, 21, 26, 30, 34, 39, 45, 48, 52, 57, 61, 66, 70, 74, 79, 83, 88, 91, 95, 99, 104, 110, 115, 119, 124, 128, 133, 137, 142, 146, 151, 155, 160, 164, 169, 173, 178, 182, 187, 191, 196, 200, 205, 209, 214]
Écrire "Position : ", RechercheLineaire(mesures, 209)
Fin

programme principal

mesures[3, 8, 12, 17, 21, 26, 30, 34, 39, 45, 48, 52, 57, 61, 66, 70, 74, 79, 83, 88, 91, 95, 99, 104, 110, 115, 119, 124, 128, 133, 137, 142, 146, 151, 155, 160, 164, 169, 173, 178, 182, 187, 191, 196, 200, 205, 209, 214]

Le compteur annonce 97 pas. C'est cohérent : quarante-sept tours de boucle à deux pas chacun, plus l'entrée et la sortie de la fonction. L'algorithme est correct et ne demande rien de particulier aux données.

Voici maintenant la même recherche, sur le même tableau et pour la même valeur, menée autrement. À chaque tour, l'algorithme examine la case du milieu de la zone encore possible. Si cette case porte la valeur cherchée, c'est fini. Sinon, la comparaison indique de quel côté continuer, et l'autre moitié est éliminée sans avoir été regardée.

Algorithme
pas 1 / 32
Fonction Dichotomie(t, cible)
bas 1
haut longueur(t)
TantQue bas <= haut
milieu (bas + haut) DIV 2
Si t[milieu] = cible Alors
Retourner milieu
SinonSi t[milieu] < cible Alors
bas milieu + 1
Sinon
haut milieu - 1
FinSi
FinTantQue
Retourner 0
FinFonction
Début
mesures [3, 8, 12, 17, 21, 26, 30, 34, 39, 45, 48, 52, 57, 61, 66, 70, 74, 79, 83, 88, 91, 95, 99, 104, 110, 115, 119, 124, 128, 133, 137, 142, 146, 151, 155, 160, 164, 169, 173, 178, 182, 187, 191, 196, 200, 205, 209, 214]
Écrire "Position : ", Dichotomie(mesures, 209)
Fin

programme principal

mesures[3, 8, 12, 17, 21, 26, 30, 34, 39, 45, 48, 52, 57, 61, 66, 70, 74, 79, 83, 88, 91, 95, 99, 104, 110, 115, 119, 124, 128, 133, 137, 142, 146, 151, 155, 160, 164, 169, 173, 178, 182, 187, 191, 196, 200, 205, 209, 214]

Le compteur annonce 32 pas, pour la même réponse. Le rapport est de trois pour un, et il ne vient pas d'une écriture plus habile : il vient de ce que la boucle n'a tourné que cinq fois. La figure suivante rend ces cinq tours visibles en affichant chaque case examinée.

Algorithme
pas 1 / 37
Fonction Dichotomie(t, cible)
bas 1
haut longueur(t)
TantQue bas <= haut
milieu (bas + haut) DIV 2
Écrire "test en ", milieu, " : ", t[milieu]
Si t[milieu] = cible Alors
Retourner milieu
SinonSi t[milieu] < cible Alors
bas milieu + 1
Sinon
haut milieu - 1
FinSi
FinTantQue
Retourner 0
FinFonction
Début
mesures [3, 8, 12, 17, 21, 26, 30, 34, 39, 45, 48, 52, 57, 61, 66, 70, 74, 79, 83, 88, 91, 95, 99, 104, 110, 115, 119, 124, 128, 133, 137, 142, 146, 151, 155, 160, 164, 169, 173, 178, 182, 187, 191, 196, 200, 205, 209, 214]
Écrire "Position : ", Dichotomie(mesures, 209)
Fin

programme principal

mesures[3, 8, 12, 17, 21, 26, 30, 34, 39, 45, 48, 52, 57, 61, 66, 70, 74, 79, 83, 88, 91, 95, 99, 104, 110, 115, 119, 124, 128, 133, 137, 142, 146, 151, 155, 160, 164, 169, 173, 178, 182, 187, 191, 196, 200, 205, 209, 214]

Les cases examinées sont les positions 24, 36, 42, 45 et 47. Cinq cases sur quarante-huit, et les quarante-trois autres n'ont jamais été lues. La différence entre les deux algorithmes est exactement là : non pas dans la vitesse d'un examen, mais dans le nombre d'examens nécessaires.

Ce que dit l'écart entre 97 et 32
Le compteur ne récompense pas une astuce d'écriture : les deux fonctions font le même travail par examen. Ce qui change est le nombre d'examens, quarante-sept contre cinq. Et cet écart n'est pas constant : il grandit avec la taille des données, parce que les deux comptes ne grandissent pas de la même façon. Doubler le tableau ajoute quarante-huit examens à la recherche linéaire, et **un seul** à la dichotomie.

Pourquoi couper en deux change l'ordre de grandeur

La recherche linéaire élimine un candidat par examen. La dichotomie en élimine la moitié. La question intéressante est : combien de fois faut-il diviser par deux pour tomber à un seul candidat ?

Taille du relevéExamens en linéaire, au pireDivisions par deux nécessaires
48486
1 0001 00010
1 000 0001 000 00020
1 000 000 0001 000 000 00030

La colonne de gauche est multipliée par mille d'une ligne à l'autre ; la colonne de droite gagne dix. Passer d'un million à un milliard d'enregistrements coûte dix examens de plus à la dichotomie, et neuf cent quatre-vingt-dix-neuf millions à la recherche linéaire. C'est ce genre d'écart qui décide si un traitement est faisable ou non, bien avant toute question de machine ou de langage.

La notation du coût se lit ailleurs
Nommer proprement ces familles de coût, les comparer, distinguer le cas moyen du pire cas : tout cela est traité dans le chapitre consacré à la complexité et au Green IT, avec la notation de Landau et les classes usuelles. Ce chapitre-ci s'en tient à ce que le compteur de pas montre directement.
Les trois fautes classiques de la dichotomie
Écrire milieu ← (bas + haut) / 2 au lieu de DIV. La division ordinaire rend un décimal, et un indice décimal est refusé. La division entière est obligatoire.
Écrire bas ← milieu au lieu de bas ← milieu + 1. La zone ne rétrécit plus quand elle est réduite à deux cases, et la boucle tourne indéfiniment. Le milieu vient d'être examiné : il doit être exclu de la zone restante.
Écrire TantQue bas < haut au lieu de bas <= haut. La zone d'une seule case n'est jamais examinée, et l'algorithme rate la valeur cherchée une fois sur deux, sans jamais se plaindre.

La version récursive dit la même chose plus brièvement, et elle relie ce chapitre au précédent : le cas de base est la zone vide, le cas récursif est une moitié de la zone courante.

Algorithme
pas 1 / 26
Fonction DichotomieR(t, cible, bas, haut)
Si bas > haut Alors
Retourner 0
FinSi
milieu (bas + haut) DIV 2
Si t[milieu] = cible Alors
Retourner milieu
SinonSi t[milieu] < cible Alors
Retourner DichotomieR(t, cible, milieu + 1, haut)
Sinon
Retourner DichotomieR(t, cible, bas, milieu - 1)
FinSi
FinFonction
Début
mesures [3, 8, 12, 17, 21, 26, 30, 34, 39, 45, 48, 52, 57, 61, 66, 70, 74, 79, 83, 88, 91, 95, 99, 104, 110, 115, 119, 124, 128, 133, 137, 142, 146, 151, 155, 160, 164, 169, 173, 178, 182, 187, 191, 196, 200, 205, 209, 214]
Écrire "Position : ", DichotomieR(mesures, 209, 1, longueur(mesures))
Fin

programme principal

mesures[3, 8, 12, 17, 21, 26, 30, 34, 39, 45, 48, 52, 57, 61, 66, 70, 74, 79, 83, 88, 91, 95, 99, 104, 110, 115, 119, 124, 128, 133, 137, 142, 146, 151, 155, 160, 164, 169, 173, 178, 182, 187, 191, 196, 200, 205, 209, 214]

Le compteur descend à 26 pas, et la pile monte à six cadres. La hauteur de pile est ici tout à fait supportable, et pour une raison qui vaut d'être notée : elle vaut le nombre de divisions par deux, donc six pour quarante-huit mesures et trente pour un milliard. Une récursivité qui coupe en deux ne fait jamais déborder la pile, là où une récursivité qui retire une unité la fait déborder dès quelques dizaines de milliers d'éléments.

Le prix : un tableau déjà trié

Tout ce qui précède repose sur une hypothèse qui n'a jamais été discutée : le tableau est trié. Sans elle, la comparaison t[milieu] < cible ne dit rien sur le côté où continuer, et l'algorithme élimine une moitié au hasard.

Algorithme
pas 1 / 36
Fonction Dichotomie(t, cible)
bas 1
haut longueur(t)
TantQue bas <= haut
milieu (bas + haut) DIV 2
Si t[milieu] = cible Alors
Retourner milieu
SinonSi t[milieu] < cible Alors
bas milieu + 1
Sinon
haut milieu - 1
FinSi
FinTantQue
Retourner 0
FinFonction
Début
mesures [45, 3, 88, 12, 99, 26, 61, 34, 8, 70, 17, 91, 21, 52, 39, 104, 30, 66, 79, 48, 83, 57, 95, 74]
Écrire "Position : ", Dichotomie(mesures, 99)
Fin

programme principal

mesures[45, 3, 88, 12, 99, 26, 61, 34, 8, 70, 17, 91, 21, 52, 39, 104, 30, 66, 79, 48, 83, 57, 95, 74]

Le tableau contient bien la valeur 99, en cinquième position. L'algorithme répond Position : 0, c'est-à-dire « absente », en 36 pas. Et il ne signale rien : il a fait son travail, tiré ses conclusions de comparaisons qui ne voulaient rien dire, et rendu une réponse fausse avec l'assurance d'une réponse juste.

Une hypothèse non vérifiée est une faute

C'est le défaut le plus dangereux de ce chapitre, parce qu'il ne se manifeste par aucun arrêt. Un algorithme qui exige une propriété des données doit l'énoncer, et le programme qui l'appelle doit la garantir. Vérifier que le tableau est trié coûterait un parcours complet, soit précisément ce que la dichotomie cherchait à éviter : la garantie doit donc venir d'ailleurs, d'un tri effectué une fois pour toutes en amont.

Cette remarque déplace le problème plutôt qu'elle ne le résout. Si obtenir un tableau trié coûte plus cher que la recherche linéaire qu'on voulait éviter, l'affaire n'est pas rentable. Elle le devient dès que le même tableau est interrogé plusieurs fois : le tri se paie une fois, les recherches se paient par cinq examens. C'est exactement le raisonnement qui justifie un index dans une base de données. Et c'est la raison pour laquelle le chapitre suivant est consacré aux tris.

Tranche : extraire une portion de tableau

La dichotomie ci-dessus travaille sur des indices bas et haut et ne découpe jamais rien : c'est le procédé le plus économique, puisqu'il ne recopie aucune donnée. D'autres algorithmes du même genre ont besoin de vraies portions, manipulables comme des tableaux autonomes. Le tri fusion, au chapitre suivant, coupe le tableau en deux moitiés qu'il traite séparément avant de les réunir. Voici l'outil qui le permet.

Algorithme
pas 1 / 26
Fonction Tranche(t, a, b)
r tableau[b - a + 1]
Pour k de a à b
r[k - a + 1] t[k]
FinPour
Retourner r
FinFonction
Début
t [3, 8, 12, 17, 21, 26, 30]
milieu longueur(t) DIV 2
g Tranche(t, 1, milieu)
d Tranche(t, milieu + 1, longueur(t))
Écrire "gauche : ", longueur(g), " cases, de ", g[1], " à ", g[longueur(g)]
Écrire "droite : ", longueur(d), " cases, de ", d[1], " à ", d[longueur(d)]
Fin

programme principal

t[3, 8, 12, 17, 21, 26, 30]

Trois détails méritent une lecture attentive, car aucun n'est évident avec des indices qui commencent à 1.

La taille vaut b - a + 1, et non b - a. Les deux bornes sont comprises : la tranche de 3 à 7 contient les cases 3, 4, 5, 6 et 7, donc cinq cases. Le + 1 est la trace du fait que la borne de départ compte elle aussi. Oublier ce + 1 produit une tranche amputée de son dernier élément, et le défaut ne se voit pas tant que les tailles sont paires.

Le décalage d'indice s'écrit k - a + 1. La case lue est t[k], la case écrite est r[k - a + 1]. Quand k vaut a, l'expression donne 1 : le premier élément de la tranche va bien dans la première case du résultat. Quand k vaut b, elle donne b - a + 1, la dernière case. Écrire r[k - a] donnerait 0 au premier tour, et l'indice 0 provoque un arrêt immédiat, avec le message qui rappelle que le premier élément porte l'indice 1.

Une tranche est une copie, pas une vue. Tranche(t, 1, 3) fabrique un tableau neuf, rempli case par case. Modifier ce résultat ne modifie pas t, et c'est ce qui rend la fonction sûre à employer. En contrepartie, la copie a un coût proportionnel à la taille de la tranche, ce qui en interdit l'usage dans une boucle interne.

Tranche ne sait pas produire une portion vide
Si `b` est plus petit que `a`, la taille demandée est nulle ou négative, et la réservation `tableau[b - a + 1]` s'arrête sur un message qui rappelle qu'un tableau compte au moins une case. Un algorithme qui coupe en deux doit donc garantir que chaque moitié contient au moins un élément, ce qui se fait en traitant le cas d'un seul élément comme cas de base, avant tout découpage.

Le schéma général

La dichotomie est un cas particulier d'une manière de faire qui porte un nom.

Définition

Diviser pour régner consiste à résoudre un problème en trois temps : diviser les données en portions plus petites, régner en résolvant chaque portion par le même procédé, et combiner les résultats partiels en un résultat global. La récursivité fournit le second temps sans effort, puisque « le même procédé » est la fonction elle-même.

La recherche dichotomique est un cas dégénéré du schéma : elle divise en deux, mais n'en traite qu'une seule moitié, et n'a donc rien à combiner. L'exemple suivant utilise les trois temps, avec Tranche pour le premier.

Algorithme
pas 1 / 150
Fonction Tranche(t, a, b)
r tableau[b - a + 1]
Pour k de a à b
r[k - a + 1] t[k]
FinPour
Retourner r
FinFonction
Fonction Maximum(t)
Si longueur(t) = 1 Alors
Retourner t[1]
FinSi
milieu longueur(t) DIV 2
g Maximum(Tranche(t, 1, milieu))
d Maximum(Tranche(t, milieu + 1, longueur(t)))
Si g > d Alors
Retourner g
FinSi
Retourner d
FinFonction
Début
mesures [12, 47, 8, 33, 61, 25, 19, 40]
Écrire "Maximum : ", Maximum(mesures)
Fin

programme principal

mesures[12, 47, 8, 33, 61, 25, 19, 40]

Le cas de base est un tableau d'une seule case, dont le maximum est son unique élément. Le cas récursif coupe en deux, demande le maximum de chaque moitié, et combine en gardant le plus grand des deux. Le déroulement prend 150 pas et empile cinq cadres, pour huit mesures que le parcours par boucle aurait traitées en bien moins.

Cette figure est donc un contre-exemple utile : ici, diviser pour régner coûte plus cher que la boucle, parce que chaque examen est précédé d'une copie, et que le nombre total d'examens ne diminue pas. Chercher un maximum oblige à regarder toutes les cases, quelle que soit la méthode. La dichotomie ne gagnait pas parce qu'elle coupait en deux, mais parce qu'elle jetait une moitié. C'est la distinction à retenir.

Diviser ne suffit pas
Diviser pour régner ne rapporte que dans deux situations : quand une des portions peut être abandonnée sans être examinée, comme dans la dichotomie, ou quand la combinaison des résultats partiels est nettement moins coûteuse que le traitement direct, comme dans le tri fusion. Découper sans l'un ni l'autre ajoute des copies et des appels à un travail qui n'a pas diminué.

Vérification

Vérification rapideon peut se reprendre

1.Sur le même relevé de 48 mesures, la recherche linéaire compte 97 pas et la dichotomie 32. D'où vient l'écart ?

2.Que produit une recherche dichotomique sur un tableau non trié qui contient pourtant la valeur cherchée ?

3.Pourquoi la taille d'une tranche vaut-elle b - a + 1 ?

4.Écrire bas ← milieu au lieu de bas ← milieu + 1 dans la boucle de dichotomie : que se passe-t-il ?

5.Maximum par découpage en deux moitiés coûte 150 pas là où une boucle en coûterait bien moins. Pourquoi ?

Exercices type

Exercice 1 : écrire un algorithme qui devine un nombre compris entre 1 et 100 par dichotomie, en affichant chaque proposition et le nombre total de propositions nécessaires.

Afficher la solution
Algorithme
pas 1 / 37
Fonction Deviner(cible, bas, haut, tours)
Si bas > haut Alors
Retourner tours
FinSi
milieu (bas + haut) DIV 2
Écrire "proposition ", tours + 1, " : ", milieu
Si milieu = cible Alors
Retourner tours + 1
SinonSi milieu < cible Alors
Retourner Deviner(cible, milieu + 1, haut, tours + 1)
Sinon
Retourner Deviner(cible, bas, milieu - 1, tours + 1)
FinSi
FinFonction
Début
Écrire "trouvé en ", Deviner(73, 1, 100, 0), " propositions"
Fin

programme principal

aucune variable

Deviner

cible73bas1haut100tours0

Les propositions sont 50, 75, 62, 68, 71 et 73 : six essais pour cent possibilités, en 37 pas. Le paramètre tours sert d'accumulateur transmis d'appel en appel, ce qui est la façon récursive de compter sans variable partagée. Aucun nombre entre 1 et 100 ne demande plus de sept propositions, puisque sept divisions par deux suffisent à réduire cent candidats à un seul.

Exercice 2 : calculer la racine carrée entière d'un nombre, c'est-à-dire le plus grand entier dont le carré ne dépasse pas ce nombre, sans utiliser d'autre opération que la multiplication et la comparaison.

Afficher la solution
Algorithme
pas 1 / 124
Fonction RacineEntiere(n)
bas 0
haut n
reponse 0
TantQue bas <= haut
milieu (bas + haut) DIV 2
Si milieu * milieu <= n Alors
reponse milieu
bas milieu + 1
Sinon
haut milieu - 1
FinSi
FinTantQue
Retourner reponse
FinFonction
Début
Écrire "Racine entière de 2025 : ", RacineEntiere(2025)
Écrire "Racine entière de 1000 : ", RacineEntiere(1000)
Fin

programme principal

aucune variable

RacineEntiere

n2025bas0

L'intérêt de cet exercice est qu'il n'y a aucun tableau : la dichotomie porte sur un intervalle de nombres, de 0 à n. Rien n'oblige à ranger quoi que ce soit, parce que la propriété qui remplace le tri est déjà vraie : si un carré dépasse n, tous les carrés plus grands le dépassent aussi. C'est cette propriété de croissance, et non l'existence d'un tableau trié, qui est la vraie condition de la dichotomie.

La variable reponse retient le dernier candidat acceptable rencontré, car la valeur cherchée n'est pas testée pour l'égalité : la boucle cherche une frontière, pas une case. Les résultats affichés sont 45 pour 2025 et 31 pour 1000, en 124 pas pour les deux calculs réunis.

Exercice 3 : écrire la somme d'un tableau selon le schéma diviser pour régner, en employant Tranche, puis comparer son coût à celui de la boucle.

Afficher la solution
Algorithme
pas 1 / 129
Fonction Tranche(t, a, b)
r tableau[b - a + 1]
Pour k de a à b
r[k - a + 1] t[k]
FinPour
Retourner r
FinFonction
Fonction Somme(t)
Si longueur(t) = 1 Alors
Retourner t[1]
FinSi
milieu longueur(t) DIV 2
Retourner Somme(Tranche(t, 1, milieu)) + Somme(Tranche(t, milieu + 1, longueur(t)))
FinFonction
Début
mesures [12, 47, 8, 33, 61, 25, 19, 40]
Écrire "Somme : ", Somme(mesures)
Fin

programme principal

mesures[12, 47, 8, 33, 61, 25, 19, 40]

Le résultat est 245, obtenu en 129 pas et cinq cadres de pile. La boucle du chapitre sur les tableaux aurait fait le même calcul en une trentaine de pas. Le découpage n'apporte donc rien ici, et c'est la leçon de l'exercice : additionner exige de lire chaque case, et aucune moitié ne peut être jetée. Le schéma n'est pas gratuit, et il ne devient rentable que lorsque la division fait disparaître du travail.

La méthode

  1. Chercher ce qu'un examen permet d'éliminer, avant de choisir la méthode. Si un examen élimine un seul candidat, le parcours linéaire est la bonne réponse. S'il en élimine la moitié, la dichotomie s'impose.
  2. Vérifier la propriété que la méthode exige, et l'écrire noir sur blanc : tableau trié, ou fonction croissante sur l'intervalle. Un algorithme dont l'hypothèse n'est pas garantie rend des réponses fausses sans se plaindre.
  3. Poser les trois temps avant d'écrire : ce qui est divisé, ce qui est résolu récursivement, ce qui est combiné. Un temps absent est le signe d'un cas dégénéré, ce qui est permis mais doit être conscient.
  4. Traiter le cas d'un seul élément comme cas de base, sans jamais tenter de découper une portion vide.
  5. Exclure le point de coupe de la portion transmise, milieu + 1 ou milieu - 1. C'est ce qui garantit que la zone rétrécit strictement, donc que la boucle ou la récursion se termine.
  6. Relever deux comptes de pas plutôt que d'argumenter : la méthode naïve et la méthode divisée, sur les mêmes données. L'écart, ou son absence, tranche la question.
  7. Refuser le découpage quand il ne fait rien disparaître. Diviser des données pour ensuite tout examiner ajoute des copies et des appels à un travail inchangé.

Synthèse

  • Sur le même relevé de quarante-huit mesures, la recherche linéaire coûte 97 pas et la dichotomie 32 : l'écart vient du nombre d'examens, quarante-sept contre cinq.
  • Diviser par deux à chaque étape change l'ordre de grandeur du coût : multiplier les données par mille n'ajoute que dix examens.
  • La recherche dichotomique s'écrit avec bas, haut et milieu ← (bas + haut) DIV 2, en excluant toujours la case examinée de la zone restante.
  • La version récursive dit la même chose en moins de lignes, et sa pile ne dépasse jamais le nombre de divisions par deux, soit trente pour un milliard d'éléments.
  • Tranche(t, a, b) extrait une copie de b - a + 1 cases, avec le décalage r[k - a + 1] ← t[k] qu'imposent des indices commençant à 1.
  • Le prix de la dichotomie est un tableau déjà trié : sans cette garantie, la réponse est fausse et silencieuse.
  • Diviser ne rapporte que si une portion est abandonnée sans lecture, ou si la combinaison coûte moins que le traitement direct.

Le prix vient d'être annoncé sans être payé : il reste à savoir comment trier, et ce que cela coûte. Les tris mettent trois méthodes sur les mêmes données et relèvent trois comptes de pas, dont l'une reprendra Tranche et le découpage en deux moitiés de ce chapitre.