Capitulo 14 - Algoritmos de Pesquisa e Ordenação
[1]Copyright © 2026 Alyce Suza.
Fundamentos de organização e recuperação eficiente de dados em memória
14.1 A Necessidade de Organização da Informação
A capacidade de armazenar grandes volumes de informação em vetores e matrizes resolve apenas a primeira metade do problema no processamento computacional. A segunda metade consiste em recuperar um dado específico no meio de milhares de registos e em apresentar essa informação de forma estruturada ao utilizador. A ciência da computação dedica um ramo inteiro ao estudo de algoritmos de pesquisa e ordenação, avaliando o custo matemático e o consumo de recursos que cada abordagem exige do processador. A escolha do algoritmo correto determina se uma aplicação encontra um registo numa fração de milissegundo ou se o sistema congela durante vários minutos ao processar uma base de dados extensa.
Donald E. Knuth, The Art of Computer Programming. Vol. 3: Sorting and Searching. 2. ed. Addison-Wesley, 1997.
14.2 Algoritmos de Pesquisa Sequencial
A pesquisa sequencial representa o método mais rudimentar e direto para localizar um elemento dentro de um vetor. O algoritmo baseia-se na travessia linear da estrutura de dados, avaliando cada posição individual desde o índice zero até ao limite final do array. A cada iteração, o processador compara o elemento alojado na memória com o valor alvo procurado. Se a verificação resultar verdadeira, a função interrompe a sua execução e devolve o índice exato onde o dado foi localizado. Caso o laço de repetição atinja o fim do vetor sem encontrar correspondência, o algoritmo devolve um valor negativo padrão, tipicamente o menos um, sinalizando formalmente a ausência do registo no sistema.
Esta abordagem possui a vantagem arquitetural de funcionar em qualquer coleção de dados, independentemente da sua desordem interna. O custo de processamento, no entanto, escala de forma linear e proporcional ao tamanho do vetor. Num cenário pessimista onde o elemento não existe ou se encontra na última posição de um array com um milhão de registos, o processador será forçado a executar um milhão de operações de comparação redundantes.
programa
{
funcao inteiro pesquisaSequencial(inteiro lista[], inteiro tamanho, inteiro alvo)
{
para (inteiro i = 0; i < tamanho; i++)
{
se (lista[i] == alvo)
{
retorne i
}
}
retorne -1
}
funcao inicio()
{
inteiro baseDados[] = {45, 12, 89, 33, 76, 21}
inteiro procurar = 33
inteiro posicao
posicao = pesquisaSequencial(baseDados, 6, procurar)
se (posicao != -1)
{
escreva("Registo localizado com sucesso no indice: ", posicao, "\n")
}
senao
{
escreva("Falha na operacao: O registo nao existe na base de dados.\n")
}
}
}
14.3 Algoritmos de Ordenação e o Método Bolha
A organização estruturada dos dados viabiliza a implementação de algoritmos de pesquisa imensamente mais rápidos, além de garantir a apresentação de relatórios legíveis para interpretação humana. Existem dezenas de métodos matemáticos para ordenar vetores, variando drasticamente na sua complexidade e eficiência. O Método Bolha, conhecido tecnicamente como Bubble Sort, constitui a técnica introdutória padrão no ensino de programação devido à sua lógica intuitiva, apesar de ser inadequado para bases de dados de escala industrial.
A mecânica do Método Bolha assenta em múltiplas passagens sucessivas pelo vetor. O algoritmo varre a estrutura comparando elementos adjacentes em pares. Se o elemento da esquerda for estritamente maior do que o elemento da direita, o sistema executa a troca física das suas posições utilizando uma variável auxiliar de memória. Este processo empurra iterativamente os maiores valores para o final do vetor, simulando o comportamento físico de bolhas a subir para a superfície de um líquido. A ordenação é dada como concluída quando o algoritmo realiza uma passagem completa pela estrutura sem efetuar qualquer permuta entre os elementos.
programa
{
funcao vazio ordenacaoBolha(inteiro lista[], inteiro tamanho)
{
inteiro memoriaAuxiliar
para (inteiro i = 0; i < tamanho - 1; i++)
{
para (inteiro j = 0; j < tamanho - 1 - i; j++)
{
se (lista[j] > lista[j+1])
{
memoriaAuxiliar = lista[j]
lista[j] = lista[j+1]
lista[j+1] = memoriaAuxiliar
}
}
}
}
funcao inicio()
{
inteiro amostra[] = {8, 3, 15, 2, 9, 4}
escreva("Estado bruto do vetor: ")
para (inteiro i = 0; i < 6; i++) { escreva(amostra[i], " ") }
ordenacaoBolha(amostra, 6)
escreva("\nEstado ordenado do vetor: ")
para (inteiro i = 0; i < 6; i++) { escreva(amostra[i], " ") }
escreva("\n")
}
}
14.4 Pesquisa Binária e Eficiência Logarítmica
Quando um vetor se encontra rigorosamente ordenado, a utilização da pesquisa sequencial torna-se num desperdício matemático injustificável. O algoritmo de Pesquisa Binária explora a ordenação prévia para aplicar a estratégia de divisão e conquista, reduzindo exponencialmente o espaço de busca a cada iteração. O sistema estabelece dois ponteiros demarcando o limite inferior e o limite superior do segmento avaliado. A cada ciclo o processador calcula o índice central e compara o valor ali alojado com o alvo procurado.
Se o valor central for exatamente igual ao alvo, a pesquisa termina instantaneamente com sucesso. Se o alvo for menor do que o valor central, o algoritmo conclui logicamente que o elemento só pode residir na metade esquerda do vetor, descartando a metade direita inteira da memória numa única operação ao ajustar o limite superior. O processo repete-se dividindo a estrutura consecutivamente até encontrar o registo ou até que os limites se cruzem. Esta arquitetura garante uma eficiência logarítmica imbatível. Num vetor com um milhão de elementos ordenados, a pesquisa binária requereria um máximo absoluto de vinte comparações matemáticas para localizar o dado ou atestar a sua ausência.
programa
{
funcao inteiro pesquisaBinaria(inteiro lista[], inteiro tamanho, inteiro alvo)
{
inteiro limiteInferior = 0
inteiro limiteSuperior = tamanho - 1
inteiro pontoCentral
enquanto (limiteInferior <= limiteSuperior)
{
pontoCentral = (limiteInferior + limiteSuperior) / 2
se (lista[pontoCentral] == alvo)
{
retorne pontoCentral
}
senao se (lista[pontoCentral] < alvo)
{
limiteInferior = pontoCentral + 1
}
senao
{
limiteSuperior = pontoCentral - 1
}
}
retorne -1
}
funcao inicio()
{
// O algoritmo exige rigorosamente que a estrutura nasca ordenada
inteiro codigosValidos[] = {102, 245, 388, 412, 599, 670, 891}
inteiro consulta = 599
inteiro resultado = pesquisaBinaria(codigosValidos, 7, consulta)
se (resultado >= 0)
{
escreva("Codigo verificado e validado na posicao de memoria: ", resultado, "\n")
}
senao
{
escreva("Alerta: O codigo fornecido nao consta no registo do sistema.\n")
}
}
}
14.5 Exercícios do Capítulo 14
Construa uma função que receba este vetor e um número alvo específico por parâmetro. O subprograma deve aplicar a técnica da pesquisa sequencial para percorrer a estrutura completa, atuando em conjunto com um acumulador simples para contabilizar quantas vezes exatas o valor alvo aparece alojado no array. A função deve devolver o total absoluto desta contagem ao bloco principal.
Altere a estrutura condicional interna do algoritmo Método Bolha para forçar a reorganização dos dados em formato estritamente decrescente, garantindo que as notas mais elevadas assumam os índices iniciais do vetor. Imprima a listagem académica completa após a consolidação da permutação.
Aplique obrigatoriamente a função de ordenação para organizar os valores em ordem crescente antes de qualquer outra operação. Em seguida, solicite ao utilizador um número para consulta e execute exclusivamente a pesquisa binária para localizar e informar em que posição definitiva o número se encontra acomodado após o processo de ordenação estrutural.
Gabarito do Capítulo 14
programa
{
funcao inteiro contarOcorrencias(inteiro lista[], inteiro tamanho, inteiro alvo)
{
inteiro contador = 0
para (inteiro i = 0; i < tamanho; i++)
{
se (lista[i] == alvo)
{
contador++
}
}
retorne contador
}
funcao inicio()
{
inteiro registos[] = {4, 7, 2, 4, 9, 4, 1, 8, 4, 5}
inteiro procura = 4
inteiro total
total = contarOcorrencias(registos, 10, procura)
escreva("Deteccao completa: O alvo ", procura, " surge ", total, " vezes na rede de dados.\n")
}
}
programa
{
funcao vazio ordenacaoDescendente(real avaliacoes[], inteiro volume)
{
real baseTemporaria
para (inteiro i = 0; i < volume - 1; i++)
{
para (inteiro j = 0; j < volume - 1 - i; j++)
{
se (avaliacoes[j] < avaliacoes[j+1])
{
baseTemporaria = avaliacoes[j]
avaliacoes[j] = avaliacoes[j+1]
avaliacoes[j+1] = baseTemporaria
}
}
}
}
funcao inicio()
{
real pauta[] = {6.5, 9.0, 4.5, 8.5, 7.0, 10.0, 5.5, 8.0}
ordenacaoDescendente(pauta, 8)
escreva("Pauta letiva compilada por ordem de merito academico:\n")
para (inteiro k = 0; k < 8; k++)
{
escreva(k + 1, "o Lugar: ", pauta[k], " valores\n")
}
}
}
programa
{
funcao vazio ordenarElementos(inteiro v[], inteiro n)
{
inteiro aux
para (inteiro i = 0; i < n - 1; i++)
{
para (inteiro j = 0; j < n - 1 - i; j++)
{
se (v[j] > v[j+1])
{
aux = v[j]
v[j] = v[j+1]
v[j+1] = aux
}
}
}
}
funcao inteiro buscarBinario(inteiro v[], inteiro n, inteiro alvo)
{
inteiro esq = 0, dir = n - 1, meio
enquanto (esq <= dir)
{
meio = (esq + dir) / 2
se (v[meio] == alvo) { retorne meio }
senao se (v[meio] < alvo) { esq = meio + 1 }
senao { dir = meio - 1 }
}
retorne -1
}
funcao inicio()
{
inteiro vetor[5], busca, id
para (inteiro i = 0; i < 5; i++)
{
escreva("Preencha a ranhura de memoria ", i, ": ")
leia(vetor[i])
}
ordenarElementos(vetor, 5)
escreva("\nProcesso de indexacao finalizado. Base de dados pronta.\n")
escreva("Indique o elemento a extrair da memoria: ")
leia(busca)
id = buscarBinario(vetor, 5, busca)
se (id != -1)
{
escreva("Elemento capturado e lido no indice oficial: ", id, "\n")
}
senao
{
escreva("Elemento rejeitado pelo subsistema de procura profunda.\n")
}
}
}
Copyright © 2026 Alyce Suza. Todos os direitos reservados nos termos da Lei 9.610/98. O conteúdo publicado no site https://wiki.suzacybersecurity.com/ é protegido pelas diretrizes brasileiras de propriedade intelectual e a sua autoria é reconhecida desde o momento da criação técnica. O compartilhamento, a reprodução e a distribuição deste material são permitidos e incentivados apenas para finalidades educacionais, acadêmicas ou de consulta técnica, sendo estritamente vedado qualquer tipo de uso comercial. Para que a replicação seja validada e legal, você deve obrigatoriamente atribuir os devidos créditos a Alyce Suza e fornecer um link direto e acessível para a publicação original. A utilização deste material para obter lucro, monetização, venda de materiais ou qualquer vantagem financeira constitui violação de direitos autorais e está sujeita às sanções legais cabíveis, assim como alterações que modifiquem o sentido original das explicações sobre segurança da informação. Para eventuais dúvidas sobre permissões de uso, parcerias ou para reportar replicações indevidas, envie um e-mail para alycesuza@gmail.com. ↩︎