<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/"
    xmlns:atom="http://www.w3.org/2005/Atom" xmlns:media="http://search.yahoo.com/mrss/" version="2.0">
    <channel>
        
        <title>
            <![CDATA[ Brainon Queiroz - freeCodeCamp.org ]]>
        </title>
        <description>
            <![CDATA[ Aprenda a codificar - de graça. Tutoriais de programação em Python, JavaScript, Linux e muito mais. ]]>
        </description>
        <link>https://www.freecodecamp.org/portuguese/news/</link>
        <image>
            <url>https://cdn.freecodecamp.org/universal/favicons/favicon.png</url>
            <title>
                <![CDATA[ Brainon Queiroz - freeCodeCamp.org ]]>
            </title>
            <link>https://www.freecodecamp.org/portuguese/news/</link>
        </image>
        <generator>Eleventy</generator>
        <lastBuildDate>Tue, 26 May 2026 16:03:27 +0000</lastBuildDate>
        <atom:link href="https://www.freecodecamp.org/portuguese/news/author/brainon/rss.xml" rel="self" type="application/rss+xml" />
        <ttl>60</ttl>
        
            <item>
                <title>
                    <![CDATA[ Como a recursão funciona — explicado com fluxogramas e vídeo ]]>
                </title>
                <description>
                    <![CDATA[ (A ilustração da capa – bem como tudo neste artigo – é de Aditya Barghava) > "Para entender recursão, você primeiro precisa entender recursão." A recursão, ou recursividade, pode ser um assunto difícil de entender — especialmente para novos programadores. Em sua forma mais simples, uma função recursiva é uma ]]>
                </description>
                <link>https://www.freecodecamp.org/portuguese/news/como-a-recursao-funciona-explicado-com-fluxogramas-e-video/</link>
                <guid isPermaLink="false">653de7bb41517403e4ea4f6a</guid>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Brainon Queiroz ]]>
                </dc:creator>
                <pubDate>Tue, 16 Apr 2024 02:05:00 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/portuguese/news/content/images/2024/04/1_FVSUmSQEEsagXaKa_ajtvA.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p data-test-label="translation-intro">
        <strong>Artigo original:</strong> <a href="https://www.freecodecamp.org/news/how-recursion-works-explained-with-flowcharts-and-a-video-de61f40cb7f9/" target="_blank" rel="noopener noreferrer" data-test-label="original-article-link">https://www.freecodecamp.org/news/how-recursion-works-explained-with-flowcharts-and-a-video-de61f40cb7f9/</a>
      </p><p><em>(A ilustração da capa – bem como tudo neste artigo – é de Aditya Barghava)</em></p><blockquote>"Para entender recursão, você primeiro precisa entender recursão."</blockquote><p>A recursão, ou recursividade, pode ser um assunto difícil de entender — especialmente para novos programadores. Em sua forma mais simples, uma função recursiva é uma função que invoca a si mesma. Deixe eu tentar explicar com um exemplo.</p><p>Imagine que você vai abrir a porta do seu quarto e encontra a porta trancada. Seu filho de três anos aparece e revela que ele trancou a porta e escondeu a chave em uma caixa ("Bem a cara dele", você pensa). Você está atrasado para o trabalho e precisa urgentemente entrar no quarto para pegar sua camisa.</p><p>Você abre a caixa apenas para encontrar... mais caixas! Caixas dentro de caixas. Você não sabe qual delas contêm a chave! Você precisa daquela camisa então decide pensar em um bom algoritmo para resolver este dilema.</p><p>Existem duas maneiras principais de se criar um algoritmo para este problema: iterativa e recursiva. Aqui estão ambas as maneiras explicadas com um fluxograma:</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2024/04/1_QrQ5uFKIhK3jQSFYeRBIRg.png" class="kg-image" alt="1_QrQ5uFKIhK3jQSFYeRBIRg" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2024/04/1_QrQ5uFKIhK3jQSFYeRBIRg.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/2024/04/1_QrQ5uFKIhK3jQSFYeRBIRg.png 800w" sizes="(min-width: 720px) 720px" width="800" height="492" loading="lazy"></figure><p>Qual delas parece mais fácil?</p><p>A primeira maneira utiliza um laço <em>while</em>. Enquanto a pilha não estiver vazia, pegue uma caixa e verifique-a. Aqui está um pseudocódigo inspirado em Javascript que mostra o que está acontecendo (pseudocódigo é escrito como se fosse código, mas se assemelha a língua humana).</p><pre><code class="language-javascript">function procura_chave(caixa_principal) {
    let pilha = caixa_principal.fazer_pilha_para_procurar();
    while (pilha nao vazia) {
        caixa = pilha.pegar_caixa();
        for (item in caixa) {
            if (item.eh_uma_caixa()) {
                pilha.append(item)
            } else if (item.eh_uma_chave()) {
                console.log("achei a chave!")
            }
        }
    }}</code></pre><p>A segunda maneira utiliza a recursão. Lembre-se, recursão é quando uma função que invoca a si própria. Aqui está a segunda maneira em pseudocódigo.</p><pre><code class="language-javascript">function procura_chave(caixa) {
  for (item in caixa) {
    if (item.eh_uma_caixa()) {
      procura_chave(item);
    } else if (item.eh_uma_chave()) {
      console.log("achei a chave!")
    } 
  }
}</code></pre><p>Ambas as abordagens resultam na mesma coisa. O principal propósito de se utilizar recursão é que, depois que você entende o conceito, o código fica mais legível. Não existe nenhum benefício de desempenho ao se usar recursão. A solução iterativa, às vezes, pode ser até mais rápida, mas a simplicidade da recursão é preferida.</p><p>Além disso, como muitos algoritmos famosos utilizam recursão, é importante entender como funciona. Se recursão ainda não soa simples para você, não se preocupe: darei mais alguns exemplos.</p><h3 id="caso-base-e-caso-recursivo"><strong>Caso base e caso recursivo</strong></h3><p>Uma coisa que você deve tomar muito cuidado ao escrever uma função recursiva é com um laço infinito. Isso ocorre quando a função continua se invocando... e nunca para!</p><p>Por exemplo, se você quiser escrever uma função de contagem regressiva. Você poderia escrevê-la recursivamente em Javascript desse jeito:</p><pre><code class="language-javascript">// CUIDADO: esta função contém um laço infinito!
function contagemRegressiva(i) {
    console.log(i)
    contagemRegressiva(i - 1)
}

