Sei sulla pagina 1di 13

Busca

Busca em Vetores
Esta aula introduz a busca em
vetores que est entre as
tarefas mais freqentemente
encontradas em programao
de computadores
Sero abordados dois tipos
de busca: linear (ou
seqencial) e binria

Prof. Dr. Jos Augusto Baranauskas


DFM-FFCLRP-USP

A hiptese bsica assumida no processo de busca que o


conjunto de dados, dentre o qual um determinado elemento
deve ser procurado, possui tamanho fixo, ou seja, um vetor:
item a[N];
onde item representa uma estrutura de dados contendo um
campo que atua como chave para a pesquisa e N uma
constante indicando o nmero de elementos
typedef struct
{ int key;
// chave de busca
...
// demais campos da estrutura
} item;
Objetivo da busca: dado x encontrar a[i].key == x
O ndice i resultante permite acesso aos demais campos

Busca

Exemplo

Para estudo, vamos admitir que o tipo item seja


composto apenas do campo chave, ou seja, o dado
a prpria chave.
Alm disso, para facilitar o estudo ainda mais, a
chave de busca ser um inteiro, ou seja, o vetor a
ser declarado como:

int a[N];

Busca de x = 19, retorna i = 5


Busca de x = 45, retorna i = 0
Busca de x = 8, retorna i = 6
E a busca de x = 81?
a

45

56

12

43

95

19

67

Lembrando que N uma constante que indica o


nmero de elementos do vetor
Assim, objetivo da busca se resume a dado x
encontrar a[i] == x
3

Exemplo

Busca Linear (ou Seqencial)

Busca de x = 19, retorna i = 5


Busca de x = 45, retorna i = 0
Busca de x = 8, retorna i = 6
E a busca de x = 81?

1. O elemento encontrado, isto , a[i] == x


2. Todo o vetor foi analisado, mas o elemento x no foi encontrado

Utilizada quando no h de informaes


adicionais sobre os dados a serem pesquisados
A busca linear termina quando for satisfeita uma
das duas condies seguintes:

45

56

12

43

95

19

67

Depende da implementao!
Pode retornar i = -1 (ou outro valor) indicativo
que a busca no teve xito

Algoritmo:
i = 0;
while (i < N && a[i] != x)
i++;
Ao trmino do lao:
Se i == N ento x no foi encontrado
seno a[i] == x, i a posio onde x foi encontrado

Busca Linear (ou Seqencial)

Busca Linear (ou Seqencial)

Busca de x = 19
i = 0;

Busca de x = 19
i = 0;
V
V
while (i < N && a[i] != x)
i++;

while (i < N && a[i] != x)


i++;
N

45

56

12

43

95

19

67

45

56

12

43

95

19

67

Busca Linear (ou Seqencial)

Busca Linear (ou Seqencial)

Busca de x = 19
i = 0;

Busca de x = 19
i = 0;
V
V
while (i < N && a[i] != x)
i++;

while (i < N && a[i] != x)


i++;
N

45

56

12

43

95

19

67

45

56

12

43

95

19

67

10

Busca Linear (ou Seqencial)

Busca Linear (ou Seqencial)

Busca de x = 19
i = 0;

Busca de x = 19
i = 0;
V
V
while (i < N && a[i] != x)
i++;

while (i < N && a[i] != x)


i++;
N

45

56

12

43

95

19

67

45

56

12

43

95

19

67

11

12

Busca Linear (ou Seqencial)

Busca Linear (ou Seqencial)

Busca de x = 19
i = 0;

Busca de x = 19
i = 0;
V
V
while (i < N && a[i] != x)
i++;

while (i < N && a[i] != x)


i++;
N

45

56

12

43

95

19

67

45

56

12

43

95

19

67

13

14

Busca Linear (ou Seqencial)

Busca Linear (ou Seqencial)

Busca de x = 19
i = 0;

Busca de x = 19
i = 0;
V
V
while (i < N && a[i] != x)
i++;

while (i < N && a[i] != x)


