Algorithme de recherche binaire en Java

Algorithme de recherche binaire en Java

1. Vue d'ensemble

Dans cet article, nous aborderons les avantages d'une recherche binaire par rapport à une simple recherche linéaire et découvrirons son implémentation en Java.

Disons que nous sommes dans le secteur de la vente de vin et que des millions d'acheteurs visitent notre application chaque jour.

Grâce à notre application, un client peut filtrer les articles dont le prix est inférieur àn dollars, sélectionner une bouteille dans les résultats de recherche et les ajouter à son panier. Nous avons des millions d'utilisateurs à la recherche de vins avec une limite de prix à la seconde. Les résultats doivent être rapides.

Sur le serveur, notre algorithme effectue une recherche linéaire dans l’ensemble de la liste des vins en comparant la limite de prix saisie par le client au prix de chaque bouteille de vin figurant dans la liste.

Ensuite, il renvoie les articles dont le prix est inférieur ou égal à la limite de prix. Cette recherche linéaire a une complexité temporelle deO(n).

Cela signifie que plus le nombre de bouteilles de vin présentes dans notre système est grand, plus cela prendra de temps. The search time increases proportionately to the number of new items introduced.

Si nous commençons à enregistrer les éléments dans un ordre trié et à rechercher des éléments à l'aide de la recherche binaire, nous pouvons atteindre une complexité deO(log n).

Avec la recherche binaire, le temps pris par les résultats de la recherche augmente naturellement avec la taille de l'ensemble de données, mais pas proportionnellement.

En termes simples, l'algorithme compare la valeur dekey avec l'élément du milieu du tableau; s'ils sont inégaux, la moitié dans laquelle la clé ne peut pas faire partie est éliminée et la recherche continue pour la moitié restante jusqu'à ce qu'elle réussisse.

Rappelez-vous que l'aspect clé ici est que le tableau est déjà trié.

Si la recherche se termine avec la moitié restante vide, lekey n'est pas dans le tableau.

3.1. Impl itératif

public int runBinarySearchIteratively(
  int[] sortedArray, int key, int low, int high) {
    int index = Integer.MAX_VALUE;

    while (low <= high) {
        int mid = (low + high) / 2;
        if (sortedArray[mid] < key) {
            low = mid + 1;
        } else if (sortedArray[mid] > key) {
            high = mid - 1;
        } else if (sortedArray[mid] == key) {
            index = mid;
            break;
        }
    }
    return index;
}

La méthoderunBinarySearchIteratively prend unsortedArray,key et les indexlow &high dessortedArray comme arguments. Lorsque la méthode exécute pour la première fois leslow, le premier index dessortedArray, est 0, tandis que leshigh, le dernier index dessortedArray, est égal à son longueur - 1.

Lemiddle est l'index du milieu dessortedArray. Maintenant, l'algorithme exécute une bouclewhile comparant leskey avec la valeur du tableau de l'index du milieu dessortedArray.

3.2. Impl récursif

Voyons maintenant une implémentation simple et récursive:

public int runBinarySearchRecursively(
  int[] sortedArray, int key, int low, int high) {
    int middle = (low + high) / 2;

    if (high < low) {
        return -1;
    }

    if (key == sortedArray[middle]) {
        return middle;
    } else if (key < sortedArray[middle]) {
        return runBinarySearchRecursively(
          sortedArray, key, low, middle - 1);
    } else {
        return runBinarySearchRecursively(
          sortedArray, key, middle + 1, high);
    }
}

La méthoderunBinarySearchRecursively accepte unsortedArray,key, les indexlow ethigh dessortedArray.

3.3. Utilisation deArrays.binarySearch()

int index = Arrays.binarySearch(sortedArray, key);

A sortedArray et unintkey, qui doit être recherché dans le tableau d'entiers, sont passés en arguments à la méthodebinarySearch de la classe JavaArrays .

3.4. Utilisation deCollections.binarySearch()

int index = Collections.binarySearch(sortedList, key);

A sortedList & anIntegerkey, qui doit être recherché dans la liste des objetsInteger, sont passés en arguments à la méthodebinarySearch de JavaCollections classe.

3.5. Performance

Whether to use a recursive or an iterative approach for writing the algorithm is mostly a matter of personal preference. Mais voici encore quelques points dont nous devons être conscients:

1. La récursivité peut être plus lente en raison de la surcharge liée au maintien d'unstack et prend généralement plus de mémoire 2. La récursivité n'est passtack- friendly. Cela peut provoquer desStackOverflowException lors du traitement de grands ensembles de données 3. La récursivité ajoute de la clarté au code en le raccourcissant par rapport à l'approche itérative.

Idéalement, une recherche binaire effectuera moins de comparaisons qu'une recherche linéaire pour les grandes valeurs de n. Pour des valeurs plus petites de n, la recherche linéaire pourrait donner de meilleurs résultats qu'une recherche binaire.

Il faut savoir que cette analyse est théorique et peut varier en fonction du contexte.

En outre,the binary search algorithm needs a sorted data set which has its costs too. Si nous utilisons un algorithme de tri par fusion pour trier les données, une complexité supplémentaire den log n est ajoutée à notre code.

Nous devons donc d’abord bien analyser nos besoins, puis décider quel algorithme de recherche convient le mieux à nos besoins.

4. Conclusion

Ce tutoriel présente une implémentation d'un algorithme de recherche binaire et un scénario dans lequel il serait préférable de l'utiliser plutôt qu'une recherche linéaire.

Veuillez trouver le code du tutorielover on GitHub.