Este contenido solo está disponible en Portugués.
Aún sin traducción para este idioma.
Algoritmos e Lógica de Programação: O Mapa que Todo Desenvolvedor Precisa
Aprenda a resolver problemas no papel antes de codificar. Entenda sequência, seleção, repetição, algoritmos de ordenação e complexidade Big O.

Você não travou porque algoritmos são difíceis. Travou porque ninguém te mostrou o problema antes de te entregar a solução. Esse artigo corrige isso — do conceito mais simples até análise de complexidade.
Essa sensação tem nome — e tem solução. Ela acontece quando você tenta escrever código antes de pensar no algoritmo. É como tentar construir uma casa sem planta: você até levanta algumas paredes, mas logo percebe que o banheiro ficou no lugar errado.
Este artigo vai te mostrar o mapa que todo desenvolvedor precisa dominar antes de digitar a primeira linha de código.
O que é um Algoritmo, de Verdade?
Esqueça a definição acadêmica por um segundo.
Um algoritmo é simplesmente uma sequência finita e ordenada de passos para resolver um problema. Sem ambiguidade. Sem passos que dependem de adivinhação. Cada instrução precisa ser clara o suficiente para que uma máquina — que não pensa, apenas executa — consiga seguir.
Pense na receita de bolo da sua avó. Ela tem ingredientes (dados de entrada), uma ordem de preparo (passos executáveis) e um resultado esperado (saída). Se você pular um passo ou trocar a ordem, o bolo não sai certo. Com algoritmos, a lógica é exatamente a mesma.
A grande virada mental que separa programadores iniciantes de programadores sólidos é: primeiro você resolve o problema no papel, depois você escreve o código.
As Três Estruturas que Governam Tudo
Toda a lógica de programação — independente da linguagem — se apoia em apenas três estruturas de controle. Sim, apenas três.

