<?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" version="2.0"><channel><title><![CDATA[Need More Coffee ☕️]]></title><description><![CDATA[Need More Coffee ☕️]]></description><link>https://needmorecoffee.hashnode.dev</link><generator>RSS for Node</generator><lastBuildDate>Sat, 12 Sep 2026 02:14:33 GMT</lastBuildDate><atom:link href="https://needmorecoffee.hashnode.dev/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[What is Depth-First Search (DFS)?]]></title><description><![CDATA[Depth-first search (DFS) is an algorithm for traversing through graph or tree data structures. You can think of it as searching through different paths in a maze to find an exit and backtracking to the previous path if the current path leads to a dea...]]></description><link>https://needmorecoffee.hashnode.dev/what-is-depth-first-search-dfs</link><guid isPermaLink="true">https://needmorecoffee.hashnode.dev/what-is-depth-first-search-dfs</guid><category><![CDATA[software development]]></category><category><![CDATA[algorithms]]></category><category><![CDATA[DFS]]></category><dc:creator><![CDATA[Kegan]]></dc:creator><pubDate>Sun, 21 Sep 2025 20:19:51 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1758484457544/3e10c2f6-d775-4a25-b4a9-51df29a880f6.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p><strong>Depth-first search (DFS)</strong> is an algorithm for traversing through graph or tree data structures. You can think of it as searching through different paths in a maze to find an exit and backtracking to the previous path if the current path leads to a dead-end. The point is to go as far down the maze as possible.</p>
<h2 id="heading-how-do-we-approach-this">How do we approach this?</h2>
<p>So, let's take a more practical look at <strong>DFS</strong> and how we approach it. We want to keep track of the nodes explored and backtrack when we hit a dead-end. Then, we want to take the next node available to us. If there aren't any more, we backtrack again until we find another one, continuing until we find our desired node or until all nodes are explored. To get a better understanding of this, lets take a look at the image below to visualize how this would work.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1758442742785/ea2b80b5-e859-42f7-9273-33aba3767be1.png" alt class="image--center mx-auto" /></p>
<p>So, as you can see, we went down 3 nodes starting from A, which is the root node, all the way to D, and we stored all explored nodes in a set. However, we still have 2 unexplored nodes in C and E, so what do we do now?</p>
<p>Well, the last explored node is D, and there doesn’t seem to be anywhere to go from there, so this is where we backtrack to the previous node, which is B. From B, we can see that there is an unexplored node in E.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1758442651324/5ff41906-1cbd-4c96-96a8-1a4ea5e138de.png" alt class="image--center mx-auto" /></p>
<p>Great, now that all sub-nodes from B have been explored, we only have C left. So, we backtrack from E to B to A. A's sub-nodes are B and C; we have already explored B, so now we go down to C.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1758443891215/2ede2a73-702a-48bc-b1cf-4909b88bae63.png" alt class="image--center mx-auto" /></p>
<h2 id="heading-how-do-we-implement-dfs-in-code">How do we implement DFS in code?</h2>
<p>So now that we understand the fundamental idea of Depth-first search, understand that there are 2 ways to implement this:</p>
<ul>
<li><p>Recursive DFS</p>
</li>
<li><p>Iterative DFS</p>
</li>
</ul>
<p>So both implementations have their pros and cons. Recursive DFS is easier to implement and more readable, but you can run into a problem where the algorithm makes too many recursive calls due to a very large graph, which can crash the program. This is also known as a <strong>recursion depth limit.</strong></p>
<p>Now, with Iterative DFS, you will write a bit more code, and it can become complex because you have more control. However, you don’t have the problem of hitting a <strong>recursion depth limit</strong>, which makes Iterative implementations better for larger graphs.</p>
<p>Now that we know a little bit about the different implementations of DFS, let's take a look at how we can do this using Python:</p>
<p><strong><em>Recursive DFS</em></strong></p>
<pre><code class="lang-python">tree = {
    <span class="hljs-string">'A'</span>: [<span class="hljs-string">'B'</span>, <span class="hljs-string">'C'</span>],
    <span class="hljs-string">'B'</span>: [<span class="hljs-string">'D'</span>, <span class="hljs-string">'E'</span>],
    <span class="hljs-string">'C'</span>: [<span class="hljs-string">'F'</span>, <span class="hljs-string">'G'</span>],
    <span class="hljs-string">'D'</span>: [<span class="hljs-string">'H'</span>, <span class="hljs-string">'I'</span>],
    <span class="hljs-string">'E'</span>: [<span class="hljs-string">'J'</span>, <span class="hljs-string">'K'</span>],
    <span class="hljs-string">'F'</span>: [<span class="hljs-string">'L'</span>, <span class="hljs-string">'M'</span>],
    <span class="hljs-string">'G'</span>: [<span class="hljs-string">'N'</span>, <span class="hljs-string">'O'</span>],
    <span class="hljs-string">'H'</span>: [], <span class="hljs-string">'I'</span>: [], <span class="hljs-string">'J'</span>: [], <span class="hljs-string">'K'</span>: [],
    <span class="hljs-string">'L'</span>: [], <span class="hljs-string">'M'</span>: [], <span class="hljs-string">'N'</span>: [], <span class="hljs-string">'O'</span>: []
}

