Algoritmo de Pesquisa Binária em Java

Algoritmo de Pesquisa Binária em Java

1. Visão geral

Neste artigo, cobriremos as vantagens de uma pesquisa binária em relação a uma pesquisa linear simples e percorreremos sua implementação em Java.

Digamos que estejamos no negócio de venda de vinho e milhões de compradores visitam nosso aplicativo todos os dias.

Através de nosso aplicativo, o cliente pode filtrar itens com preço inferior an dólares, selecionar uma garrafa nos resultados da pesquisa e adicioná-la ao carrinho. Temos milhões de usuários que procuram vinhos com um limite de preço a cada segundo. Os resultados precisam ser rápidos.

No back-end, nosso algoritmo executa uma pesquisa linear em toda a lista de vinhos, comparando o limite de preço inserido pelo cliente com o preço de cada garrafa de vinho na lista.

Em seguida, ele retorna itens com um preço menor ou igual ao limite de preço. Essa pesquisa linear tem uma complexidade de tempo deO(n).

Isso significa que quanto maior o número de garrafas de vinho em nosso sistema, mais tempo levará. The search time increases proportionately to the number of new items introduced.

Se começarmos a salvar itens em ordem classificada e pesquisarmos por itens usando a pesquisa binária, podemos atingir uma complexidade deO(log n).

Com a pesquisa binária, o tempo gasto pelos resultados da pesquisa aumenta naturalmente com o tamanho do conjunto de dados, mas não proporcionalmente.

Simplificando, o algoritmo compara o valor dekey com o elemento do meio da matriz; se forem desiguais, a metade da qual a chave não pode fazer parte é eliminada e a busca continua pela metade restante até obter sucesso.

Lembre-se - o aspecto principal aqui é que a matriz já está classificada.

Se a pesquisa terminar com a metade restante vazia, okey não está na matriz.

3.1. Iterative Impl

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;
}

O métodorunBinarySearchIteratively levasortedArray,key & os índiceslow &high desortedArray como argumentos. Quando o método é executado pela primeira vez emlow, o primeiro índice desortedArray, é 0, enquantohigh, o último índice desortedArray, é igual ao seu comprimento - 1.

Omiddle é o índice do meio desortedArray. Agora, o algoritmo executa um loopwhile comparandokey com o valor da matriz do índice do meio desortedArray.

3.2. Impl recursivo

Agora, vamos dar uma olhada em uma implementação simples e recursiva também:

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);
    }
}

O métodorunBinarySearchRecursively aceitasortedArray,key, os índiceslowehigh desortedArray.

3.3. UsandoArrays.binarySearch()

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

A sortedArraye umintkey, que deve ser pesquisado na matriz de inteiros, são passados ​​como argumentos para o métodobinarySearch da classe JavaArrays .

3.4. UsandoCollections.binarySearch()

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

A sortedList & anIntegerkey, que deve ser pesquisado na lista de objetosInteger, são passados ​​como argumentos para o métodobinarySearch do JavaCollections classe.

3.5. atuação

Whether to use a recursive or an iterative approach for writing the algorithm is mostly a matter of personal preference. Mas ainda aqui estão alguns pontos que devemos estar cientes:

1. A recursão pode ser mais lenta devido à sobrecarga de manter umstacke geralmente ocupa mais memória 2. A recursão não éstack-amigável. Pode causarStackOverflowException ao processar conjuntos de big data 3. A recursão adiciona clareza ao código, pois o torna mais curto em comparação à abordagem iterativa

Idealmente, uma pesquisa binária executará menos número de comparações em contraste com uma pesquisa linear para grandes valores de n. Para valores menores de n, a pesquisa linear pode ter um desempenho melhor do que uma pesquisa binária.

Deve-se saber que essa análise é teórica e pode variar dependendo do contexto.

Além disso,the binary search algorithm needs a sorted data set which has its costs too. Se usarmos um algoritmo de classificação por mesclagem para classificar os dados, uma complexidade adicional den log n é adicionada ao nosso código.

Então, primeiro precisamos analisar bem nossos requisitos e depois tomar uma decisão sobre qual algoritmo de pesquisa se adequaria melhor aos nossos requisitos.

4. Conclusão

Este tutorial demonstrou uma implementação do algoritmo de pesquisa binária e um cenário em que seria preferível usá-lo em vez de uma pesquisa linear.

Encontre o código do tutorialover on GitHub.