1. Sequência
A mais simples. Os passos são executados um após o outro, na ordem em que aparecem.
int x = 10;
int y = 20;
int soma = x + y;
printf("Resultado: %d\n", soma);Nada de surpresa. O computador lê linha por linha, de cima para baixo.
2. Seleção (Decisão)
Aqui o programa ganha inteligência. Dependendo de uma condição, ele escolhe um caminho ou outro.
if (temperatura > 38) {
printf("Febre detectada. Consulte um médico.\n");
} else {
printf("Temperatura normal.\n");
}Existem três formas principais de seleção:
- Simples: um ou dois caminhos alternativos (
if/else) - Encadeada: escolha entre vários caminhos (
if/else if/else) - Múltipla: comparar uma variável com vários valores fixos (
switch/case)
O switch/case é perfeito quando você tem muitas opções bem definidas — como os dias da semana ou as opções de um menu.
3. Repetição (Laços)
O coração da automação. Executar o mesmo bloco de código várias vezes sem precisar reescrevê-lo.
Repetição contada — quando você sabe exatamente quantas vezes vai repetir:
for (int i = 1; i <= 10; i++) {
printf("%d\n", i);
}Repetição com pré-condição — quando você testa a condição antes de entrar no laço:
while (saldo > 0) {
saldo -= parcela;
}Repetição com pós-condição — quando o bloco precisa executar pelo menos uma vez:
do {
printf("Digite um número positivo: ");
scanf("%d", &numero);
} while (numero <= 0);Regra de ouro: evite laços infinitos interrompidos por break. Se você precisa de um break para sair de um laço, provavelmente a condição de parada foi mal definida.
Tipos de Dados: A Matéria-Prima do Programa
Antes de processar qualquer informação, o computador precisa saber com que tipo de dado está lidando. Em C, os tipos básicos são:
| Tipo | O que armazena | Exemplo |
|---|---|---|
| int | Números inteiros | 42, -7, 0 |
| float | Números com casas decimais | 3.14, -0.5 |
| char | Um único caractere | 'A', 'z' |
| char[] | Cadeia de caracteres (texto) | "Olá, mundo" |
Esses dados vivem como variáveis (valores que mudam durante a execução) ou constantes (valores que nunca mudam). Usar constantes para valores fixos — como PI = 3.14159 — torna o código mais legível e seguro.
Funções: O Segredo do Código Limpo
Se você se pegar repetindo o mesmo bloco de código em lugares diferentes, é sinal de que aquele trecho merece virar uma função.
Uma função é um bloco de código com um objetivo específico. Ela recebe dados (parâmetros), processa e devolve um resultado.
float calcularMedia(float nota1, float nota2, float nota3) {
return (nota1 + nota2 + nota3) / 3;
}Existem dois tipos fundamentais:
- void: a função executa uma ação e não devolve nada (como imprimir na tela)
- Tipada (int, float...): a função faz um cálculo e devolve um resultado
Boas funções têm nomes que descrevem exatamente o que fazem. calcularMedia() é muito melhor do que func1(). Seu eu do futuro — e seus colegas de equipe — vão agradecer.
Boas Práticas que Fazem Diferença
Dominar a sintaxe é a parte fácil. O que separa um código amador de um código profissional são os hábitos.
Planeje antes de codificar. Antes de abrir o editor, defina: quais dados entram? Quais saem? Qual a sequência de passos? Um rascunho em papel vale mais do que uma hora de tentativa e erro.
Comente o que não é óbvio. O compilador ignora comentários, mas seus colegas (e você mesmo, daqui a seis meses) não. Documente a intenção do código, não apenas o que ele faz.
// Calcula o índice de massa corporal conforme tabela da OMS
float imc = peso / (altura * altura);Escreva código portável. Evite funções específicas de um sistema operacional quando existir uma alternativa no padrão ISO do C. Código portável roda em Windows, Linux e Unix sem modificações.
Use nomes significativos. temperatura, contador, nomeUsuario são infinitamente melhores que t, c, n. Clareza não é frescura — é respeito pelo próximo que vai ler seu código.
Algoritmos Clássicos que Todo Programador Deve Conhecer
Teoria sem prática é decoração. Veja como os conceitos acima se materializam em algoritmos reais — os mesmos usados em bancos de dados, sistemas de busca e aplicações do dia a dia.
Busca Linear vs. Busca Binária: a diferença que muda tudo
Imagine que você precisa encontrar o número 23 em uma lista de mil números.
Busca Linear — verifica um por um, do início ao fim:
def busca_linear(lista, alvo):
for i in range(len(lista)):
if lista[i] == alvo:
return i # retorna o índice onde encontrou
return -1 # não encontrado
numeros = [2, 5, 8, 12, 16, 23, 38, 56, 72, 91]
print(busca_linear(numeros, 23)) # saída: 5Funciona. Mas no pior caso, percorre todos os elementos. Em uma lista de um milhão? Um milhão de comparações.
Busca Binária — divide o problema ao meio a cada passo. Requer lista ordenada:
def busca_binaria(lista, alvo):
inicio = 0
fim = len(lista) - 1
while inicio <= fim:
meio = inicio + (fim - inicio) // 2
if lista[meio] == alvo:
return meio # encontrou!
elif lista[meio] < alvo:
inicio = meio + 1 # descarta a metade esquerda
else:
fim = meio - 1 # descarta a metade direita
return -1 # não encontrado
numeros = [2, 5, 8, 12, 16, 23, 38, 56, 72, 91]
print(busca_binaria(numeros, 23)) # saída: 5Em uma lista de um milhão de elementos, a busca binária encontra qualquer valor em no máximo 20 comparações. Não é mágica — é logaritmo.
| Algoritmo | Pior caso (1 milhão de itens) | Requer ordenação? |
|---|---|---|
| Busca Linear | 1.000.000 comparações | Não |
| Busca Binária | ~20 comparações | Sim |

