Recherche dichotomique récursive, prouvée
Exercice · niveau 2 · informatique (MP2I/MPI), chapitre 5 — Récursivité
Énoncé
Écrire une recherche dichotomique récursive dans un tableau trié, avec spécification, terminaison, correction et complexité.
Corrigé
(* cherche t x renvoie un indice i tel que t.(i) = x, ou -1 si x est absent.
Precondition : t est trie par ordre croissant.
La fonction auxiliaire travaille sur la tranche t.(g .. d-1). *)
let cherche t x =
let rec aux g d =
if g >= d then -1
else
let m = g + (d - g) / 2 in
if t.(m) = x then m
else if t.(m) < x then aux (m + 1) d
else aux g m
in aux 0 (Array.length t)
Terminaison. Variant : , entier positif (l'appel n'a lieu que si ). Comme , la tranche a pour largeur , et la tranche a pour largeur . Le variant décroît strictement, et il est minoré par : la récursion s'arrête.
Correction. Invariant, au sens de la récurrence sur le variant : si figure dans , alors il figure dans la tranche . Il tient à l'appel initial (la tranche est le tableau entier). Il se conserve : le tableau étant trié, si tout indice porte une valeur , donc ne peut être qu'à droite ; symétriquement à gauche. À l'arrêt, ou bien on a trouvé en , ou bien la tranche est vide et l'invariant dit alors que n'est nulle part.
Complexité. La largeur est au moins divisée par deux à chaque appel : , deuxième récurrence du cours avec , donc comparaisons. Mesuré : le nombre maximal d'appels vaut exactement .
n : 1 7 15 1000 1000000
appels au pire : 2 4 5 11 21
floor(log2 n) + 2 : 2 4 5 11 21
En espace, la profondeur de pile est — soit blocs pour un million d'éléments. C'est l'exemple annoncé par la mise en garde du cours : une récursion sur éléments un par un coûte en pile, la même en dichotomie coûte .
Deux fautes classiques que la preuve écarte. Écrire aux m d au lieu de aux (m+1) d : le variant ne décroît plus quand , et la fonction boucle. Écrire (g + d) / 2 : correct en OCaml, où les entiers font bits, mais générateur de dépassement en C sur de grands indices — on y écrit g + (d - g) / 2, comme au chapitre chap:langage-c.
Les autres exercices de ce chapitre Le cours du chapitre
Un blocage sur cet exercice ? Le tuteur d'Adloun guide par questions, sans donner la réponse.