Técnicas de Busca
Motivação
Padrões típicos de busca em coleções
Busca sequencial em uma lista
Lendo as listas a partir de um arquivo
def lerDadosString(nomeArquivo):
with open(nomeArquivo) as arquivo:
lista = []
for linha in arquivo:
str = linha[:-1].strip()
lista.append(str)
return lista
def lerDadosFloat(nomeArquivo):
with open(nomeArquivo) as arquivo:
lista = []
for linha in arquivo:
valor = float(linha)
lista.append(valor)
return lista
# programa principal
cidades = lerDadosString('cidades.txt')
maximas = lerDadosFloat('maximas.txt')
minimas = lerDadosFloat('minimas.txt')
Busca por Existência: Há alguma cidade com temperatura máxima diária acima dos 40ºC?
...
cidades = lerDadosString('cidades.txt')
maximas = lerDadosFloat('maximas.txt')
minimas = lerDadosFloat('minimas.txt')
for temperatura in maximas:
if temperatura > 40.0:
print('Uma cidade passou dos 40 graus')
break
else:
print('Nenhuma cidade passou dos 40 graus')
Busca por Quantidade: Quantas cidades no país estão com temperatura mínima diária abaixo de 15ºC?
...
cidades = lerDadosString('cidades.txt')
maximas = lerDadosFloat('maximas.txt')
minimas = lerDadosFloat('minimas.txt')
contador = 0
for temperatura in minimas:
if temperatura < 15.0:
contador += 1
print('Número de cidades abaixo dos 15 graus: %d' \
% contador)
Busca por Elementos: Quais as cidades com temperatura máxima acima de 35ºC?
...
cidades = lerDadosString('cidades.txt')
maximas = lerDadosFloat('maximas.txt')
minimas = lerDadosFloat('minimas.txt')
contador = 0
cidadesQuentes = []
for i in range(len(maximas)):
temperatura = maximas[i]
if temperatura > 35.0:
# relacionando cidades e máximas pelo índice i
cidade = cidades[i]
cidadesQuentes.append(cidade)
print('Estas foram as cidades com temperatura')
print('máxima acima dos 35 graus:\n')
for cidade in cidadesQuentes:
print(cidade)
Ordem de complexidade da busca
Busca binária em uma lista
Como funciona a busca binária?
Posição | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
Elemento | 7 | 13 | 20 | 35 | 60 | 90 | 110 | 150 | 200 |
E se a busca fosse pelo número 150?
Posição | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
Elemento | 7 | 13 | 20 | 35 | 60 | 90 | 110 | 150 | 200 |
Função Iterativa de Busca Binária
def buscaBinaria(lista, chave):
inicio = 0
final = len(lista)-1
while inicio <= final:
meio = (inicio + final)//2;
if lista[meio] == chave:
# achou a chave no meio
return meio
elif lista[meio] < chave:
# procure à direita
inicio = meio + 1
else:
# procure à esquerda
final = meio – 1
# se não achou retorne o índice -1
return -1
Busca Binária Recursiva
Posição | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
Elemento | 7 | 13 | 20 | 35 | 60 | 90 | 110 | 150 | 200 |
Função Recursiva de Busca Binária para verificar a Existência da chave
def buscaBinaria(lista, chave):
meio = len(lista)//2
if not lista:
return False
elif lista[meio] == chave:
return True
elif lista[meio] > chave:
# procure à esquerda
return buscaBinaria(lista[:meio],chave)
else:
# procure à direita
return buscaBinaria(lista[meio+1:],chave)
Busca binária Recursiva para localizar a Posição da chave
Função Recursiva de Busca Binária para localizar a Posição da chave
def buscaBinaria(lista, chave):
meio = len(lista)//2
if not lista:
return -1
elif lista[meio] == chave:
return meio
elif lista[meio] > chave:
# procure à esquerda
return buscaBinaria(lista[:meio],chave)
else:
# procure à direita
resultado = buscaBinaria(lista[meio+1:],chave)
if resultado == -1:
return resultado
else:
return resultado + meio + 1
Complexidade
Busca Sequencial versus Busca Binária
Número de Elementos na Lista | Busca Sequencial (Caso Médio) | Busca Binária (Pior Caso) |
n | (n + 1) / 2 | int (log2 n) + 1 |
1 | 1 | 0 |
10 | 5,5 | 4 |
100 | 50,5 | 7 |
1.000 | 500,5 | 10 |
10.000 | 5.000,5 | 14 |
100.000 | 50.000,5 | 17 |
1.000.000 | 500.000,5 | 20 |
10.000.000 | 5.000.000,5 | 24 |