i++;
N

45

56

12

43

95

19

67

45

56

12

43

95

19

67

15

16

Busca Linear (ou Seqencial)

Busca Linear (ou Seqencial)

Busca de x = 19
i = 0;

Busca de x = 19
i = 0;
V
F
while (i < N && a[i] != x)
i++;

while (i < N && a[i] != x)


i++;
N

45

56

12

43

95

19

67

45

56

12

43

95

19

67

17

18

Busca Linear (ou Seqencial)

Exemplo em C++

Busca de x = 19
i = 0;

#include <iostream>
using namespace std;
int busca_sequencial(int x, int N, int a[])
{ int i = 0;
while (i < N && a[i] != x)
i++;
return (i == N) ? -1 : i;

while (i < N && a[i] != x)


i++;
N

Busca
Busca
Busca
Busca

45

56

12

43

95

19

67

de
de
de
de

19
45
8
81

=
=
=
=

5
0
6
-1

int main(void)
{ const int m = 8;
int v[m] = {45,56,12,43,95,19,8,67};
cout << "Busca
cout << "Busca
cout << "Busca
cout << "Busca
return 0;

Trmino do lao: Se i != N ento x foi


encontrado na posio i do vetor

de
de
de
de

19
45
8
81

=
=
=
=

"
"
"
"

<<
<<
<<
<<

busca_sequencial(19,m,v) << endl;


busca_sequencial(45,m,v) << endl;
busca_sequencial(8,m,v) << endl;
busca_sequencial(81,m,v) << endl;

}
19

20

Anlise da Busca Linear

Busca Linear com Sentinela

Em mdia so efetuadas N/2 comparaes


de chaves para encontrar um elemento
particular x no vetor a de N elementos
O pior caso requerer N comparaes de
chaves
Isso pode consumir muito tempo quando o
nmero de elementos do vetor grande

O uso da sentinela tem como objetivo


acelerar a busca, atravs da simplificao da
expresso booleana
A idia bsica fazer com que o elemento x
sempre seja encontrado
Para isso, introduz-se um elemento adicional
no final do vetor

21

Busca Linear com Sentinela

22

Busca de x = 56

Algoritmo:
item a[N+1];
i = 0;
a[N] = x;
// sentinela
while (a[i] != x)
i++;
Ao final do lao, i == N implica que x no foi
encontrado (exceto o correspondente
sentinela).

i = 0;
a[N] = x;
while (a[i] != x)
i++;
N

45

56

12

43

95

19

67

23

24

Busca de x = 56

Busca de x = 56

i = 0;
a[N] = x;

i = 0;
a[N] = x;

while (a[i] != x)
i++;

V
while (a[i] != x)
i++;

45

56

12

43

95

19

67

56

45

56

12

43

95

19

67

56

Sentinela
25

Busca de x = 56

26

Busca de x = 56

i = 0;
a[N] = x;

i = 0;
a[N] = x;

while (a[i] != x)
i++;

F
while (a[i] != x)
i++;

45

56

12

43

95

19

67

56

45

56

12

43

95

19

67

56

27

Busca de x = 56

28

Busca de x = 81

i = 0;
a[N] = x;

i = 0;
a[N] = x;

while (a[i] != x)
i++;

while (a[i] != x)
i++;

45

56

12

43

95

19

67

56

45

56

12

43

95

19

67

Trmino do lao: Se i != N ento x foi


encontrado na posio i do vetor
29

30

Busca de x = 81

Busca de x = 81

i = 0;
a[N] = x;

i = 0;
a[N] = x;

while (a[i] != x)
i++;

V
while (a[i] != x)
i++;

45

56

12

43

95

19

67

81

45

56

12

43

95

19

67

81

Sentinela
31

Busca de x = 81

32

Busca de x = 81

i = 0;
a[N] = x;

i = 0;
a[N] = x;

while (a[i] != x)
i++;

V
while (a[i] != x)
i++;

45

56

12

43

95

19

67

81

45

56

12

43

95

19

67

81

33

Busca de x = 81

34

Busca de x = 81

i = 0;
a[N] = x;

i = 0;
a[N] = x;

while (a[i] != x)
i++;

V
while (a[i] != x)
i++;

45

56

12

43

95

19

67

81

45

56

12

43

95

19

67

81

35

36

Busca de x = 81

Busca de x = 81

i = 0;
a[N] = x;

i = 0;
a[N] = x;

while (a[i] != x)
i++;

V
while (a[i] != x)
i++;

45

56

12

43

95

19

67

81

45

56

12

43

95

19

67

81

37

Busca de x = 81

38

Busca de x = 81

i = 0;
a[N] = x;

i = 0;
a[N] = x;

while (a[i] != x)
i++;

V
while (a[i] != x)
i++;

45

56

12

43

95

19

67

81

45

56

12

43

95

19

67

81

39

Busca de x = 81

40

Busca de x = 81

i = 0;
a[N] = x;

i = 0;
a[N] = x;

while (a[i] != x)
i++;

V
while (a[i] != x)
i++;

45

56

12

43

95

19

67

81

45

56

12

43

95

19

67

81

41

42

Busca de x = 81

Busca de x = 81

i = 0;
a[N] = x;

i = 0;
a[N] = x;

while (a[i] != x)
i++;

V
while (a[i] != x)
i++;

45

56

12

43

95

19

67

81

45

56

12

43

95

19

67

81

43

Busca de x = 81

44

Busca de x = 81

i = 0;
a[N] = x;

i = 0;
a[N] = x;

while (a[i] != x)
i++;

V
while (a[i] != x)
i++;

45

56

12

43

95

19

67

81

45

56

12

43

95

19

67

81

45

Busca de x = 81

46

Busca de x = 81

i = 0;
a[N] = x;

i = 0;
a[N] = x;

while (a[i] != x)
i++;

F
while (a[i] != x)
i++;

45

56

12

43

95

19

67

81

45

56

12

43

95

19

67

81
i

47

48

Busca de x = 81

Exemplo em C++
#include <iostream>
using namespace std;

i = 0;
a[N] = x;

int busca_sentinela(int x, int N, int a[])


{ int i = 0;
a[N] = x; // sentinela
while (a[i] != x)
i++;
return (i == N) ? -1 : i;

while (a[i] != x)
i++;
N

45

56

12

43

95

19

67

81

de
de
de
de

19
45
8
81

=
=
=
=

5
0
6
-1

int main(void)
{ const int m = 8;
int v[m+1] ={45,56,12,43,95,19,8,67};

Busca
Busca
Busca
Busca

cout << "Busca


cout << "Busca
cout << "Busca
cout << "Busca
return 0;

Trmino do lao: Se i != N ento x foi encontrado na


posio i do vetor. Como i == N, ento x no foi
encontrado (exceto sentinela)

de
de
de
de

19
45
8
81

=
=
=
=

"
"
"
"

<<
<<
<<
<<

busca_sentinela(19,m,v) << endl;


busca_sentinela(45,m,v) << endl;
busca_sentinela(8,m,v) << endl;
busca_sentinela(81,m,v) << endl;

}
49

50

Anlise da Busca com Sentinela

Busca Binria

Em mdia so efetuadas (N+1)/2


comparaes para encontrar um elemento
particular x no vetor a de N elementos
O pior caso requerer N+1 comparaes

No possvel acelerar a busca sem que se disponha de


maiores informaes acerca do elemento a ser localizado
Sabe-se que uma busca pode ser mais eficiente se os
dados estiverem ordenados, ou seja:
a[0] <= a[1] <= <= a[N-1]
A idia principal a de teste um elemento sorteado
aleatoriamente, por exemplo, a[m], comparando-o com o
elemento de busca x.
Se tal elemento for igual a x, a busca termina.
Se for menor que x, conclui-se que todos os elementos com ndices
menores ou iguais a m podem ser eliminados dos prximos testes.
Se for maior que x, todos aqueles elementos com ndices maiores ou
iguais a m podem ser tambm eliminados da busca.
51

52

Busca Binria

Busca Binria

Busca de x = 19
Suponha m = 3

Algoritmo:
a 8
12
19
43
L = 0;
R = N - 1;
achou = false;
while (L <= R && ! achou)
{ m = qualquer valor entre L e R;
if (a[m] == x)
achou = true;
else
if (a[m] < x)
L = m + 1;
else
R = m - 1;
}

N=8

12

19

43

45

56

67

95

Como a[m] > x,


Elementos com ndices maiores que
m podem ser eliminados da busca
53

45

56

67

95
N=8

54

Busca Binria

Busca Binria

Embora a escolha de m seja aparentemente


arbitrria (no sentido que o algoritmo
funciona independentemente dele) o valor
desta varivel influencia na eficincia do
algoritmo
claro que, a cada passo, deve-se eliminar
o maior nmero possvel de elementos em
futuras buscas
A soluo tima escolher a mediana dos
elementos, porque ela elimina, em qualquer
caso, metade dos elementos do vetor

A eficincia pode ser ligeiramente melhorada atravs da


permutao entre as duas clusulas de comparao.
A condio de igualdade deve ser testada em segundo
lugar, porque o sucesso ocorre apenas uma vez em todo o
processo
Porm, a questo mais relevante se refere ao fato de, como
na busca linear, se poder ou no encontrar uma soluo
que proporcione uma condio mais simples para a
finalizao do processo
possvel obter tal algoritmo rpido se for abandonada a
meta de terminar a busca no instante exato em que for
encontrado o elemento pesquisado
Isso parece pouco inteligente primeira vista, mas
observando-se mais a fundo, pode-se perceber facilmente
que o ganho em eficincia em cada passo ser maior do
que a perda ocasionada pela comparao de alguns poucos
elementos adicionais
55

56

Busca Binria Rpida

Busca de x = 19

Algoritmo:
L = 0;
R = N - 1;
while (L < R)
{ m = (L + R) / 2;
if (a[m] < x)
L = m + 1;
else
R = m;
}
Se ao trmino do algoritmo a condio a[R] == x for
verdadeira, ento x foi encontrado na posio R de a; caso
contrrio x no foi encontrado.

L = 0;
R = N - 1;
while (L < R)
{ m = (L + R) / 2;
if (a[m] < x)
L = m + 1;
else
R = m;
}

N=8

12

19

43

45

56

67

95

57

58

Busca de x = 19

Busca de x = 19

L = 0;
R = N - 1;
while (L < R)
{ m = (L + R) / 2;
if (a[m] < x)
L = m + 1;
else
R = m;
}

L = 0;
R = N - 1;
while (L < R)
{ m = (L + R) / 2;
if (a[m] < x)
L = m + 1;
else
R = m;
}

N=8

12

19

43

45

56

67

95

N=8

12

19

43

45

56

67

95

m
R

59

60

10

Busca de x = 19

Busca de x = 19

L = 0;
R = N - 1;
while (L < R)
{ m = (L + R) / 2;
if (a[m] < x)
L = m + 1;
else
R = m;
}

L = 0;
R = N - 1;
while (L < R)
{ m = (L + R) / 2;
if (a[m] < x)
L = m + 1;
else
R = m;
}

N=8

12

19

43

45

56

67

95

N=8

12

19

43

45

56

67

95

61

62

Busca de x = 19

Busca de x = 19

L = 0;
R = N - 1;
while (L < R)
{ m = (L + R) / 2;
if (a[m] < x)
L = m + 1;
else
R = m;
}

L = 0;
R = N - 1;
while (L < R)
{ m = (L + R) / 2;
if (a[m] < x)
L = m + 1;
else
R = m;
}

N=8

12

19

43

45

56

67

95

N=8

12

19

43

45

56

67

95

63

64

Busca de x = 19

Busca de x = 19

L = 0;
R = N - 1;
while (L < R)
{ m = (L + R) / 2;
if (a[m] < x)
L = m + 1;
else
R = m;
}

L = 0;
R = N - 1;
while (L < R)
{ m = (L + R) / 2;
if (a[m] < x)
L = m + 1;
else
R = m;
}

N=8

12

19

43

45

56

67

95

N=8

12

19

43

45

56

67

95

65

66

11

Busca de x = 19

Busca de x = 19

L = 0;
R = N - 1;
while (L < R)
{ m = (L + R) / 2;
if (a[m] < x)
L = m + 1;
else
R = m;
}

L = 0;
R = N - 1;
while (L < R)
{ m = (L + R) / 2;
if (a[m] < x)
L = m + 1;
else
R = m;
}

N=8

12

19

43

45

56

67

95

N=8

12

19

43

45

56

67

95

m
R

67

68

Busca de x = 19

Busca de x = 19

L = 0;
R = N - 1;
while (L < R)
{ m = (L + R) / 2;
if (a[m] < x)
L = m + 1;
else
R = m;
}

L = 0;
R = N - 1;
while (L < R)
{ m = (L + R) / 2;
if (a[m] < x)
L = m + 1;
else
R = m;
}

N=8

12

19

43

45

56

67

95

N=8

12

19

43

45

56

67

95

m
R

Trmino do lao: Como a[R] == x, x foi encontrado na


posio R de a

69

70

Exemplo em C++

Anlise da Busca Binria Rpida

#include <iostream>
using namespace std;
int busca_binaria_rapida(int x, int N, int a[])
{ int L,R,m;

Em mdia so efetuadas + log2(N)-1+ comparaes


de chaves para encontrar um elemento particular x
no vetor a de N elementos
O pior caso requerer + log2 N + comparaes

L = 0;
R = N - 1;
while (L < R)
{ m = (L + R) / 2;
if (a[m] < x)
L = m + 1;
else
R = m;
}
return (x == a[R]) ? R : -1;

Busca
Busca
Busca
Busca

de
de
de
de

19
45
8
81

=
=
=
=

5
0
6
-1

}
int main(void)
{ const int m = 8;
int v[m+1] ={8,12,19,43,45,56,67,95};
cout << "Busca
cout << "Busca
cout << "Busca
cout << "Busca
return 0;
}

de
de
de
de

19
45
8
81

=
=
=
=

"
"
"
"

<<
<<
<<
<<

busca_binaria_rapida(19,m,v) << endl;


busca_binaria_rapida(45,m,v) << endl;
busca_binaria_rapida(8,m,v) << endl;
busca_binaria_rapida(81,m,v) << endl;
71

N Comparaes (pior caso)

128

1.024

10

32.768

15

1.048.576

20

1.073.741.824

30

1.099.511.627.776

40

1080

266
72

12

Comparao

Comparao

Considerando os algoritmos de busca vistos,


a tabela seguinte mostra a ordem de
grandeza dos nmeros mnimo (Cmn), mdio
(Cmd) e mximo (Cmx) de comparaes de
chaves.
Algoritmo
Busca Linear
Busca Linear com Sentinela
Busca Binria
Busca Binria Rpida

Cmn
O(1)
O(1)
O(1)
O(log2N)

Cmd
O(N)
O(N)
O(log2N)
O(log2N)

Nmero de
comparaes

Cmx
O(N)
O(N)
O(log2N)
O(log2N)

Busca Linear

Busca Binria

Nmero de elementos (N)


73

74

Resumo
Das anlises dos algoritmos de busca, est claro
que o mtodo de busca binria tem um
desempenho to bom ou melhor do que o mtodo
de busca linear
Entretanto, a atualizao dos ndices esquerdo,
direito e mdio (L, R e m no algoritmo,
respectivamente) requer tempo adicional
Assim, para vetores com poucos elementos, a
busca linear adequada
Para vetores com muitos elementos, a busca
binria mais eficiente, mas isso requer que o
vetor esteja ordenado
75

13

Potrebbero piacerti anche