<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">recursive_dfs</span>(<span class="hljs-params">tree, node, explored=None</span>):</span>
    <span class="hljs-keyword">if</span> explored <span class="hljs-keyword">is</span> <span class="hljs-literal">None</span>:
        explored = set() <span class="hljs-comment"># initialize the explored set</span>
    explored.add(node) <span class="hljs-comment"># add node to set</span>
    print(node) <span class="hljs-comment"># display the current node</span>
    <span class="hljs-keyword">for</span> n <span class="hljs-keyword">in</span> tree[node]: <span class="hljs-comment"># visit node in tree</span>
        <span class="hljs-keyword">if</span> n <span class="hljs-keyword">not</span> <span class="hljs-keyword">in</span> explored:
            recursive_dfs(tree, n, explored) <span class="hljs-comment"># recursive call </span>

recursive_dfs(tree, <span class="hljs-string">"A"</span>)
</code></pre>
<p><strong><em>Output</em></strong></p>
<pre><code class="lang-bash">A
B
D
H
I
E
J
K
C
F
L
M
G
N
O
</code></pre>
<p>So here we can see that we start at root node “A” and we go all the way down to “O”.</p>
<p><strong><em>Iterative DFS</em></strong></p>
<pre><code class="lang-python"><span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">iterative_dfs</span>(<span class="hljs-params">tree, start</span>):</span>
    explored = set() <span class="hljs-comment"># explored nodes</span>
    stack = [start]

    <span class="hljs-keyword">while</span> stack: <span class="hljs-comment"># Continue until stack is empty</span>
        node = stack.pop() <span class="hljs-comment"># Pop a node from the stack</span>
        <span class="hljs-keyword">if</span> node <span class="hljs-keyword">not</span> <span class="hljs-keyword">in</span> explored:
            explored.add(node) <span class="hljs-comment"># add node to set</span>
            print(node) <span class="hljs-comment"># display current node </span>
            stack.extend(reversed(tree[node])) <span class="hljs-comment"># Add sub nodes to stack (reversed() reverses the list)</span>

iterative_dfs(tree, <span class="hljs-string">"A"</span>)
</code></pre>
<p>So you can see the difference in both implementations. In Iterative DFS, we use a stack to keep track of nodes and sub-nodes we need to explore, and when you run both these versions, the same result is returned.</p>
<p>So hopefully you now understand the concept of Depth-first search and how to implement it, there are other aspects of DFS you should understand like the time complexity and some other trade-offs as well, but I just wanted to give you a quick and simple example of what DFS is and how to implement it, I will paste links to other resources that I think will help understand a little bit more.</p>
<h2 id="heading-other-resources">Other resources</h2>
<ul>
<li><p><a target="_blank" href="https://www.datacamp.com/tutorial/big-o-notation-time-complexity">Big O Notation &amp; Time Complexity</a></p>
</li>
<li><p><a target="_blank" href="https://leetcode.com/problem-list/depth-first-search/">Depth-first search leetcode</a></p>
</li>
</ul>
<h2 id="heading-lets-connect">Lets connect</h2>
<ul>
<li><p><a target="_blank" href="https://substack.com/@kegandev">Follow me on Substack</a></p>
</li>
<li><p><a target="_blank" href="https://x.com/KeganDev">Follow me on Twitter/X</a></p>
</li>
</ul>
]]></content:encoded></item></channel></rss>