contagemRegressiva(5); // Essa é a chamada inicial da função.</code></pre><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2024/04/1_LGjfggsIiQHbfJothG1hYw.png" class="kg-image" alt="1_LGjfggsIiQHbfJothG1hYw" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2024/04/1_LGjfggsIiQHbfJothG1hYw.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/2024/04/1_LGjfggsIiQHbfJothG1hYw.png 800w" sizes="(min-width: 720px) 720px" width="800" height="321" loading="lazy"></figure><p>Essa função continuará se invocando pra sempre. Se você acidentalmente criou um código com um laço infinito, &nbsp;pode apertar "Ctrl+C" para encerrar seu script (ou, se estiver no CodePen, precisará adicionar "?turn_off_js=true" no fim da URL.)</p><p>Uma função recursiva sempre precisará de uma condição para dizer quando ela precisa parar de se invocar. Sempre existirão duas partes de uma função recursiva: O caso recursivo e o caso base. O caso recursivo é quando a função invoca a si mesma. O caso base é quando a função deverá parar de se invocar. Isso evitará os laços infinitos.</p><p>Aqui está a contagem regressiva novamente, desta vez com um caso base:</p><pre><code class="language-javascript">function contagemRegressiva(i) {
    console.log(i)  
    if (i &lt;= 1) {  // caso base
        return;
    } else {     // caso recursivo
        contagemRegressiva(i - 1);
    }
}

