Visão Geral dos Algoritmos

0:00 / 0:00

Um algoritmo é uma receita pra resolver um problema: uma sequência finita de passos que, dado um input, produz um output. Existe muito antes do computador — e a forma como a gente escreve algoritmos hoje é resultado de uma evolução de mais de 2 mil anos. Esta página percorre essa linha do tempo em 6 paradas, do papiro até o Clean Code.

1. Antes do computador — algoritmo é mais velho que máquina +

A ideia de "passo a passo pra resolver um problema" não nasceu com a informática. Ela é matemática pura, e tem nomes bem antigos.

QuandoQuemO quê
~300 a.C.EuclidesAlgoritmo de Euclides — calcula MDC de dois números. Considerado o primeiro algoritmo formal documentado.
séc. IXAl-KhwarizmiMatemático persa. O nome "algoritmo" vem da latinização do nome dele (Algoritmi). Também deu origem à palavra "álgebra".
1843Ada LovelaceEscreveu o primeiro algoritmo destinado a uma máquina (a Máquina Analítica de Babbage, que nunca chegou a ser construída). É considerada a primeira programadora.
1936Alan TuringDefine formalmente o que é "computável" com a Máquina de Turing — modelo teórico que fundamenta a ciência da computação.

Ou seja: quando o primeiro computador foi ligado, já tinha 2 mil anos de teoria de algoritmos esperando.

2. A máquina nua — linguagem de máquina e Assembly +

Os primeiros computadores eletrônicos (anos 40) eram programados diretamente em binário — sequências de 0 e 1 que o processador entende como instruções.

Linguagem de máquina

Cada CPU tem um conjunto de instruções próprio. Uma instrução pra somar dois números pode ser algo como 10110000 01100001. Programar assim é tedioso e propenso a erro — qualquer bit trocado quebra o programa.

Assembly

Veio em seguida como uma camada fina por cima do binário. Em vez de 10110000, você escreve MOV AL, 61h. Cada instrução Assembly corresponde a uma instrução de máquina (relação 1:1), mas com nomes legíveis (mnemônicos).

; soma dois números em Assembly x86
MOV AX, 5      ; coloca 5 no registrador AX
ADD AX, 3      ; soma 3 ao AX
; AX agora vale 8

Ainda é colado no hardware: você precisa saber quais registradores existem, como a CPU lê memória, etc. Não tem if, não tem for, não tem função — só JUMP (pular pra outro lugar do código).

3. As linguagens estruturadas — onde nasceu o for, while, if e função +

Anos 50 e 60. O custo de programar em Assembly era altíssimo — cada projeto reinventava a roda. Surgem as linguagens de alto nível: você escreve algo próximo da matemática e um compilador traduz pra Assembly.

AnoLinguagemFoco
1957FORTRANCálculo científico. Primeira linguagem de alto nível com adoção real.
1958LISPInteligência artificial. Inventou o paradigma funcional.
1958ALGOLLinguagem acadêmica. Inventou os blocos de código, o if/then/else, o for, o while e o conceito de função recursiva.
1959COBOLAplicações comerciais. Ainda roda em bancos hoje.
1972CSíntese: rápido como Assembly, estruturado como ALGOL. Vira a base do mundo Unix e fundação de quase tudo que veio depois.

A revolução do ALGOL

Quando alguém pergunta "onde foram criados os for, while, if, e funções?" — a resposta é ALGOL 58/60. Antes dele, o controle de fluxo era feito com GOTO (pular pra um número de linha). ALGOL inventou:

  • Blocos de código com BEGIN/END (depois viraria { } no C)
  • Estruturas de controle: if-then-else, for, while
  • Funções e procedimentos com parâmetros e recursão
  • Escopo léxico de variáveis

Programação estruturada (1968)

Edsger Dijkstra publica "Go To Considered Harmful" — um manifesto contra o uso de GOTO. Defende que todo algoritmo pode (e deve) ser escrito apenas com sequência, seleção (if) e repetição (loops). Esse paradigma ficou conhecido como programação estruturada e dominou os anos 70/80.

A parada no C

O C (Dennis Ritchie, 1972) consolidou tudo isso numa linguagem prática e portátil. Sintaxe enxuta, performance perto do Assembly, e a possibilidade de escrever sistemas operacionais inteiros (Unix). Java, JavaScript, Python, C# — todas herdam sintaxe do C.

// um algoritmo estruturado em C — soma de 1 a N
int somatorio(int n) {
    int total = 0;
    for (int i = 1; i <= n; i++) {
        total += i;
    }
    return total;
}
4. Algoritmos viram ciência — Knuth, estruturas de dados e Big O +

Em 1968, Donald Knuth começa a publicar The Art of Computer Programming — uma série de livros que formaliza algoritmos como disciplina científica. A pergunta deixa de ser "esse código funciona?" e passa a ser "esse código é eficiente?".

Estruturas de dados clássicas

Diferentes formas de organizar dados na memória, cada uma boa pra um tipo de operação:

EstruturaPra que serveExemplo
Array / ListaAcesso por índiceLista de produtos no carrinho
Pilha (Stack)Último a entrar, primeiro a sair (LIFO)Botão "voltar" do navegador
Fila (Queue)Primeiro a entrar, primeiro a sair (FIFO)Fila de impressão
Hash / DicionárioBusca por chave em tempo constanteCache de sessão por user_id
ÁrvoreHierarquia + busca rápidaSistema de arquivos, índices de banco
GrafoRelações entre entidadesRede social, mapa de ruas (GPS)

