Domine inglês técnico de programação em 2025, seja qual for seu nível. Inscrição gratuita
Recursão e algoritmos básicos: desvendando o poder oculto da programação
Rocketseat
Navegação Rápida:
Já pensou em olhar para dois espelhos posicionados frente a frente? A imagem parece se repetir infinitamente, criando um túnel sem fim. Isso soa familiar? Bem-vindo ao fascinante mundo da recursão na programação! Aqui, uma função tem a incrível habilidade de chamar a si mesma, mergulhando em um loop que só termina quando uma condição específica é satisfeita. Parece complicado? Calma, vamos explorar juntos esse conceito de forma simples e divertida!
O que é recursão?
Imagine que o Diego, nosso CTO na Rocketseat, está liderando a criação de um sistema de navegação em diretórios para gerenciar projetos de programação. Cada pasta pode conter arquivos e outras subpastas, que por sua vez contêm mais arquivos e subpastas. Como navegar por essa estrutura infinita?
A resposta é: recursão. Em vez de tentar resolver tudo de uma vez, o algoritmo desce em cada subpasta e a trata como um problema menor, resolvendo parte por parte até chegar a um final.
Na programação, a recursão funciona assim: uma função chama a si mesma para dividir um problema maior em subproblemas menores, até encontrar uma solução simples (o famoso caso base).
Algoritmos básicos recursivos
Vamos colocar a mão na massa e ver alguns exemplos práticos? Prepare seu editor de código e vamos codar juntos!
Fatorial
O fatorial de um número é o produto de todos os números inteiros positivos até ele. Por exemplo, o fatorial de 5 (representado por 5!) é 5 × 4 × 3 × 2 × 1 = 120.
Implementação em JavaScript:
function fatorial(n) { if (n === 0 || n === 1) { return 1; // Caso base } else { return n * fatorial(n - 1); // Chamada recursiva } } console.log(fatorial(5)); // Saída: 120
Perceba como a funçãofatorial
chama a si mesma comn - 1
até quen
seja 0 ou 1.
Sequência de Fibonacci
A sequência de Fibonacci é famosa: cada número é a soma dos dois anteriores. Sequência: 0, 1, 1, 2, 3, 5, 8, 13, ...
Implementação em Python:
def fibonacci(n): if n <= 1: return n # Caso base else: return fibonacci(n-1) + fibonacci(n-2) # Chamadas recursivas print(fibonacci(7)) # Saída: 13
Aqui, a funçãofibonacci
chama a si mesma duas vezes, reduzindo o problema a somas de números menores na sequência.
Busca binária
A busca binária é um algoritmo eficiente para encontrar um elemento em um array ordenado, dividindo o espaço de busca pela metade a cada iteração.
Implementação em JavaScript:
function buscaBinaria(array, valor, inicio = 0, fim = array.length - 1) { if (inicio > fim) { return -1; // Valor não encontrado } let meio = Math.floor((inicio + fim) / 2); if (array[meio] === valor) { return meio; // Valor encontrado } else if (array[meio] > valor) { return buscaBinaria(array, valor, inicio, meio - 1); // Busca na metade esquerda } else { return buscaBinaria(array, valor, meio + 1, fim); // Busca na metade direita } } const numeros = [1, 3, 5, 7, 9, 11]; console.log(buscaBinaria(numeros, 7)); // Saída: 3
A funçãobuscaBinaria
divide o array continuamente até encontrar o valor ou concluir que ele não está presente.
Torres de Hanoi
Este é um clássico problema que envolve mover uma pilha de discos entre hastes, seguindo regras específicas.
Implementação em Python:
def torres_de_hanoi(n, origem, destino, auxiliar): if n == 1: print(f"Mova o disco 1 de {origem} para {destino}") return torres_de_hanoi(n-1, origem, auxiliar, destino) print(f"Mova o disco {n} de {origem} para {destino}") torres_de_hanoi(n-1, auxiliar, destino, origem) torres_de_hanoi(3, 'A', 'C', 'B')
A funçãotorres_de_hanoi
resolve o problema movendo discos entre as hastes de forma recursiva.
Por que a recursão é importante?
Elegância e simplicidade
A recursão permite escrever código que é mais próximo da definição matemática do problema. Isso torna as soluções mais elegantes e, muitas vezes, mais fáceis de entender.
Dividir para conquistar
Esse é um princípio fundamental na ciência da computação. Ao dividir um problema complexo em subproblemas menores, podemos resolvê-lo de maneira mais eficiente. A recursão é a ferramenta perfeita para implementar essa estratégia.
Aplicações na vida real
A recursão está presente em diversas áreas:
- Inteligência artificial: algoritmos como minimax em jogos de tabuleiro utilizam recursão para prever movimentos.
- Processamento de imagens: fractais e algoritmos de preenchimento usam recursão para repetir padrões.
- Sistemas operacionais: navegação em sistemas de arquivos, onde pastas podem conter outras pastas.
A recursão pode parecer desafiadora no início, mas com prática e paciência, você vai perceber o quão poderosa ela é. Então, pronto para mergulhar nesse universo infinito de possibilidades? A Rocketseat está aqui para te acompanhar nessa jornada. Bora codar?
Vamos codar juntos?
Imagine que a Fernanda precisa organizar uma lista enorme de nomes para um evento da Rocketseat. Ordenar essa lista manualmente seria uma tarefa árdua, mas com o algoritmo merge sort, isso se torna simples e eficiente.
O conceito por trás do merge sort
O merge sort é um algoritmo de ordenação que segue o princípio "dividir para conquistar". Ele funciona da seguinte maneira:
- Divisão: divide a lista original em duas metades aproximadamente iguais.
- Conquista: ordena recursivamente as duas metades.
- Combinação: mescla as duas metades ordenadas em uma única lista ordenada.
Passo a passo do algoritmo
Vamos implementar o merge sort passo a passo usando JavaScript.
Passo 1: dividir o array
Criamos uma função
mergeSort
que divide o array ao meio até que cada subarray tenha apenas um elemento.function mergeSort(array) { if (array.length <= 1) { return array; // Caso base: array de tamanho 0 ou 1 já está ordenado } const meio = Math.floor(array.length / 2); const esquerda = array.slice(0, meio); const direita = array.slice(meio); // Chamada recursiva para cada metade return merge(mergeSort(esquerda), mergeSort(direita)); }
Passo 2: ordenar recursivamente as metades
A função
mergeSort
é chamada recursivamente para cada metade do array até atingir o caso base.- Caso base: quando o array tem tamanho 0 ou 1, ele é retornado como está.
- Chamada recursiva: a função continua dividindo as metades até chegar ao caso base.
Passo 3: mesclar os arrays ordenados
Criamos a função
merge
para combinar dois arrays ordenados em um único array ordenado.function merge(esquerda, direita) { let resultado = []; let indiceEsquerda = 0; let indiceDireita = 0; while (indiceEsquerda < esquerda.length && indiceDireita < direita.length) { if (esquerda[indiceEsquerda] < direita[indiceDireita]) { resultado.push(esquerda[indiceEsquerda]); indiceEsquerda++; } else { resultado.push(direita[indiceDireita]); indiceDireita++; } } // Concatena os elementos restantes return resultado .concat(esquerda.slice(indiceEsquerda)) .concat(direita.slice(indiceDireita)); }
Passo 4: testar o algoritmo com a lista da Fernanda
Vamos usar o algoritmo para ordenar a lista de participantes:
const participantes = ['Diego', 'Mayk', 'Larissa', 'Fernanda', 'Ana', 'Bruno']; console.log(mergeSort(participantes)); // Saída: ['Ana', 'Bruno', 'Diego', 'Fernanda', 'Larissa', 'Mayk']
Visualizando o processo de ordenação
Vamos ver como o merge sort funciona com a lista da Fernanda.
Divisão Inicial
['Diego', 'Mayk', 'Larissa'] | ['Fernanda', 'Ana', 'Bruno']
Divisão Recursiva
- Esquerda:
['Diego'] | ['Mayk', 'Larissa']
['Mayk'] | ['Larissa']
- Direita:
['Fernanda'] | ['Ana', 'Bruno']
['Ana'] | ['Bruno']
Caso base
- Agora, todos os subarrays têm apenas um elemento.
Combinação (mesclagem)
- Mesclando ['Mayk'] e ['Larissa']:
- 'Larissa' vem antes de 'Mayk'.
- Resultado:
['Larissa', 'Mayk']
- Mesclando ['Diego'] com ['Larissa', 'Mayk']:
- 'Diego' vem antes de 'Larissa'.
- Resultado:
['Diego', 'Larissa', 'Mayk']
- Mesclando ['Ana'] e ['Bruno']:
- 'Ana' vem antes de 'Bruno'.
- Resultado:
['Ana', 'Bruno']
- Mesclando ['Fernanda'] com ['Ana', 'Bruno']:
- 'Ana' vem antes de 'Fernanda'.
- 'Bruno' vem antes de 'Fernanda'.
- Resultado:
['Ana', 'Bruno', 'Fernanda']
- Mesclando as duas metades finais:
- Comparar 'Diego' e 'Ana' → 'Ana' primeiro.
- Comparar 'Diego' e 'Bruno' → 'Bruno' primeiro.
- Comparar 'Diego' e 'Fernanda' → 'Diego' primeiro.
- Seguem 'Fernanda', 'Larissa' e 'Mayk'.
- Resultado final:
['Ana', 'Bruno', 'Diego', 'Fernanda', 'Larissa', 'Mayk']
Por que a recursão é essencial aqui?
A recursão simplifica o processo de dividir e mesclar, tornando o código mais intuitivo e próximo da definição conceitual do algoritmo.
- Divisão recursiva: a função se chama para dividir o array até chegar ao caso base.
- Mesclagem ordenada: a combinação dos subarrays é feita de forma ordenada, garantindo a ordenação final.
Com esse passo a passo detalhado, a Fernanda pode usar o Merge Sort para organizar eficientemente qualquer lista, garantindo que tudo esteja em ordem para os eventos da Rocketseat. E você, pronto para implementar o Merge Sort nos seus projetos?
Materiais para aprimorar seus conhecimentos
- Loops em JavaScript: Um guia básico para iniciantes
Entenda como os loops funcionam e otimize suas habilidades em JavaScript com exemplos práticos.
- Problemas de lógica em JavaScript
Resolva problemas clássicos de lógica com soluções detalhadas em JavaScript.
- Desafios clássicos de lógica com Python
Teste suas habilidades em lógica com desafios interessantes resolvidos em Python.
- Loops em Python explicados
Domine os loops em Python com explicações claras e exemplos aplicáveis.
Cursos gratuitos: comece sua jornada hoje mesmo
- ‣ Minicurso de Python
Descubra os fundamentos do Python e aplique conceitos funcionais de forma prática.
- ‣ Curso Discover - JavaScript, CSS e HTML
Aprofunde-se nos fundamentos do desenvolvimento web e domine o JavaScript, que suporta paradigmas funcionais e imperativos.
Transforme sua carreira com a formação Full-Stack
Quer dar um grande salto na sua carreira? Conheça nossa formação Full-Stack, um programa completo para quem deseja dominar as principais linguagens e ferramentas web, construir projetos incríveis e se destacar no mercado.
O que você vai encontrar:
- Mais de 44 horas de conteúdo gravado, com aulas ministradas por Mayk Brito e Rodrigo Gonçalves.
- Certificado validado pelo mercado ao final da formação.
- Acompanhamento personalizado, com tutoria, mentorias de carreira e eventos de networking.
- Projetos profissionais para enriquecer seu portfólio e preparar você para desafios reais.
Tecnologias ensinadas:
- JavaScript, TypeScript, HTML, CSS, React.js e Node.js, com aulas práticas e exemplos do mundo real.
A Rocketseat está aqui para te impulsionar em todas as etapas da sua jornada como dev. Desde o primeiro código até a construção de projetos profissionais, nossos cursos, artigos e formações são pensados para transformar conhecimento em resultados reais.