Dichotomie
9 mars 2007
static int dicho(int[] t, int i)
int bas=0, haut=t.length-1;
while (bas <= haut) {
int centre = (haut+bas)/2;
if (i==t[centre])
return centre; //(1)
if (i < t[centre])
haut=centre-1;
else
bas=centre+1;
}
return -1;
}
De façon générale, il faut être très attentif sur ce qui se passe lorsque l’intervalle devient très
petit.
Terminaison : si on note l=haut −bas,ldécroit au moins de 1 à chaque passage dans la boucle
où i! = t[centre](en général il est même plus que divisé par 2, mais attention à ce qui peut se
passer pour les petites valeurs. . .).
Nécessairement, si on n’a jamais i== t[centre],lva donc finir par vérifier l < 0, ce qui est la
condition d’arrêt.
Invariant de boucle : «si iest dans le tableau, il est à un indice compris entre bas et haut». En
effet, cette propriété est vraie avant la boucle. Si elle est vraie au début de la boucle (iest dans
[bas, haut]), et si on a par exemple i < t[centre](strictement !), nécessairement, si iest dans
le tableau, il est dans [bas, centre −1] par monotonie du tableau (le seul cas problématique est
celui où t[centre −1] < i < t[centre]. Dans ce cas, in’apparait pas dans le tableau, et notre
propriété reste vraie).
On peut donc maintenant prouver simplement l’algorithme : on voit déjà que s’il retourne, il
retourne une valeur correcte. Reste à voir qu’il ne rate pas i. Si iest dans le tableau, on a à
tout moment que iapparaît entre bas et haut. On commence par regarder ce qu’il se passe
lorsque l== 0 ou l== 1. Une petite étude de cas permet de voir que l’on trouve bien idans
ces cas là. Dans le cas général, on remarque juste que si l’algorithme de retourne pas, il passe
1