Big O — medindo "rápido" e "lento"

Notação que descreve como o tempo cresce conforme o input cresce, ignorando constantes. É o vocabulário universal pra dizer se um algoritmo escala.

Big OComo cresceExemplo
O(1)ConstanteAcesso a item de array por índice
O(log n)Logarítmico — muito bomBusca binária, busca em árvore balanceada
O(n)LinearPercorrer uma lista
O(n log n)Bom pra ordenaçãoMergeSort, QuickSort
O(n²)Quadrático — ruim em listas grandesBubbleSort, dois loops aninhados
O(2ⁿ)Exponencial — proibitivoForça bruta em problemas combinatórios

Ordenar 1 milhão de itens com BubbleSort (O(n²)) leva minutos; com QuickSort (O(n log n)) leva milissegundos. Mesmo input, mesma máquina — só muda o algoritmo.

5. Outros paradigmas — não foi só procedural → OO +

A história costuma ser contada como uma linha reta: máquina → estruturada → orientada a objetos. Mas a evolução foi vários paradigmas em paralelo, cada um resolvendo o problema do seu jeito.

ParadigmaIdeia centralLinguagens
Imperativo / ProceduralSequência de comandos que mudam estadoC, Pascal, FORTRAN
Orientado a ObjetosDados + comportamento juntos em classesSmalltalk (1972), C++, Java
FuncionalFunções puras, sem estado mutávelLisp (1958), Haskell, Erlang
LógicoVocê declara fatos e regras; a máquina deduz a respostaProlog (1972)
DeclarativoDiz o que quer, não como obterSQL (1974), HTML

O retorno do funcional

Por décadas, OO dominou. Mas a partir de 2010 o estilo funcional voltou forte — Java 8 ganhou lambdas e Stream, JavaScript adotou map/filter/reduce, Kotlin e Scala misturam OO com funcional.

// estilo procedural
int total = 0;
for (Pedido p : pedidos) {
    if (p.isPago()) {
        total += p.getValor();
    }
}

// estilo funcional (Java 8+)
int total = pedidos.stream()
    .filter(Pedido::isPago)
    .mapToInt(Pedido::getValor)
    .sum();

Os dois fazem a mesma coisa, mas o segundo expressa a intenção, não o passo a passo. É a mesma onda do SQL — você diz "me dá os pagos", não "percorra a lista um por um".

6. OO e o caminho até o Clean Code +

Conforme os sistemas cresceram (anos 80/90), ficou claro que escrever um algoritmo que funciona não basta — ele precisa ser legível, testável e modificável. Surgem livros e movimentos focados em qualidade de código.

AnoMarcoContribuição
1972SmalltalkPrimeira linguagem 100% orientada a objetos. Define os conceitos de classe, objeto, mensagem, herança.
1994Design Patterns (Gang of Four)23 padrões reutilizáveis pra problemas recorrentes em OO: Singleton, Factory, Observer, Strategy, etc.
1999Refactoring (Martin Fowler)Catalogou 70+ refatorações com nome próprio: Extract Method, Rename Variable, Replace Conditional with Polymorphism.
1999TDD (Kent Beck)Escrever o teste antes do código. Ciclo "red → green → refactor".
2000sSOLID (Robert Martin)5 princípios pra OO escalável: SRP, OCP, LSP, ISP, DIP.
2008Clean Code (Robert Martin)Síntese de tudo acima — nomes claros, funções pequenas, sem comentários redundantes, testes confiáveis.

O que mudou na cabeça do programador

Antes: "se compila e roda, tá bom". Depois: código é lido 10x mais vezes do que escrito — e o leitor é você daqui a 6 meses, ou um colega novo. O algoritmo continua sendo o mesmo, mas como ele é expresso ganha tanta importância quanto se ele funciona.

// "funciona" mas é difícil de ler
public boolean v(User u) {
    return u != null && u.s == 1 && u.t > 0;
}

// Clean Code — o nome conta a história
public boolean isUserActive(User user) {
    return user != null
        && user.getStatus() == STATUS_ACTIVE
        && user.getRemainingTokens() > 0;
}
Linha do tempo — resumo +
EraPeríodoMarco
1. Pré-computador300 a.C. – 1936Euclides → Al-Khwarizmi → Lovelace → Turing
2. A máquina nua1940sLinguagem de máquina, Assembly
3. Estruturadas1957 – 1972FORTRAN → ALGOL (for/while/if) → C
4. Algoritmos como ciência1968+Knuth, estruturas de dados, Big O
5. Outros paradigmas1958+Lisp (funcional), Prolog (lógico), SQL (declarativo)
6. OO e qualidade1972 – 2008Smalltalk → GoF → Refactoring → SOLID → Clean Code

Cada era resolveu um problema da anterior: máquina nua era impraticável → estruturadas. Estruturadas viraram caóticas em sistemas grandes → OO. OO virou bagunçada → Clean Code. A próxima era já está em curso (IA gerando código), e provavelmente vai cobrar a próxima conta.