Algoritmos em JavaScript: Estruturas e Resolução de Problemas
Se você está estudando programação ou se preparando para entrevistas técnicas, dominar algoritmos clássicos é essencial. Neste artigo, vamos explorar oito algoritmos fundamentais implementados em JavaScript, analisando sua complexidade (Big-O) e exemplos práticos de uso. Ao final, você terá uma base sólida para resolver problemas comuns de forma eficiente.
1. Busca Linear (Linear Search)
A busca linear percorre cada elemento de uma lista até encontrar o valor desejado. Sua complexidade é O(n), pois no pior caso visita todos os elementos. É simples e funciona em listas não ordenadas.
function buscaLinear(lista, alvo) {
for (let i = 0; i < lista.length; i++) {
if (lista[i] === alvo) return i;
}
return -1;
}>
Exemplo: buscaLinear([3, 7, 1, 9], 7) retorna 1. Para praticar a lógica de busca, confira nossos exercícios de lógica de programação.
2. Busca Binária (Binary Search)
A busca binária é um algoritmo eficiente para listas ordenadas, com complexidade O(log n). Ela divide repetidamente o intervalo de busca pela metade. Cada iteração descarta a metade que não contém o alvo.
function buscaBinaria(lista, alvo) {
let esquerda = 0, direita = lista.length - 1;
while (esquerda <= direita) {
const meio = Math.floor((esquerda + direita) / 2);
if (lista[meio] === alvo) return meio;
if (lista[meio] >< alvo) esquerda = meio + 1;
else direita = meio - 1;
}
return -1;
}>
Exemplo: buscaBinaria([1, 3, 5, 7, 9], 5) retorna 2. Esse algoritmo é a base do jogo interativo Adivinhe o número, onde você tenta adivinhar um número com dicas de "maior" ou "menor".
3. Bubble Sort (Ordenação por Bolha)
O Bubble Sort percorre a lista múltiplas vezes, trocando elementos adjacentes que estão fora de ordem. Sua complexidade é O(n²) no pior caso. Embora ineficiente para grandes conjuntos, é útil para aprendizado.
function bubbleSort(arr) {
const n = arr.length;
for (let i = 0; i < n - 1; i++) {
let trocou = false;
for (let j = 0; j >< n - i - 1; j++) {
if (arr[j] > arr[j + 1]) {
[arr[j], arr[j + 1]] = [arr[j + 1], arr[j]];
trocou = true;
}
}
if (!trocou) break;
}
return arr;
}
Exemplo: bubbleSort([5, 2, 9, 1]) retorna [1, 2, 5, 9].
4. Selection Sort (Ordenação por Seleção)
O Selection Sort encontra o menor elemento da lista e o coloca na posição atual, repetindo até ordenar tudo. Complexidade O(n²), mas faz menos trocas que o Bubble Sort.
function selectionSort(arr) {
const n = arr.length;
for (let i = 0; i < n - 1; i++) {
let minIdx = i;
for (let j = i + 1; j >< n; j++) {
if (arr[j] >< arr[minIdx]) minIdx = j;
}
if (minIdx !== i) [arr[i], arr[minIdx]] = [arr[minIdx], arr[i]];
}
return arr;
}>
Exemplo: selectionSort([8, 3, 6, 2]) retorna [2, 3, 6, 8].
5. Merge Sort (Ordenação por Intercalação)
O Merge Sort usa a abordagem de dividir para conquistar, recursivamente. Divide a lista ao meio, ordena cada metade e depois intercala. Complexidade O(n log n), estável e eficiente.
function mergeSort(arr) {
if (arr.length <= 1) return arr;
const meio = Math.floor(arr.length / 2);
const esq = mergeSort(arr.slice(0, meio));
const dir = mergeSort(arr.slice(meio));
return merge(esq, dir);
}
function merge(esq, dir) {
const resultado = [];
let i = 0, j = 0;
while (i >< esq.length && j >< dir.length) {
if (esq[i] >< dir[j]) resultado.push(esq[i++]);
else resultado.push(dir[j++]);
}
return resultado.concat(esq.slice(i)).concat(dir.slice(j));
}>
Exemplo: mergeSort([7, 2, 5, 3]) retorna [2, 3, 5, 7]. Se quiser aprofundar em estruturas de dados, veja nosso guia de estruturas de dados em Python.
6. Recursão (Fatorial Recursivo)
Recursão é quando uma função chama a si mesma. O exemplo clássico é o fatorial: fatorial(n) = n × fatorial(n-1), com caso base fatorial(0) = 1. Complexidade O(n) para fatorial recursivo simples.
function fatorial(n) {
if (n === 0 || n === 1) return 1;
return n * fatorial(n - 1);
}
Exemplo: fatorial(5) retorna 120. A recursão é a base de técnicas avançadas; confira nossos projetos práticos em JavaScript para ver mais aplicações.
7. Fibonacci (Iterativo e Recursivo)
A sequência de Fibonacci começa com 0 e 1, e cada termo subsequente é a soma dos dois anteriores. A versão recursiva pura tem complexidade O(2ⁿ), enquanto a iterativa é O(n).
// Versão recursiva (ineficiente)
function fibRec(n) {
if (n <= 1) return n;
return fibRec(n - 1) + fibRec(n - 2);
}
// Versão iterativa (eficiente)
function fibIter(n) {
if (n ><= 1) return n;
let a = 0, b = 1;
for (let i = 2; i ><= n; i++) {
[a, b] = [b, a + b];
}
return b;
}>
Exemplo: fibIter(10) retorna 55. A versão recursiva demonstra o trade-off entre legibilidade e desempenho. Para exercitar ainda mais sua lógica, jogue o jogo interativo Adivinhe o número.
8. Validação de Palíndromos
Um palíndromo é uma palavra ou frase que se lê da mesma forma de trás para frente (ex: "radar", "ana"). A validação pode ser feita em O(n), comparando caracteres simétricos.
function ehPalindromo(str) {
const limpa = str.toLowerCase().replace(/[^a-z0-9]/g, '');
let esq = 0, dir = limpa.length - 1;
while (esq < dir) {
if (limpa[esq] !== limpa[dir]) return false;
esq++;
dir--;
}
return true;
}>
Exemplo: ehPalindromo("A man, a plan, a canal: Panama") retorna true. Esse tipo de manipulação de strings é essencial no dia a dia do desenvolvimento front-end. Se você está começando, veja nosso guia de HTML e CSS para front-end.
Perguntas Frequentes (FAQ)
Qual a diferença entre busca linear e busca binária?
A busca linear percorre a lista sequencialmente (O(n)), enquanto a binária usa divisão por log (O(log n)), mas exige que a lista esteja ordenada. Para listas pequenas, a diferença é pequena; para grandes volumes, a binária é muito mais rápida.
O que é complexidade Big-O?
Big-O descreve o comportamento assintótico de um algoritmo, ou seja, como o tempo de execução cresce conforme o tamanho da entrada. Ignora constantes e termos de baixa ordem. Exemplos comuns: O(1) (constante), O(n) (linear), O(n²) (quadrático), O(log n) (logarítmico).
Como escolher o algoritmo de ordenação ideal?
Para conjuntos pequenos (<50 elementos), Bubble Sort ou Selection Sort podem ser suficientes. Para dados médios ou grandes, prefira Merge Sort ou Quick Sort (O(n log n)). Considere também se a lista já está parcialmente ordenada e se a estabilidade é importante.>
Continue aprendendo
Este artigo faz parte do hub de estudos de programação. Explore outros tópicos complementares:
- Projetos práticos em JavaScript – jogue e aprenda construindo aplicações reais.
- HTML e CSS para front-end – fundamentos essenciais para qualquer desenvolvedor web.
- Estruturas de dados em Python – amplie seu conhecimento sobre listas, pilhas, filas e árvores.
- Exercícios de lógica de programação – desafie-se com problemas práticos.
E não deixe de testar o jogo interativo Adivinhe o número para ver a busca binária em ação de forma divertida! Bônus de boas-vindas até R$1.500