DEV Community

Cover image for Busca Binária
TheNewHackers
TheNewHackers

Posted on • Edited on

4 2

Busca Binária

A Busca Binária (Binary Search) é um dos algoritmos de busca mais fáceis de implementar e entender na minha opinião.

Antes de iniciarmos a explicação, vamos ver o seguinte problema:

"Dado um array de inteiros ordenado, descubra se o número 42 está nesse array"

O problema parece extremamente simples a primeira vista, e logo já pensamos em uma solução em O(N) - no pior caso. Ou seja percorrer o array do inicio até encontrar o número 42, ou chegar ao fim do array.

Por exemplo esse código em Ruby:

def naive_solution(arr)
  for elem in arr
    return true if elem == 42
  end

  false
end
Enter fullscreen mode Exit fullscreen mode

Certo, mas está faltando algo nesse exercício... Qual é o tamanho desse array? Em outras palavras, qual é o valor máximo de N?

Segue abaixo o benchmark para entendermos até onde nossa solução é viável:

                user     system      total        real
N = 10^3    0.000041   0.000002   0.000043 (  0.000038)
N = 10^4    0.000356   0.000015   0.000371 (  0.000370)
N = 10^5    0.003486   0.000000   0.003486 (  0.003486)
N = 10^6    0.038462   0.000000   0.038462 (  0.038473)
N = 10^7    0.352321   0.000000   0.352321 (  0.352354)
N = 10^8    3.532989   0.000000   3.532989 (  3.533004)
Enter fullscreen mode Exit fullscreen mode

Podemos ver que a partir de N = 10^8, nosso código já começa a apresentar problemas de desempenho!


Busca Binária implementada pelo Ruby

Antes mesmo de explicar como a Busca Binária funciona, veja o código e o benchmark dele logo abaixo:

def built_in_binary_search(arr)
  !arr.bsearch { |elem| 42 - elem }.nil?
end
Enter fullscreen mode Exit fullscreen mode
N = 10^3    0.000026   0.000001   0.000027 (  0.000006)
N = 10^4    0.000019   0.000001   0.000020 (  0.000020)
N = 10^5    0.000015   0.000001   0.000016 (  0.000003)
N = 10^6    0.000028   0.000001   0.000029 (  0.000030)
N = 10^7    0.000004   0.000000   0.000004 (  0.000004)
N = 10^8    0.000004   0.000000   0.000004 (  0.000005)
Enter fullscreen mode Exit fullscreen mode

Isso mesmo, para N = 10^8, nosso código levou 0,000005 segundos para resolver o problema!


Entendendo a Busca Binária

Na busca binária sempre teremos um array ordernado, pois só através da pré-ordenação que conseguiremos fazer otimizações, de modo que passaremos a encontrar um elemento no array em O(logN).

A primeira etapa é encontrar o inicio do array atual, o fim e o meio desse array. Aqui chamaremos o inicio de L, o fim de R e o meio de MID.

Utilizaremos o seguinte array para o exemplo:

[1, 9, 15, 17, 23, 42, 80]
 ^         ^           ^
 L         MID         R 
Enter fullscreen mode Exit fullscreen mode

Nessa primeira etapa teremos L = 0, R = 6 e MID = (L+R)/2 = 3.

Em MID teremos o valor 17, que é menor que o número procurado (42). Então como o array está ordenado, sabemos que o elemento está do lado direito, e que tudo antes de MID pode ser ignorado!

Assim partimos para a segunda etapa, onde atualizamos os valores das variáveis.
Agora L = MID (3), R continua 6, e MID = (L+R)/2 = 4

[1, 9, 15, 17, 23, 42, 80]
           ^   ^       ^
           L   MID     R
Enter fullscreen mode Exit fullscreen mode

Novamente o valor em MID é menor que 42, pois ele é igual a 23.
Assim partiremos para atualização das variáveis novamente.
L = MID (4), R continua 6 e MID = (L+R)/2 = 5

[1, 9, 15, 17, 23, 42, 80]
               ^   ^    ^
               L   MID  R
Enter fullscreen mode Exit fullscreen mode

Como o valor em MID é 42, então finalizamos nosso algoritmo!

Veja que gastamos 3 iterações para achar o número 42, e em uma busca sequencial (similar a naive_solution) gastaríamos 6 iterações! Ou seja, 2 VEZES MAIS RÁPIDO!


Abaixo segue os links dos arquivos utilizados para o benchmark:

https://github.com/TheNewHackers/busca-algoritmos/blob/master/binary_search/binary_search.rb

https://github.com/TheNewHackers/busca-algoritmos/blob/master/binary_search/built_in_binary_search.rb

https://github.com/TheNewHackers/busca-algoritmos/blob/master/binary_search/naive.rb

Image of Datadog

Master Mobile Monitoring for iOS Apps

Monitor your app’s health with real-time insights into crash-free rates, start times, and more. Optimize performance and prevent user churn by addressing critical issues like app hangs, and ANRs. Learn how to keep your iOS app running smoothly across all devices by downloading this eBook.

Get The eBook

Top comments (0)

Billboard image

The Next Generation Developer Platform

Coherence is the first Platform-as-a-Service you can control. Unlike "black-box" platforms that are opinionated about the infra you can deploy, Coherence is powered by CNC, the open-source IaC framework, which offers limitless customization.

Learn more

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay