1
+ /*
2
+ Crontibuidores
3
+ - Dromedario de Chapéu
4
+
5
+ O que é busca Binaria -
6
+ "A busca binária é um eficiente algoritmo para encontrar um item em uma lista
7
+ ordenada de itens. Ela funciona dividindo repetidamente pela metade a porção da
8
+ lista que deve conter o item, até reduzir as localizações possíveis a apenas uma.
9
+ Nós usamos a busca binária em um jogo de adivinhação no tutorial introdutório."
10
+ - Khan Academy : https://pt.khanacademy.org/computing/computer-science/algorithms/binary-search/a/binary-search
11
+ */
12
+
13
+ // O <T> em Rust indica que não se espera tipo especifico e sim qualquer tipo
14
+ // no caso o T é usado para indicar o tipo dos valores da lista e o valor a ser
15
+ // procurado.
16
+ fn busca_binaria < T > ( lista : & [ T ] , valor : T ) -> ( bool , usize )
17
+ where
18
+ // É preciso especificar que T implementa as Traits PartialEq e PartialOrd para
19
+ // indicar que T pode ser comparado T e que possui uma ordem de maior e menor
20
+ T : PartialEq ,
21
+ T : PartialOrd ,
22
+ {
23
+ // Centro indica o centro a lista ou sublista
24
+ let mut centro = lista. len ( ) / 2 ;
25
+
26
+ // Limite_r representa o maior indice possivel, referente ao extremo direito
27
+ // da lista atual, serve para dividir a lista original sem precisar ficar
28
+ // clonando ou literalmente dividindo. Seria o [-1] da sublista
29
+ let mut limite_r = lista. len ( ) - 1 ;
30
+
31
+ // Limite_l representa o mesmo que Limite_r porem para o extremo esquerdo,
32
+ // ou sejá, o [0] da sub lista.
33
+ let mut limite_l = 0 ;
34
+
35
+ loop {
36
+ // O valor esta sendo passado por referencia e depois acessado pelo seu
37
+ // ponteiro pelo sistema de owenrship o Rust, isso pode feito com atribuição
38
+ // simples como `valor_p = lista[centro]` em um Python por exemplo
39
+ let valor_p = & lista[ centro] ;
40
+
41
+ // O primeiro bloco de if se responsabiliza em verificar se o valor que estamos
42
+ // buscado foi encontrado, caso não ele verifica da ultima operação para esta
43
+ // o centro não mudou de posição, ou sejá, não ha mais valores para verificar
44
+ // e o item não existe
45
+ if * valor_p == valor {
46
+ return ( true , centro)
47
+ } else if centro == limite_l && centro == limite_r {
48
+ return ( false , 0 )
49
+ }
50
+
51
+ // O segundo bloco se responsabiliza em verificar a distancia entre o valor recebido
52
+ // e o atual valor_p, caso sejá valor_p sejá maior, significa que o valor procurado
53
+ // esta mais para tras, e o centro é movido para o centro da sub lista anterior.
54
+ // Porem caso valor sejá maior qe o valor_p, significa que precisamos mover o centro
55
+ // para o centro da sub lista superiors
56
+ if * valor_p > valor {
57
+ limite_r = centro;
58
+ centro = centro / 2 ;
59
+ } else if * valor_p < valor {
60
+ limite_l = centro;
61
+ // O If esta verificando se o espaço entre limite_r e limite_l é igual a 1
62
+ // pois a operação de padrão usada daria o resultado de 0 nesse caso, pos
63
+ // Rust aredonda os valores para baixo, logo 0.5 é jogado para 0
64
+ // Poderia ser feito em uma linha utilizado conversõ de tipos e arredondamento
65
+ // porem eu pessoalmente acredito que a performance ganha não vale compensa
66
+
67
+ centro = if ( limite_r - limite_l) == 1 { centro + 1 }
68
+ else { centro + ( limite_r - limite_l) / 2 } ;
69
+ // Forma em uma linha -
70
+ // centro = centro + (((limite_r - limite_l) as f32 / 2.0).ceil() as usize);
71
+ }
72
+ }
73
+ }
74
+
75
+ fn main ( ) {
76
+ let lista = vec ! [ -5 , -4 , -3 , -2 , -1 ] ;
77
+ let ( existe, centro) = busca_binaria ( & lista, 6 ) ;
78
+ println ! ( "{}, {}" , existe, centro) ;
79
+ }
80
+
81
+ #[ cfg( test) ]
82
+ mod test {
83
+ use super :: * ;
84
+
85
+ #[ test]
86
+ fn busca ( ) {
87
+ let lista = vec ! [ -3 , -2 , -1 , 0 , 1 , 2 , 3 ] ;
88
+ assert_eq ! ( busca_binaria( & lista, -7 ) , ( false , 0 ) ) ;
89
+ assert_eq ! ( busca_binaria( & lista, -2 ) , ( true , 1 ) ) ;
90
+ assert_eq ! ( busca_binaria( & lista, 0 ) , ( true , 3 ) ) ;
91
+ assert_eq ! ( busca_binaria( & lista, 2 ) , ( true , 5 ) ) ;
92
+ assert_eq ! ( busca_binaria( & lista, 7 ) , ( false , 0 ) ) ;
93
+ }
94
+ }
0 commit comments