Adloun

informatique (MP2I/MPI) · Chapitre 15 · Application directe du cours

Problème — Le tri par partition-fusion sur tableaux : coût exact et stabilité

Diviser pour régner · niveau 3 (difficile)

Énoncé

La version du cours travaille sur des listes. On la veut sur tableaux.

  • Écrire le tri, avec un tampon unique alloué une seule fois.
  • Compter exactement ses comparaisons sur un tableau trié, un tableau inverse, un tableau aléatoire.
  • Le tri est-il stable — deux éléments égaux gardent-ils leur ordre ? De quoi cela dépend-il ?
  • Combien de mémoire supplémentaire ? Peut-on descendre en dessous ?

Corrigé de la question 1

1. Le tri.


(* Trie t par ordre croissant, en place, à l'aide d'un tampon de taille n.
   Précondition : aucune. Complexité : Theta(n log n) en temps, Theta(n) en espace.
   Le tampon est alloué UNE fois : une allocation par appel récursif ferait
   n log n allocations pour rien. *)
let tri_fusion t =
  let n = Array.length t in
  if n > 1 then begin
    let tampon = Array.make n t.(0) in
    let rec trier g d =                       (* trie t.[g .. d-1] *)
      if d - g > 1 then begin
        let m = g + (d - g) / 2 in
        trier g m; trier m d;
        let i = ref g and j = ref m and k = ref g in
        (* INVARIANT : tampon.[g .. k-1] contient, triés, les éléments déjà pris
           dans t.[g .. i-1] et t.[m .. j-1]. *)
        while !i < m && !j < d do
          if t.(!i) <= t.(!j)                 (* <= et non < : voir question 3 *)
          then begin tampon.(!k) <- t.(!i); incr i end
          else begin tampon.(!k) <- t.(!j); incr j end;
          incr k
        done;
        while !i < m do tampon.(!k) <- t.(!i); incr i; incr k done;
        while !j < d do tampon.(!k) <- t.(!j); incr j; incr k done;
        Array.blit tampon g t g (d - g)
      end
    in trier 0 n
  end

Terminaison : variant , divisé par deux à chaque appel ; les trois boucles ont pour variant . Correction : l'invariant écrit ci-dessus, plus le fait que les deux moitiés sont triées par hypothèse de récurrence.

Question 2 : comment l'IA t'aide

2. Compter exactement ses comparaisons sur un tableau trié, un tableau inverse, un tableau aléatoire.

Élève

Je pensais qu'une fusion de deux moitiés faisait toujours comparaisons, donc environ au total, quel que soit le tableau. Mais le compteur donne nettement moins sur un tableau trié.

IA

Regarde la première boucle de fusion : jusqu'à quand compare-t-elle ? Sur un tableau déjà trié, que se passe-t-il pour la moitié gauche au cours de chaque fusion ?

Élève

Elle compare tant que les deux moitiés ont des éléments. Sur un tableau trié, tous les éléments de gauche passent d'abord : la gauche s'épuise, et la droite est recopiée sans comparaison.

IA

C'est cela. Combien de comparaisons cela fait-il par niveau de récursion, et combien y a-t-il de niveaux ? Le tableau inverse se comporte-t-il de même, et à quelle borne comparer le cas aléatoire ?

L'IA ne donne pas la réponse : elle pose la question qui fait avancer. À toi de continuer.

Continue cet exercice avec l'IA

Reprends la question 2 là où le dialogue s'arrête, puis la suite de l'exercice.

Continuer avec l'IA — gratuit, sans inscription

Gratuit, sans inscription. L'IA te guide pas à pas, sans te donner la réponse.

Le cours du chapitre · Tous les exercices du chapitre

Continuer avec l'IA, gratuit →