Algoritmos de Ordenação: colocando a casa em ordem
Para usar a busca binária, você precisa de dados ordenados. E para ordenar dados, você precisa de um algoritmo de ordenação.
Bubble Sort — o mais simples para entender. Funciona como bolhas subindo à superfície: a cada passagem, o maior elemento flutua para o fim:
def bubble_sort(lista):
n = len(lista)
for i in range(n):
for j in range(0, n - i - 1):
# se o elemento atual é maior que o próximo, troca
if lista[j] > lista[j + 1]:
lista[j], lista[j + 1] = lista[j + 1], lista[j]
return lista
numeros = [64, 34, 25, 12, 22, 11, 90]
print(bubble_sort(numeros)) # [11, 12, 22, 25, 34, 64, 90]O mesmo algoritmo em C:
void bubble_sort(int arr[], int n) {
for (int i = 0; i < n - 1; i++) {
for (int j = 0; j < n - i - 1; j++) {
if (arr[j] > arr[j + 1]) {
int temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
}Por que aprender Bubble Sort se ele é lento? Porque ele ensina os padrões fundamentais de ordenação: comparação, troca e passagens múltiplas. Depois de entender o Bubble Sort, algoritmos como Merge Sort e Quick Sort fazem sentido imediato.
Recursão: quando a função chama a si mesma
Um conceito que assusta iniciantes mas é elegante quando você entende: uma função que resolve um problema chamando a si mesma com uma versão menor do mesmo problema.
def fatorial(n):
# caso base: para a recursão
if n == 0 or n == 1:
return 1
# chamada recursiva com problema menor
return n * fatorial(n - 1)
print(fatorial(5)) # 5 × 4 × 3 × 2 × 1 = 120Toda função recursiva tem dois componentes obrigatórios:
- Caso base: a condição de parada (sem ela, recursão infinita)
- Chamada recursiva: o problema reduzido a uma versão menor de si mesmo
Recursão é a base de algoritmos poderosos como Merge Sort, busca em árvores e travessia de grafos.
Complexidade de Algoritmos: o custo do que você escreve
Todo algoritmo tem um custo. A notação Big O descreve como esse custo cresce conforme o tamanho da entrada aumenta.
| Notação | Nome | Exemplo |
|---|---|---|
| O(1) | Constante | Acessar elemento de array por índice |
| O(log n) | Logarítmica | Busca Binária |
| O(n) | Linear | Busca Linear |
| O(n log n) | Linearítmica | Merge Sort, Quick Sort |
| O(n²) | Quadrática | Bubble Sort, Selection Sort |
A escolha do algoritmo impacta diretamente a performance do sistema. Um algoritmo O(n²) aplicado a um milhão de registros é catastrófico. O mesmo problema com O(log n) roda em milissegundos.

O Erro Mais Comum de Quem Está Começando
A maioria dos iniciantes tenta aprender programação aprendendo linguagem.
Decoram a sintaxe do if, do for, do while — mas quando chegam em um problema real, travam. Porque o problema nunca é a sintaxe. O problema é a lógica.
A linguagem é apenas a notação. O algoritmo é o pensamento.
Inverta a ordem: primeiro resolva o problema no papel, depois traduza para o código. Desenhe o fluxo. Quebre o problema em partes menores. Defina as entradas e saídas de cada parte. Só então abra o editor.
Esse hábito — aparentemente simples — é o que diferencia um programador que avança de um que fica preso eternamente nos tutoriais.
Conclusão
Algoritmos e lógica de programação não são matéria de faculdade. São a base de tudo que você vai construir como desenvolvedor.
Sequência, seleção e repetição. Tipos de dados. Funções bem nomeadas. Busca binária. Complexidade Big O. Planejamento antes do código.
Esses conceitos não saem de moda. Não importa se a linguagem do momento é C, Python, JavaScript ou qualquer outra que surgir nos próximos anos — a lógica por trás de todas elas é a mesma.
O que ficou
- Algoritmo: sequência finita e ordenada de passos para resolver um problema.
- Três estruturas de controle: sequência, seleção e repetição.
- Tipos de dados: int, float, char — variáveis vs constantes.
- Funções: blocos reutilizáveis com objetivo específico.
- Busca Binária é O(log n) — exponencialmente mais rápida que busca linear.
- Bubble Sort ensina os padrões de ordenação que todo algoritmo avançado usa.
- Recursão: caso base + chamada recursiva. Sempre.
- Big O: O custo do algoritmo determina se o sistema escala ou trava.
- Primeiro resolva no papel. Depois abra o editor.



