Complexidade de Algoritmos
Por que alguns algoritmos ficam lentos com dados grandes? A notação Big-O descreve como o tempo de execução cresce com a entrada. Aprenda O(1), O(n), O(n²) e O(log n).
Renato Freitas
Atualizado em 5 de maio de 2026
Por que a eficiência importa
Um algoritmo que ordena 10 números em 1 milissegundo pode levar 16 minutos para ordenar 1 milhão de números — se tiver o algoritmo errado. Outro algoritmo pode fazer o mesmo em menos de 1 segundo. Essa diferença não vem do hardware, mas da matemática por trás de como o tempo de execução cresce com o tamanho da entrada.
Para entradas pequenas, qualquer algoritmo parece rápido. O computador moderno é tão veloz que as diferenças são imperceptíveis. O problema aparece em escala: bases de dados com bilhões de registros, imagens com milhões de pixels, redes sociais com centenas de milhões de usuários. Nesses contextos, escolher o algoritmo errado pode tornar um produto inutilizável.
A análise de complexidade dá uma linguagem matemática para comparar algoritmos independentemente do hardware. Em vez de medir segundos (que variam com o processador), medimos como o número de operações cresce em relação ao tamanho n da entrada.
🧮 Teste você mesmo — CalcSim
Quer mais recursos? Baixar app CalcSim IA
A notação Big-O
Big-O é uma notação matemática que descreve o comportamento de crescimento de uma função. O(f(n)) significa 'o tempo de execução cresce proporcionalmente a f(n) no pior caso, ignorando constantes e termos menores'.
Por que ignorar constantes? Porque o que importa é a tendência de crescimento. Um algoritmo que faz 100n operações e outro que faz 5n operações têm a mesma classe de complexidade O(n). Para n = 1 milhão, ambos fazem entre 5 e 100 milhões de operações — a diferença é um fator constante, não uma diferença de escala.
Big-O descreve o pior caso. A busca linear em uma lista de n elementos pode encontrar o elemento na primeira posição (1 operação) ou na última (n operações). Big-O se preocupa com o pior caso: O(n).
As quatro complexidades mais comuns
O(1) — constante: o tempo de execução não depende do tamanho da entrada. Acessar um elemento de um array pelo índice é O(1): notas[42] sempre leva o mesmo tempo, seja o array de 10 ou de 10 milhões de elementos. É a melhor complexidade possível.
O(n) — linear: o tempo cresce proporcionalmente ao tamanho da entrada. A busca linear (percorrer todos os elementos até encontrar o buscado) é O(n). Se n dobra, o tempo máximo dobra. Para n = 1 milhão, até 1 milhão de comparações.
O(n²) — quadrático: comum em algoritmos com dois laços aninhados. O Bubble Sort é O(n²): para cada um dos n elementos, faz até n comparações. Se n dobra, o tempo quadruplica. Para n = 10.000, até 100 milhões de operações — começa a ficar lento.
O(log n) — logarítmica: o tempo cresce muito devagar. A busca binária em uma lista ordenada é O(log n): a cada passo, elimina metade dos elementos restantes. Para n = 1 bilhão, são necessárias apenas 30 comparações (log₂ de 1.000.000.000 ≈ 30). É praticamente constante na prática.
- O(1): constante — acesso por índice, inserção no início de uma hashtable
- O(log n): logarítmica — busca binária, operações em árvores balanceadas
- O(n): linear — busca linear, percorrer uma lista
- O(n log n): log-linear — Merge Sort, Quicksort (caso médio)
- O(n²): quadrática — Bubble Sort, dois laços aninhados sobre n elementos
Busca linear versus busca binária
A busca linear verifica cada elemento do início ao fim. É O(n) e funciona em qualquer lista, ordenada ou não. A busca binária exige que a lista esteja ordenada, mas é muito mais eficiente: O(log n).
Como funciona a busca binária? Pegue o elemento do meio da lista. Se for o buscado, acabou. Se for maior que o buscado, descarte a metade direita e repita na metade esquerda. Se for menor, descarte a metade esquerda e repita na metade direita. A cada passo, o espaço de busca é cortado pela metade.
Comparação prática: buscar um nome em uma lista de 1 milhão de pessoas ordenada alfabeticamente. Busca linear: até 1.000.000 comparações. Busca binária: até 20 comparações. Essa diferença dramática explica por que bancos de dados ordenam seus índices e por que a ordenação é tão importante.
Implicações práticas para software real
No dia a dia do desenvolvimento, o conhecimento de complexidade guia escolhas de estrutura de dados. Hashtables (dicionários) oferecem inserção e busca O(1) em média — é por isso que são onipresentes. Árvores binárias balanceadas oferecem O(log n) para busca, inserção e remoção — usadas em bancos de dados e sistemas de arquivos.
Um erro comum é chamar uma função O(n) dentro de um laço O(n), criando inadvertidamente um algoritmo O(n²). Isso pode passar despercebido em testes com poucos dados e só aparecer em produção, com dados reais.
Otimização prematura é um problema real: não tente otimizar antes de identificar gargalos. Mas conhecer a complexidade dos algoritmos que você usa é diferente de otimizar prematuramente — é fazer escolhas informadas desde o início do design.
Perguntas frequentes
Big-O mede tempo ou memória?
Big-O pode medir ambos. A complexidade de tempo (temporal) descreve quantas operações o algoritmo executa. A complexidade de espaço (espacial) descreve quanta memória adicional é necessária em função do tamanho da entrada. Geralmente, quando se fala em Big-O sem especificação, refere-se à complexidade temporal.
O que é complexidade de caso médio versus pior caso?
O pior caso é o cenário mais desfavorável possível. O caso médio é a expectativa sobre entradas aleatórias. O Quicksort tem pior caso O(n²) (quando o pivô é sempre o menor ou maior elemento) mas caso médio O(n log n). Na prática, o caso médio costuma ser mais relevante, mas o pior caso importa em sistemas críticos.
Um algoritmo O(n²) é sempre pior que um O(n)?
Para n suficientemente grande, sim. Mas para n pequeno, um algoritmo O(n²) com constante baixa pode ser mais rápido que um O(n) com constante alta. O Insertion Sort (O(n²)) frequentemente é mais rápido que o Merge Sort (O(n log n)) para listas com menos de 20–30 elementos, por ter overhead menor.
Como saber a complexidade de um algoritmo que escrevi?
Conte os laços e como eles crescem com n. Um laço simples sobre n elementos é O(n). Dois laços aninhados, cada um sobre n elementos, é O(n²). Se a cada iteração você divide o problema pela metade (como na busca binária), é O(log n). Ignore constantes e termos dominados pelo maior.
Complexidade importa para iniciantes?
Entender os conceitos básicos sim — saber que dois laços aninhados são potencialmente problemáticos e que busca em lista desordenada é mais lenta que em ordenada são conhecimentos práticos imediatos. Análise formal detalhada pode ser aprendida gradualmente conforme a experiência aumenta.
Este artigo foi útil para você?
Avalie com estrelas para nos ajudar a melhorar o conteúdo.
Faça login para avaliar este artigo.
Ainda tem dúvida?
O Professor IA explica passo a passo
Faça uma pergunta em linguagem natural e receba uma explicação personalizada sobre Lógica de Programação — ou qualquer outro tópico.
Prefere resolver pelo celular?
Baixar o app grátis →Continue aprendendo