{"id":710,"date":"2023-09-19T17:10:30","date_gmt":"2023-09-19T17:10:30","guid":{"rendered":"https:\/\/baldsolutions.com\/?p=710"},"modified":"2023-10-07T15:07:22","modified_gmt":"2023-10-07T15:07:22","slug":"tree-traversal-use-cases-featuring-haskell","status":"publish","type":"post","link":"https:\/\/baldsolutions.com\/index.php\/2023\/09\/19\/tree-traversal-use-cases-featuring-haskell\/","title":{"rendered":"Tree traversal use cases (featuring Haskell)"},"content":{"rendered":"\n<p><\/p>\n\n\n\n<h1 class=\"wp-block-heading\">Introduction<\/h1>\n\n\n\n<p>Tree structure is extremely popular in the computer science.  From time to time trees need to be traversed (i.e. visiting all the nodes) and there are three popular algorithms to do that:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>pre-order,<\/li>\n\n\n\n<li>in-order,<\/li>\n\n\n\n<li>post-order.<\/li>\n<\/ul>\n\n\n\n<p>Each of them has its own use case and in this post I give a practical example of one use case for each algorithm. This time I implemented the solution in Haskell (first time here, hope not the last).  My motivation for this topic is pretty straightforward &#8211; I believe it is much easier to remember and understand an algorithm if you know at least one usage of it. Without further ado, let&#8217;s go!<\/p>\n\n\n\n<p>Note: I do not explain Haskell syntax nor internals in this post. However, you can check the code in my repo if you want to run locally or just look at it.<\/p>\n\n\n\n<h1 class=\"wp-block-heading\">Pre-order<\/h1>\n\n\n\n<p>One of the use cases for the pre-order traversal algorithm is tree cloning.  Let&#8217;s consider <br>a tree that we want to clone:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"381\" height=\"295\" src=\"https:\/\/baldsolutions.com\/wp-content\/uploads\/2023\/09\/image.png\" alt=\"\" class=\"wp-image-714\" srcset=\"https:\/\/baldsolutions.com\/wp-content\/uploads\/2023\/09\/image.png 381w, https:\/\/baldsolutions.com\/wp-content\/uploads\/2023\/09\/image-300x232.png 300w\" sizes=\"auto, (max-width: 381px) 100vw, 381px\" \/><\/figure>\n\n\n\n<p>We can implement a tree cloning function using the following pseudocode:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>1  Node Clone(Node existingNode){\n2   if(existingNode == null){\n3      return null;\n4   }\n5\n6   newNode = new Node();\n7   newNode.Value = existingNode.Value;\n8   newNode.Left = Clone(existingNode.Left)\n9   newNode.Right = Clone(existingNode.Right)\n10\n11  return newNode;\n12 }<\/code><\/pre>\n\n\n\n<p>As you can see the cloning process clone the tree in a pre-order fashion:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Process a node &#8211; create a clone of the node with the proper value (line 6-7),<\/li>\n\n\n\n<li>Go left &#8211; clone left subtree (line 8),<\/li>\n\n\n\n<li>Go right &#8211; clone right subtree (line 9),<\/li>\n\n\n\n<li>Once the function finishes it returns the root node.<\/li>\n<\/ol>\n\n\n\n<h1 class=\"wp-block-heading\">In-order<\/h1>\n\n\n\n<p>Let&#8217;s talk a bit about in-order traversal algorithm and the same tree structure as the previous one:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"381\" height=\"295\" src=\"https:\/\/baldsolutions.com\/wp-content\/uploads\/2023\/09\/image.png\" alt=\"\" class=\"wp-image-714\" srcset=\"https:\/\/baldsolutions.com\/wp-content\/uploads\/2023\/09\/image.png 381w, https:\/\/baldsolutions.com\/wp-content\/uploads\/2023\/09\/image-300x232.png 300w\" sizes=\"auto, (max-width: 381px) 100vw, 381px\" \/><\/figure>\n\n\n\n<p>If you look closer you can see that the tree has a unique feature &#8211; each and every left node has less value than the parent and each and every right node has greater value than the parent. If we have tree like this we can use the in-order traversal to get all the nodes in an ascending order -&gt; [1, 5, 6, 7, 8, 10, 11, 12, 14, 15, 20].<\/p>\n\n\n\n<h1 class=\"wp-block-heading\">Post-order<\/h1>\n\n\n\n<p>Last but not least algorithm is the post-order. This time let&#8217;s consider slightly different tree:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"380\" height=\"283\" src=\"https:\/\/baldsolutions.com\/wp-content\/uploads\/2023\/09\/image-1.png\" alt=\"\" class=\"wp-image-716\" srcset=\"https:\/\/baldsolutions.com\/wp-content\/uploads\/2023\/09\/image-1.png 380w, https:\/\/baldsolutions.com\/wp-content\/uploads\/2023\/09\/image-1-300x223.png 300w\" sizes=\"auto, (max-width: 380px) 100vw, 380px\" \/><\/figure>\n\n\n\n<p>The tree represents abstract syntax tree of a simple arithmetic expression: <br>((10 &#8211; (16 \/ 8)) + ((20 &#8211; 14) * 20)). Interestingly, we can use the post-order to traverse the tree and compute the arithmetic expression &#8211; so let&#8217;s do it!<\/p>\n\n\n\n<p>First, let&#8217;s use the post-order tree traversal and get all the nodes: <br>[10, 16, 8, \/, -, 20, 14, -, 20, *, +]. What we get here is a collection of tokens that represents <a href=\"https:\/\/en.wikipedia.org\/wiki\/Reverse_Polish_notation\" target=\"_blank\" rel=\"noopener\" title=\"\">reverse polish notation<\/a>. There are two types of tokens:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>values (e.g. 10, 16),<\/li>\n\n\n\n<li>operators (e.g. *, +).<\/li>\n<\/ul>\n\n\n\n<p>The reverse polish notation is incredibly handy when it comes to compute e.g. an arithmetic expressions without using parenthesis. The algorithm to compute result from given tokens is simple and can be implemented based on the pseudocode (we consider here only valid collection of tokens):<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>int computeFromReversePolishNotation(List&lt;Token&gt; tokens){\n   stack = new Stack&lt;int&gt;()\n\n   foreach(token in tokens){\n      if(isNumber(token)){\n          stack.push(token);\n      } else {\n          rightOperand = stack.Pop()\n          leftOperand = stack.Pop()\n          operator = getOperator(token)\n          r = compute(operator, leftOperand, rightOperand)\n          stack.Push(r)\n      }\n   }\n\n   return stack.Single()\n}\n<\/code><\/pre>\n\n\n\n<p>Illustration of the algorithm:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full is-resized\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/baldsolutions.com\/wp-content\/uploads\/2023\/09\/image-5.png\" alt=\"\" class=\"wp-image-720\" style=\"width:645px;height:242px\" width=\"645\" height=\"242\" srcset=\"https:\/\/baldsolutions.com\/wp-content\/uploads\/2023\/09\/image-5.png 694w, https:\/\/baldsolutions.com\/wp-content\/uploads\/2023\/09\/image-5-300x112.png 300w\" sizes=\"auto, (max-width: 645px) 100vw, 645px\" \/><\/figure>\n\n\n\n<p>That&#8217;s pretty neat, isn&#8217;t it?<\/p>\n\n\n\n<h1 class=\"wp-block-heading\">Summary<\/h1>\n\n\n\n<p>To sum up, in this post the three use cases of three different tree traversal algorithms are presented. Personally, I find it much easier to memorize an algorithm if I am aware of its use case. If you are interested in the implementation of the pre-order, in-order and post-order traversal algorithms in Haskell you can find the source code on my <a href=\"https:\/\/github.com\/tglowka\/baldsolutions\/tree\/master\/haskell\/tree-traversal\" target=\"_blank\" rel=\"noopener\" title=\"\">GitHub<\/a>. Moreover, there are two implementations of reverse polish notation. The former one uses simple collection-as-stack approach whereas the latter implementation is based on a stack implemented with a state monad (inspired by this <a href=\"https:\/\/www.cs.bu.edu\/fac\/snyder\/cs320\/Lectures\/Lecture12--%20State%20Monad.pdf\" target=\"_blank\" rel=\"noopener\" title=\"\">lecture<\/a>).<\/p>\n\n\n\n<p>Have a nice day, bye!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Introduction Tree structure is extremely popular in the computer science. From time to time trees need to be traversed (i.e. visiting all the nodes) and&#8230;<\/p>\n<div class=\"more-link-wrapper\"><a class=\"more-link\" href=\"https:\/\/baldsolutions.com\/index.php\/2023\/09\/19\/tree-traversal-use-cases-featuring-haskell\/\">Continue reading<span class=\"screen-reader-text\">Tree traversal use cases (featuring Haskell)<\/span><\/a><\/div>\n","protected":false},"author":3,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0,"footnotes":""},"categories":[15],"tags":[],"class_list":["post-710","post","type-post","status-publish","format-standard","hentry","category-haskell","entry"],"aioseo_notices":[],"_links":{"self":[{"href":"https:\/\/baldsolutions.com\/index.php\/wp-json\/wp\/v2\/posts\/710","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/baldsolutions.com\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/baldsolutions.com\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/baldsolutions.com\/index.php\/wp-json\/wp\/v2\/users\/3"}],"replies":[{"embeddable":true,"href":"https:\/\/baldsolutions.com\/index.php\/wp-json\/wp\/v2\/comments?post=710"}],"version-history":[{"count":21,"href":"https:\/\/baldsolutions.com\/index.php\/wp-json\/wp\/v2\/posts\/710\/revisions"}],"predecessor-version":[{"id":740,"href":"https:\/\/baldsolutions.com\/index.php\/wp-json\/wp\/v2\/posts\/710\/revisions\/740"}],"wp:attachment":[{"href":"https:\/\/baldsolutions.com\/index.php\/wp-json\/wp\/v2\/media?parent=710"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/baldsolutions.com\/index.php\/wp-json\/wp\/v2\/categories?post=710"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/baldsolutions.com\/index.php\/wp-json\/wp\/v2\/tags?post=710"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}