contagemRegressiva(5); // Essa é a chamada inicial da função.</code></pre><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2024/04/1_rQ9Z3DmtGk1Bb6_Mx5W6rQ.png" class="kg-image" alt="1_rQ9Z3DmtGk1Bb6_Mx5W6rQ" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2024/04/1_rQ9Z3DmtGk1Bb6_Mx5W6rQ.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/2024/04/1_rQ9Z3DmtGk1Bb6_Mx5W6rQ.png 800w" sizes="(min-width: 720px) 720px" width="800" height="463" loading="lazy"></figure><p>Pode não ser óbvio o que está acontecendo nessa função. Vou explicar o que acontece quando se executa a função <code>contagemRegressiva</code> passando "5" como argumento.</p><p>Começamos imprimindo o número 5 no console utilizando <code>console.log</code>. Como cinco não é menor ou igual a um, vamos para o bloco else. Lá, invocamos novamente a função <code>contagemRegressiva</code> com o número quatro (5-1=4).</p><p>Imprimimos o número 4. Novamente, <code>i</code> não é menor ou igual a um, então vamos para o bloco else e invocamos a função <code>contagemRegressiva</code> novamente com o argumento 3. Esse processo continua até <code>i</code><em><em> </em>ser igual a um</em>. Quando isso acontecer, imprimimos o número um &nbsp;e então <code>i</code><em><em> </em>será menor ou igual a um</em>. Finalmente chegamos à declaração de retorno, então encerramos o laço e saímos da função.</p><h3 id="call-stack">Call stack</h3><p>Funções recursivas utilizam algo chamado "<em>call stack</em>" (ou "pilha de chamadas", em português). Quando um programa invoca uma função, essa função vai para o topo dessa pilha. Essa estrutura é similar à uma pilha de livros. Você adiciona livros na pilha um de cada vez. Então quando você quer retirar um livro da pilha, você sempre tira primeiro o livro do topo.</p><p>Vou mostrar a pilha de chamadas em ação com a função <code>fatorial</code>. A expressão <code>fatorial(5)</code> é escrita como 5! e é definida assim: 5! = 5 * 4 * 3 * 2 * 1. Aqui está uma função recursiva para calcular o fatorial de um número.</p><pre><code class="language-javascript">function fatorial(x) {
    if (x == 1) {
        return 1;
    } else {
        return x * fatorial(x-1);
    }
}</code></pre><p>Agora, vamos ver o que acontece se você chamar <code>fatorial(3)</code>. A ilustração abaixo mostra como a pilha de chamada (<em>call stack</em>) funciona, linha por linha. A chamada mais ao topo da pilha mostra qual chamada de <code>fatorial</code> (no exemplo em inglês, <code>fact</code>) está sendo executada no momento.</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2024/04/1_YRkMsMPRFAt8Y9BiC0QVDg.png" class="kg-image" alt="1_YRkMsMPRFAt8Y9BiC0QVDg" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2024/04/1_YRkMsMPRFAt8Y9BiC0QVDg.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/2024/04/1_YRkMsMPRFAt8Y9BiC0QVDg.png 800w" sizes="(min-width: 720px) 720px" width="800" height="1065" loading="lazy"></figure><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2024/04/1_AWu17xnQ-lxVwpgVhEo_lA.png" class="kg-image" alt="1_AWu17xnQ-lxVwpgVhEo_lA" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2024/04/1_AWu17xnQ-lxVwpgVhEo_lA.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/2024/04/1_AWu17xnQ-lxVwpgVhEo_lA.png 800w" sizes="(min-width: 720px) 720px" width="800" height="342" loading="lazy"><figcaption>Crédito da imagem: Aditya Bhargava</figcaption></figure><p>Note como cada chamada de <code>fatorial</code> tem sua própria cópia de <code>x</code>. Isso é muito importante para fazer com que a recursão funcione. Você não pode acessar a cópia de <code>x</code> de uma função diferente.</p><h3 id="j-encontrou-a-chave"><em><strong>Já encontrou a chave</strong><em><strong>?</strong></em></em></h3><p>Vamos voltar brevemente ao exemplo original sobre procurar a chave nas caixas aninhadas. Lembre-se, o primeiro método foi iterativo utilizando um laço <em>while</em>. Com aquele método, você primeiro alinha as caixas e depois procura em cada uma delas, assim você sempre sabe em quais caixas você ainda precisa procurar.</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2024/04/1_qFezr1s9YpK6-GsMJqwhOA.png" class="kg-image" alt="1_qFezr1s9YpK6-GsMJqwhOA" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2024/04/1_qFezr1s9YpK6-GsMJqwhOA.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/2024/04/1_qFezr1s9YpK6-GsMJqwhOA.png 800w" sizes="(min-width: 720px) 720px" width="800" height="602" loading="lazy"></figure><p>Essa abordagem, porém, não existe no método recursivo. Como seu algoritmo sabe em quais caixas você ainda precisa procurar? A "pilha de caixas" é salva na <em>stack</em>. Essa <em>stack </em>consiste em chamadas de funções "meio completas", cada uma com suas listas "meio completas" para serem verificadas. A <em>stack </em>gerencia toda essa pilha para você!</p><p>Graças à recursão, você pode finalmente encontrar a chave e pegar sua camisa!</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2024/04/1_8Y0_goJ5oKvt1tzSX4d8Tw.png" class="kg-image" alt="1_8Y0_goJ5oKvt1tzSX4d8Tw" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2024/04/1_8Y0_goJ5oKvt1tzSX4d8Tw.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/2024/04/1_8Y0_goJ5oKvt1tzSX4d8Tw.png 800w" sizes="(min-width: 720px) 720px" width="800" height="948" loading="lazy"></figure><p>Você também pode assistir esse vídeo (em inglês) de 5 minutos sobre recursão. Isso vai ajudar a reforçar esses conceitos de recursão.</p><figure class="kg-card kg-embed-card" data-test-label="fitted">
        <div class="fluid-width-video-container">
          <div style="padding-top: 56.49999999999999%;" class="fluid-width-video-wrapper">
            <iframe width="200" height="113" src="https://www.youtube.com/embed/vPEJSJMg4jY?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen="" title="Recursion in software development" name="fitvid0"></iframe>
          </div>
        </div>
      </figure><h3 id="conclus-o">Conclusão</h3><p>Espero que este artigo tenha trazido mais clareza sobre recursão na programação. Este artigo é baseado em meu novo curso na Manning Publications chamado <a href="https://www.manning.com/livevideo/algorithms-in-motion?a_aid=algmotion&amp;a_bid=9022d293" rel="noopener">Algorithms in Motion</a> (Algoritmos em movimento). O curso (bem como este artigo) é baseado no incrível livro <a href="https://www.amazon.com.br/Entendendo-Algoritmos-ilustrado-programadores-curiosos-ebook/dp/B07B61HC3L/ref=sr_1_2?__mk_pt_BR=%C3%85M%C3%85%C5%BD%C3%95%C3%91&amp;crid=133K2BLHICWLZ&amp;dib=eyJ2IjoiMSJ9.Wv6UVv25BsUBwcrCqITDs-m0BkMNBl-LKfHg-sIuts4c49DpYxB0_DuUQQGQb3x0xf0NRhDsI9S2gZhX08_fVEf0SxSgh0k9HYYT0QzZIVtyuKYRJB8NziEokgXfelyPsx1u6WfPdPDvKbvd2sVB_NqbvQmdVmrmHXh0mSXkbwGsdyFmoWc3KNdOYlX6eNBqOWVORV8zAtQefhgB-f1c9RxUpYmtyGWCGdeDOxAiNIe3jzfl9KuxE8I8YupBE_odaOrTkq45LvUfNmNumUGs1naqBkGdrrccRcaax1eQMz0.ilAagk3S36f7vXESs77PBU3EE_3NwCIuhcAZoHbVjl8&amp;dib_tag=se&amp;keywords=algoritmos+de+grokking&amp;qid=1713165925&amp;sprefix=algoritmos+de+grokking%2Caps%2C246&amp;sr=8-2">Entendendo algoritmos</a>, de Aditya Bhargava. Foi ele quem desenhou todas as ilustrações deste artigo.</p><p>Se você aprende melhor lendo livros, <a href="https://www.amazon.com.br/Entendendo-Algoritmos-ilustrado-programadores-curiosos-ebook/dp/B07B61HC3L/ref=sr_1_2?__mk_pt_BR=%C3%85M%C3%85%C5%BD%C3%95%C3%91&amp;crid=133K2BLHICWLZ&amp;dib=eyJ2IjoiMSJ9.Wv6UVv25BsUBwcrCqITDs-m0BkMNBl-LKfHg-sIuts4c49DpYxB0_DuUQQGQb3x0xf0NRhDsI9S2gZhX08_fVEf0SxSgh0k9HYYT0QzZIVtyuKYRJB8NziEokgXfelyPsx1u6WfPdPDvKbvd2sVB_NqbvQmdVmrmHXh0mSXkbwGsdyFmoWc3KNdOYlX6eNBqOWVORV8zAtQefhgB-f1c9RxUpYmtyGWCGdeDOxAiNIe3jzfl9KuxE8I8YupBE_odaOrTkq45LvUfNmNumUGs1naqBkGdrrccRcaax1eQMz0.ilAagk3S36f7vXESs77PBU3EE_3NwCIuhcAZoHbVjl8&amp;dib_tag=se&amp;keywords=algoritmos+de+grokking&amp;qid=1713165925&amp;sprefix=algoritmos+de+grokking%2Caps%2C246&amp;sr=8-2">adquira o livro</a>! Se você aprende melhor assistindo vídeos, considere <a href="https://www.manning.com/livevideo/algorithms-in-motion?a_aid=algmotion&amp;a_bid=9022d293">adquirir meu curso</a> (em inglês).</p><blockquote>Tenha 39% de desconto no meu curso usando o código '<strong><strong>39carnes</strong></strong>'!</blockquote><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2024/04/1_a5UFtQIHwXy7SCQpI9GdVQ.png" class="kg-image" alt="1_a5UFtQIHwXy7SCQpI9GdVQ" width="260" height="326" loading="lazy"></figure><p>Por fim, para realmente entender recursão, leia este artigo de novo!</p> ]]>
                </content:encoded>
            </item>
        
    </channel>
</rss>
