Adloun

Recherche séquentielle, dichotomique, arrière

Cours · algorithmique (école d'ingénieur), chapitre 12 · école d'ingénieur, informatique · le début du chapitre, la suite sur Adloun

Objectifs du chapitre

  • Écrire une recherche séquentielle à partir de son invariant, et en connaître la complexité .
  • Écrire sans erreur une recherche dichotomique dans un tableau trié, à partir d'un invariant sur un intervalle semi-ouvert , et justifier sa complexité .
  • Savoir parcourir un tableau « à rebours » (recherche arrière) : dernière occurrence, insertion dans un préfixe trié, recherche en escalier dans un tableau à deux dimensions.

Chercher une valeur est sans doute l'opération la plus fréquente d'un programme. Ce chapitre présente trois façons de parcourir l'espace de recherche : du début vers la fin (séquentielle), en coupant l'espace en deux à chaque étape (dichotomique), de la fin vers le début (arrière). Chaque programme est écrit à partir d'une propriété invariante, selon la méthode du chapitre 11 : initialisation, progression, arrêt.

12.1 Recherche séquentielle

Problème

Un tableau et une valeur sont donnés. Retourner le premier indice tel que , ou si n'est pas dans .

On parcourt le tableau de gauche à droite. À tout instant, on a examiné les cases d'un préfixe sans y trouver . C'est l'invariant :


static int rechercheSeq(int[] T, int x) { int n = T.length;
    int i = 0;
    // I(i) : x n'est pas dans T[0:i]
    while (i < n && T[i] != x)
        i = i + 1;       // I(i) et T[i] != x ==> I(i+1)
    // I(i) et (i == n ou T[i] == x)
    if (i == n) return -1; // x n'est pas dans T[0:n]
    return i;              // T[i] == x et x n'est pas dans T[0:i]
}

Attention

L'ordre des deux conditions de la boucle est essentiel. En Java, l'opérateur && n'évalue sa seconde opérande que si la première est vraie : quand , la case (qui n'existe pas) n'est jamais lue. Écrire T[i] != x && i < n provoquerait une ArrayIndexOutOfBoundsException lorsque est absent.

Complexité.

Le corps de boucle est en temps constant ; il est exécuté au plus fois. Dans le pire cas ( absent, ou présent seulement en dernière case), le temps de calcul est de la forme : la recherche séquentielle est en . On ne peut pas faire mieux sur un tableau quelconque : tant qu'une case n'a pas été lue, elle pourrait contenir .

12.2 Recherche dichotomique

Si le tableau est trié, chaque case lue renseigne aussi sur ses voisines. Comparer à la case du milieu permet d'éliminer d'un seul coup la moitié du tableau : c'est la dichotomie (du grec : « couper en deux »). C'est ainsi que l'on cherche un mot dans un dictionnaire papier.

12.2.1 Le bon problème : la position d'insertion

Plutôt que « est-il dans ? », on résout un problème un peu plus général, qui a toujours une réponse et qui se programme sans cas particulier.

Définition 12.1Position d'insertion

Soit un tableau trié par ordre croissant et une valeur. La position d'insertion de dans est le plus petit indice tel que toutes les valeurs de sont . Autrement dit : .

Par exemple avec : la position d'insertion de est (la première occurrence de ), celle de est , celle de est , celle de est . Une fois connu, est dans si et seulement si et .

12.2.2 L'invariant

On maintient deux indices et qui délimitent la zone d'incertitude : à gauche de tout est , à partir de tout est .

Dans les deux cas, la zone d'incertitude a strictement diminué, car .


static int premierIndice(int[] T, int x) { int n = T.length;
    int g = 0, d = n;
    // I(g,d) : T[0:g] < x  et  T[d:n] >= x
    while (g < d) {
        int m = g + (d - g) / 2;      // g <= m < d
        if (T[m] < x) g = m + 1;      // T[0:m+1] < x  ==> I(m+1,d)
        else d = m;                   // T[m:n] >= x   ==> I(g,m)
    }
    // I(g,d) et g == d : T[0:g] < x et T[g:n] >= x
    return g;
}

static boolean dans(int[] T, int x) { // T trié croissant
    int i = premierIndice(T, x);
    return i < T.length && T[i] == x;
}

La suite du cours est sur Adloun

Le chapitre en entier, formules et figures comprises, avec le tuteur, les fiches, les QCM et les exercices.

Lire la suite du cours

En accès libre, sans inscription.

Exercices corrigés de ce chapitre

Lire la suite du cours →