<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/">
    <channel>
        <title>Deor</title>
        <link>https://paragraph.com/@deor</link>
        <description>fullstack + solidity engineer</description>
        <lastBuildDate>Sat, 04 Jul 2026 12:16:32 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <language>en</language>
        <image>
            <title>Deor</title>
            <url>https://storage.googleapis.com/papyrus_images/34d53fa6ee6b9679a34d45e9cdd71b2be7ee5cb483c12422e508d3bce2d6ba02.jpg</url>
            <link>https://paragraph.com/@deor</link>
        </image>
        <copyright>All rights reserved</copyright>
        <item>
            <title><![CDATA[Solidity Trees: Binary Search Trees (Part 1)]]></title>
            <link>https://paragraph.com/@deor/solidity-trees-binary-search-trees-part-1</link>
            <guid>lvBxfXDNuzv9SwD2lDYZ</guid>
            <pubDate>Tue, 15 Mar 2022 00:14:25 GMT</pubDate>
            <description><![CDATA[This is the first part in a two part series about tree implementations in solidity. In this first part, we will be going over the basics of trees and implementing one of the most basic of trees, the binary search tree. We will first talk about what trees are and why we use them, some basic overview on time complexity, and then we will go analyze an implementation in solidity.What are trees?A tree is an abstract data structure where data is stored in a hierarchical tree structure in the form o...]]></description>
            <content:encoded><![CDATA[<p>This is the first part in a two part series about tree implementations in solidity. In this first part, we will be going over the basics of trees and implementing one of the most basic of trees, the binary search tree.</p><p>We will first talk about what trees are and why we use them, some basic overview on time complexity, and then we will go analyze an implementation in solidity.</p><h2 id="h-what-are-trees" class="text-3xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0">What are trees?</h2><p>A tree is an abstract data structure where data is stored in a hierarchical tree structure in the form of nodes that are linked to other subtrees. A tree has a root node, and nodes that are linked to it are called children nodes. Let us look at an example:</p><figure float="none" data-type="figure" class="img-center" style="max-width: null;"><img src="https://storage.googleapis.com/papyrus_images/856a655bce7e740bd05dd124f2813eb4a5406092382cb3e5d18d8d2255de0779.png" alt="" blurdataurl="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACwAAAAAAQABAAACAkQBADs=" nextheight="600" nextwidth="800" class="image-node embed"><figcaption HTMLAttributes="[object Object]" class="hide-figcaption"></figcaption></figure><p>In this tree, the Student node is the root of the tree. It’s children are Name, Address, ID, and Course, this group of nodes are also called siblings because they share the same parent.</p><p>Some trees have special properties that make them useful. The binary search tree is the most common example. It has several rules on how it works:</p><ul><li><p>Each node can have a maximum of two children nodes connected to it</p></li><li><p>Nodes being inserted must be comparable in some way, for example, 1 &lt; 2</p></li><li><p>When inserting a number, all the numbers to the left of it must be smaller, and all of the numbers to the right of it must be bigger</p></li></ul><p>The last rule is the most important. Here is an example a binary search tree:</p><figure float="none" data-type="figure" class="img-center" style="max-width: null;"><img src="https://storage.googleapis.com/papyrus_images/2ef18ae2f2f36f9647e3e74a1e2e029f1e860a9b538e5a1cd95bd7739afbb935.png" alt="" blurdataurl="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACwAAAAAAQABAAACAkQBADs=" nextheight="600" nextwidth="800" class="image-node embed"><figcaption HTMLAttributes="[object Object]" class="hide-figcaption"></figcaption></figure><p>Start at the root of the tree, and look at the left and right sub tree. The left node is 8, which is smaller than 10, and the right node is 12, which is bigger then 10. You might be able to see where we are going with this.</p><h2 id="h-why-do-we-use-trees" class="text-3xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0">Why do we use trees?</h2><p>To understand why we use trees, it is good to have a basic overview of time complexity in computer algorithms.</p><p>Let us say that we want to iterate over an array once, printing each value while we are doing it. That would look something like this (pseudo code):</p><pre data-type="codeBlock" text="Array a;
n = a.length; 
for (i=0; i&lt;n; i++)
  print(a[i]);
"><code>Array a<span class="hljs-comment">;</span>
<span class="hljs-attr">n</span> = a.length<span class="hljs-comment">; </span>
for (<span class="hljs-attr">i</span>=<span class="hljs-number">0</span><span class="hljs-comment">; i&#x3C;n; i++)</span>
  print(a<span class="hljs-section">[i]</span>)<span class="hljs-comment">;</span>
</code></pre><p>Lets declare some things:</p><ul><li><p>The array has length of 100</p></li><li><p>It takes 1 unit for each iteration, lets say this unit is in seconds.</p></li></ul><p>Overall, we are iterating over this array N times, which is commonly declared with the notation O(n).</p><blockquote><p>We wont go over the background of the notation in this article. Just imagine if N is 100 it will take O(100) units for the algorithm to execute, which is 100 seconds in this case.</p></blockquote><p>Now, let us look at another example like the one above, but instead with a nested for-loop:</p><pre data-type="codeBlock" text="Array a;
n = a.length; 
for (i=0; i&lt;n; i++)
   for (x=0; x&lt;n; x++)
      print(a[x]);
"><code>Array a<span class="hljs-comment">;</span>
<span class="hljs-attr">n</span> = a.length<span class="hljs-comment">; </span>
for (<span class="hljs-attr">i</span>=<span class="hljs-number">0</span><span class="hljs-comment">; i&#x3C;n; i++)</span>
   for (<span class="hljs-attr">x</span>=<span class="hljs-number">0</span><span class="hljs-comment">; x&#x3C;n; x++)</span>
      print(a<span class="hljs-section">[x]</span>)<span class="hljs-comment">;</span>
</code></pre><p>Here, our top for-loop will iterate N times, and our bottom for-loop will iterate N times. Combining them, we get N*N, or N^2 times. This time complexity is denoted as O(N^2), which means this algorithm will take 10,000 units to come to completion.</p><p>What does this have to do with trees?</p><p>The problem of time complexity originated with a simple idea: lets say we have an array of 1000 items, and want to sort it. There is a simple way to do this, bubble sort:</p><pre data-type="codeBlock" text="for (int max = elements.length - 1; max &gt; 0; max--) {
    boolean swapped = false;
    for (int i = 0; i &lt; max; i++) {
        int left = elements[i];
        int right = elements[i + 1];
        if (left &gt; right) {
            elements[i + 1] = left;
            elements[i] = right;
            swapped = true;
        }
    }
    if (!swapped) break;
}
"><code><span class="hljs-keyword">for</span> (<span class="hljs-keyword">int</span> max <span class="hljs-operator">=</span> elements.<span class="hljs-built_in">length</span> <span class="hljs-operator">-</span> <span class="hljs-number">1</span>; max <span class="hljs-operator">></span> <span class="hljs-number">0</span>; max<span class="hljs-operator">-</span><span class="hljs-operator">-</span>) {
    boolean swapped <span class="hljs-operator">=</span> <span class="hljs-literal">false</span>;
    <span class="hljs-keyword">for</span> (<span class="hljs-keyword">int</span> i <span class="hljs-operator">=</span> <span class="hljs-number">0</span>; i <span class="hljs-operator">&#x3C;</span> max; i<span class="hljs-operator">+</span><span class="hljs-operator">+</span>) {
        <span class="hljs-keyword">int</span> left <span class="hljs-operator">=</span> elements[i];
        <span class="hljs-keyword">int</span> right <span class="hljs-operator">=</span> elements[i <span class="hljs-operator">+</span> <span class="hljs-number">1</span>];
        <span class="hljs-keyword">if</span> (left <span class="hljs-operator">></span> right) {
            elements[i <span class="hljs-operator">+</span> <span class="hljs-number">1</span>] <span class="hljs-operator">=</span> left;
            elements[i] <span class="hljs-operator">=</span> right;
            swapped <span class="hljs-operator">=</span> <span class="hljs-literal">true</span>;
        }
    }
    <span class="hljs-keyword">if</span> (<span class="hljs-operator">!</span>swapped) <span class="hljs-keyword">break</span>;
}
</code></pre><p>Bubble sort has a <strong>worst case</strong> time complexity of O(N^2). That means if we want to sort 10000 items, it will take 10000^2 units to sort it. With computers, this can be done almost instantly. However, the issue arises when we are sorting arrays with large N’s. For example, in C++, sorting an array of 1 million integers can take up to an hour.</p><blockquote><p>Commonly when talking about time complexity, we are attempting to describe the worst possible time for an algorithm to take. There is a chance that the majority of an array is sorted already, but we care more about the worst case than the best case.</p></blockquote><p>There are much better ways to sort an array, including other algorithms, and also other data structures. This is where the binary search tress come in.</p><h2 id="h-binary-search-tree-time-complexity" class="text-3xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0">Binary Search Tree Time Complexity</h2><p>When inserting a number into a BST (Binary search tree), the number gets sorted into the tree. This allows operations on the BST to be efficient, and sorting itself to be more efficent.</p><figure float="none" data-type="figure" class="img-center" style="max-width: null;"><img src="https://storage.googleapis.com/papyrus_images/1224e471d73cf6fdcd8361d297e4ce7d6c45a4d061f6d8e1b62b8b8ce3e44fa7.png" alt="" blurdataurl="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACwAAAAAAQABAAACAkQBADs=" nextheight="600" nextwidth="800" class="image-node embed"><figcaption HTMLAttributes="[object Object]" class="hide-figcaption"></figcaption></figure><p>Take a look at the average case of Insert and Search, versus the worst case. The reason for the differences is because of an occurrence where numbers can be inserted in sorted order, for example:</p><figure float="none" data-type="figure" class="img-center" style="max-width: null;"><img src="https://storage.googleapis.com/papyrus_images/f496134ffe93f4675a7e7a9fd738ff4ff37081b28ccd99b998594de78922be0d.png" alt="" blurdataurl="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACwAAAAAAQABAAACAkQBADs=" nextheight="600" nextwidth="800" class="image-node embed"><figcaption HTMLAttributes="[object Object]" class="hide-figcaption"></figcaption></figure><p>This means that to access the 7 node, it will take O(n) time as you will have to go over all the nodes in the tree first.</p><p>A subset of the binary search tree exists that solves this issue, and achieves O(log n) worst case time complexity for insert and search. We will explore these and their implementation in solidity in part two of this series.</p><h2 id="h-binary-search-tree-in-solidity" class="text-3xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0">Binary Search Tree in Solidity</h2><p>Why would we write a binary search tree in solidity? Having an efficient way to sort data in a programming language where efficiency directly saves you money (gas) is definitely something that is crucial.</p><p>Every iteration over an array costs gas, and for large array’s it is possible for you to run out of gas while sorting it. We move this gas from the sort operation to the insert operation.</p><blockquote><p>The full code for this is on GitHub here:</p><p><a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://github.com/d3or/sol-trees">https://github.com/d3or/sol-trees</a></p></blockquote><p>The way nodes are stored is similar to how we did it with our stack implementation via linked lists, where we store our actual nodes in a mapping, with each node having its own unique id that other nodes can point to it via.</p><pre data-type="codeBlock" text="   struct Node {
        uint256 value;
        bytes32 left;
        bytes32 right;
    }   
"><code>   <span class="hljs-keyword">struct</span> <span class="hljs-title">Node</span> {
        <span class="hljs-keyword">uint256</span> value;
        <span class="hljs-keyword">bytes32</span> left;
        <span class="hljs-keyword">bytes32</span> right;
    }   
</code></pre><p>Here is our node struct, and it is rather simple. It stores a <code>uint256</code> value, and two <code>bytes32</code> values, left and right. These are used to indicate the two children of the node, and are set to the address ID of those nodes.</p><p>Next we have the address of our root as a state variable, and our mapping to store our nods:</p><pre data-type="codeBlock" text="    mapping (bytes32 =&gt; Node) private tree;
   
    bytes32 private rootAddress;
"><code>    <span class="hljs-keyword">mapping</span> (<span class="hljs-keyword">bytes32</span> <span class="hljs-operator">=</span><span class="hljs-operator">></span> Node) <span class="hljs-keyword">private</span> tree;
   
    <span class="hljs-keyword">bytes32</span> <span class="hljs-keyword">private</span> rootAddress;
</code></pre><p>Now, we have our state variables set up. Next, we look at insertion. Hang tight, this might look complicated but it is actually relatively simple!</p><pre data-type="codeBlock" text="    function insert(uint256 value) public {
        Node memory root = tree[rootAddress];
        // if the tree is empty
        if (root.value == 0) {
            root.value = value;
            root.left = 0;
            root.right = 0;
            tree[0] = root;
            rootAddress = generateId(value, 0);
            tree[rootAddress] = root;
        } else {
            // if the tree is not empty
            // find the correct place to insert the value
            insertHelper(value, rootAddress);
        }
    }
"><code>    <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">insert</span>(<span class="hljs-params"><span class="hljs-keyword">uint256</span> value</span>) <span class="hljs-title"><span class="hljs-keyword">public</span></span> </span>{
        Node <span class="hljs-keyword">memory</span> root <span class="hljs-operator">=</span> tree[rootAddress];
        <span class="hljs-comment">// if the tree is empty</span>
        <span class="hljs-keyword">if</span> (root.<span class="hljs-built_in">value</span> <span class="hljs-operator">=</span><span class="hljs-operator">=</span> <span class="hljs-number">0</span>) {
            root.<span class="hljs-built_in">value</span> <span class="hljs-operator">=</span> value;
            root.left <span class="hljs-operator">=</span> <span class="hljs-number">0</span>;
            root.right <span class="hljs-operator">=</span> <span class="hljs-number">0</span>;
            tree[<span class="hljs-number">0</span>] <span class="hljs-operator">=</span> root;
            rootAddress <span class="hljs-operator">=</span> generateId(value, <span class="hljs-number">0</span>);
            tree[rootAddress] <span class="hljs-operator">=</span> root;
        } <span class="hljs-keyword">else</span> {
            <span class="hljs-comment">// if the tree is not empty</span>
            <span class="hljs-comment">// find the correct place to insert the value</span>
            insertHelper(value, rootAddress);
        }
    }
</code></pre><p>First, we attain the root of the tree by using the state-variable root address to access the root node stored inside our mapping.</p><p>Next, we check if the tree is empty. If it is empty, we create the root node, generate its unique id, and put it into the mapping.</p><blockquote><p>In this example, the root node should not have a value less than 0. We are using <strong>unsigned</strong> 256 bit integers. Thus, a node can not have the value of 0.</p></blockquote><p>If the tree is not empty, we use the function <code>insertHelper</code>, and pass the value and the root address where it recursively finds the right place to insert the node into the tree.</p><pre data-type="codeBlock" text="    // helper function for insert
    function insertHelper(uint256 value, bytes32 nodeAddress) internal {
        Node memory node = tree[nodeAddress];
        if (value &lt; node.value) {
            if (node.left == 0) {
                insertNode(value, nodeAddress, 0);
            } else {
                insertHelper(value, node.left);
            }
        } else {
            if (node.right == 0) {
                insertNode(value, nodeAddress, 1);
            } else {
                insertHelper(value, node.right);
            }
        }
    }
"><code>    <span class="hljs-comment">// helper function for insert</span>
    <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">insertHelper</span>(<span class="hljs-params"><span class="hljs-keyword">uint256</span> value, <span class="hljs-keyword">bytes32</span> nodeAddress</span>) <span class="hljs-title"><span class="hljs-keyword">internal</span></span> </span>{
        Node <span class="hljs-keyword">memory</span> node <span class="hljs-operator">=</span> tree[nodeAddress];
        <span class="hljs-keyword">if</span> (value <span class="hljs-operator">&#x3C;</span> node.<span class="hljs-built_in">value</span>) {
            <span class="hljs-keyword">if</span> (node.left <span class="hljs-operator">=</span><span class="hljs-operator">=</span> <span class="hljs-number">0</span>) {
                insertNode(value, nodeAddress, <span class="hljs-number">0</span>);
            } <span class="hljs-keyword">else</span> {
                insertHelper(value, node.left);
            }
        } <span class="hljs-keyword">else</span> {
            <span class="hljs-keyword">if</span> (node.right <span class="hljs-operator">=</span><span class="hljs-operator">=</span> <span class="hljs-number">0</span>) {
                insertNode(value, nodeAddress, <span class="hljs-number">1</span>);
            } <span class="hljs-keyword">else</span> {
                insertHelper(value, node.right);
            }
        }
    }
</code></pre><p>This function checks if the node’s value is less than the current node, if so, if the left child is empty, it inserts the node into that position. If it is less but the node is not empty, it then calls the function again but with that new node, until it finds an empty spot. It does the same operation for if the value is bigger than the current node.</p><p>The insert node function is rather simple, it takes three parameters, the value, the address to put the node, and a <code>0</code> or <code>1</code> value to indicate where to put the node, left or right.</p><pre data-type="codeBlock" text="    function insertNode(uint256 value, bytes32 nodeAddress, uint256 location) internal {
        Node memory parentNode = tree[nodeAddress];
        bytes32 nodeId = generateId(value, nodeAddress);
        if (location == 0) {
            // if the value is less than the current node
            parentNode.left = nodeId;
        } else {
            // if the value is greater than the current node
            parentNode.right = nodeId;
        }

        // update the tree
        tree[nodeAddress] = parentNode;
        tree[nodeId] = Node(value, 0, 0);
    }
"><code>    <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">insertNode</span>(<span class="hljs-params"><span class="hljs-keyword">uint256</span> value, <span class="hljs-keyword">bytes32</span> nodeAddress, <span class="hljs-keyword">uint256</span> location</span>) <span class="hljs-title"><span class="hljs-keyword">internal</span></span> </span>{
        Node <span class="hljs-keyword">memory</span> parentNode <span class="hljs-operator">=</span> tree[nodeAddress];
        <span class="hljs-keyword">bytes32</span> nodeId <span class="hljs-operator">=</span> generateId(value, nodeAddress);
        <span class="hljs-keyword">if</span> (location <span class="hljs-operator">=</span><span class="hljs-operator">=</span> <span class="hljs-number">0</span>) {
            <span class="hljs-comment">// if the value is less than the current node</span>
            parentNode.left <span class="hljs-operator">=</span> nodeId;
        } <span class="hljs-keyword">else</span> {
            <span class="hljs-comment">// if the value is greater than the current node</span>
            parentNode.right <span class="hljs-operator">=</span> nodeId;
        }

        <span class="hljs-comment">// update the tree</span>
        tree[nodeAddress] <span class="hljs-operator">=</span> parentNode;
        tree[nodeId] <span class="hljs-operator">=</span> Node(value, <span class="hljs-number">0</span>, <span class="hljs-number">0</span>);
    }
</code></pre><p>Left = 0</p><p>Right = 1</p><p>This article is a lot longer than I was expecting, so I will skip going over how deletion works and instead go over to how to display the tree in order and how to find elements.</p><blockquote><p>You can look at the deletion function in the source code, there are detailed comments on how it works.</p></blockquote><pre data-type="codeBlock" text="    // inorder traversal
    function displayInOrder() public {
        displayInOrderHelper(rootAddress);
    }

    // recursive helper function for inorder traversal
    function displayInOrderHelper(bytes32 nodeAddress) internal     {
        Node memory node = tree[nodeAddress];
        if (node.left != 0) {
            displayInOrderHelper(node.left);
        }
        console.log(node.value);
        if (node.right != 0) {
            displayInOrderHelper(node.right);
        }
    }   
"><code>    <span class="hljs-comment">// inorder traversal</span>
    <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">displayInOrder</span>(<span class="hljs-params"></span>) <span class="hljs-title"><span class="hljs-keyword">public</span></span> </span>{
        displayInOrderHelper(rootAddress);
    }

    <span class="hljs-comment">// recursive helper function for inorder traversal</span>
    <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">displayInOrderHelper</span>(<span class="hljs-params"><span class="hljs-keyword">bytes32</span> nodeAddress</span>) <span class="hljs-title"><span class="hljs-keyword">internal</span></span>     </span>{
        Node <span class="hljs-keyword">memory</span> node <span class="hljs-operator">=</span> tree[nodeAddress];
        <span class="hljs-keyword">if</span> (node.left <span class="hljs-operator">!</span><span class="hljs-operator">=</span> <span class="hljs-number">0</span>) {
            displayInOrderHelper(node.left);
        }
        console.log(node.<span class="hljs-built_in">value</span>);
        <span class="hljs-keyword">if</span> (node.right <span class="hljs-operator">!</span><span class="hljs-operator">=</span> <span class="hljs-number">0</span>) {
            displayInOrderHelper(node.right);
        }
    }   
</code></pre><p>This is also pretty simple! It recursively goes down the tree in ascending order. The code is pretty self explanatory.</p><blockquote><p>I was using hardhat’s console.log feature when displaying the tree. This is the base algorithm for displaying a tree in order, and it can be expanded upon by making a non-recursive version via a stack, that way it will be easier to return the values.</p></blockquote><p>Finding elements also works similarly:</p><pre data-type="codeBlock" text="    // search for a value in the tree
    function findElement(uint256 value) public view returns (bool) {
        return findElementHelper(value, rootAddress);
    }

    // recursive helper function for findElement
    function findElementHelper(uint256 value, bytes32 nodeAddress) internal view returns (bool) {
        Node memory node = tree[nodeAddress];
        if (node.value == value) {
            return true;
        } else if (node.value &gt; value) {
            if (node.left == 0) {
                return false;
            } else {
                return findElementHelper(value, node.left);
            }
        } else {
            if (node.right == 0) {
                return false;
            } else {
                return findElementHelper(value, node.right);
            }
        }
    } 
"><code>    <span class="hljs-comment">// search for a value in the tree</span>
    <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">findElement</span>(<span class="hljs-params"><span class="hljs-keyword">uint256</span> value</span>) <span class="hljs-title"><span class="hljs-keyword">public</span></span> <span class="hljs-title"><span class="hljs-keyword">view</span></span> <span class="hljs-title"><span class="hljs-keyword">returns</span></span> (<span class="hljs-params"><span class="hljs-keyword">bool</span></span>) </span>{
        <span class="hljs-keyword">return</span> findElementHelper(value, rootAddress);
    }

    <span class="hljs-comment">// recursive helper function for findElement</span>
    <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">findElementHelper</span>(<span class="hljs-params"><span class="hljs-keyword">uint256</span> value, <span class="hljs-keyword">bytes32</span> nodeAddress</span>) <span class="hljs-title"><span class="hljs-keyword">internal</span></span> <span class="hljs-title"><span class="hljs-keyword">view</span></span> <span class="hljs-title"><span class="hljs-keyword">returns</span></span> (<span class="hljs-params"><span class="hljs-keyword">bool</span></span>) </span>{
        Node <span class="hljs-keyword">memory</span> node <span class="hljs-operator">=</span> tree[nodeAddress];
        <span class="hljs-keyword">if</span> (node.<span class="hljs-built_in">value</span> <span class="hljs-operator">=</span><span class="hljs-operator">=</span> value) {
            <span class="hljs-keyword">return</span> <span class="hljs-literal">true</span>;
        } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (node.<span class="hljs-built_in">value</span> <span class="hljs-operator">></span> value) {
            <span class="hljs-keyword">if</span> (node.left <span class="hljs-operator">=</span><span class="hljs-operator">=</span> <span class="hljs-number">0</span>) {
                <span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>;
            } <span class="hljs-keyword">else</span> {
                <span class="hljs-keyword">return</span> findElementHelper(value, node.left);
            }
        } <span class="hljs-keyword">else</span> {
            <span class="hljs-keyword">if</span> (node.right <span class="hljs-operator">=</span><span class="hljs-operator">=</span> <span class="hljs-number">0</span>) {
                <span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>;
            } <span class="hljs-keyword">else</span> {
                <span class="hljs-keyword">return</span> findElementHelper(value, node.right);
            }
        }
    } 
</code></pre><p>Take a look at the <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://github.com/d3or/sol-trees">repo on GitHub</a> to see the rest of the functions and ways to interact with the tree.</p><h2 id="h-conclusion" class="text-3xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0">Conclusion</h2><p>We barely scratched the surface of what is possible with trees. In the next part, we will be looking into implementing an alternative search tree that has worst-case time complexity of search of O(logn)!</p><p>I hope you were able to learn something from this article! If you have any comments or questions feel free to direct message me on twitter <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://twitter.com/Deor">@Deor</a></p><p><a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://twitter.com/Deor">https://twitter.com/Deor</a></p>]]></content:encoded>
            <author>deor@newsletter.paragraph.com (Deor)</author>
            <enclosure url="https://storage.googleapis.com/papyrus_images/f11264790042d0f5c1556cc7806ba0171bdf0c5cb7087a9a2679cf149b0e4d59.jpg" length="0" type="image/jpg"/>
        </item>
        <item>
            <title><![CDATA[Creating a stack in solidity via a linked list.]]></title>
            <link>https://paragraph.com/@deor/creating-a-stack-in-solidity-via-a-linked-list</link>
            <guid>FqddU82Viq6JA9UZRVoD</guid>
            <pubDate>Sun, 20 Feb 2022 16:41:09 GMT</pubDate>
            <description><![CDATA[Ok, cool. Now what are all these words. A stack? A linked list? Solidity? Lets start off with going over linked lists.If you are already familiar with linked lists and stacks, you can skip these parts and go to the end where the solidity code is discussedWhat is a linked list?A linked list is a data structure that is made up of nodes. Every node contains two things: data, and a pointer to the next node in the list. In this scenario, we are using a single linked list, which is a linked list th...]]></description>
            <content:encoded><![CDATA[<p>Ok, cool. Now what are all these words. A stack? A linked list? Solidity?</p><p>Lets start off with going over linked lists.</p><blockquote><p>If you are already familiar with linked lists and stacks, you can skip these parts and go to the end where the solidity code is discussed</p></blockquote><h2 id="h-what-is-a-linked-list" class="text-3xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0">What is a linked list?</h2><p>A linked list is a data structure that is made up of nodes. Every node contains two things: data, and a pointer to the next node in the list. In this scenario, we are using a single linked list, which is a linked list that only points to the next node.</p><p>There are other types of inked lists, such a doubly linked lists, where each node points to the node in front of it and behind it.</p><figure float="none" data-type="figure" class="img-center" style="max-width: null;"><img src="https://storage.googleapis.com/papyrus_images/b8f4b31cdd1dcb6612c2582a4f67c9feabc537f6c028ed6c502a2e93569738b7.png" alt="Array vs Linked List diagram" blurdataurl="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACwAAAAAAQABAAACAkQBADs=" nextheight="600" nextwidth="800" class="image-node embed"><figcaption HTMLAttributes="[object Object]" class="">Array vs Linked List diagram</figcaption></figure><h3 id="h-why-not-just-use-an-array" class="text-2xl font-header !mt-6 !mb-4 first:!mt-0 first:!mb-0">Why not just use an array?</h3><p>Linked lists have several advantages over traditional arrays.</p><p>For example, when inserting an element at a position in an array, you normally need to shift over all of the elements to the right. On the other hand, to insert data into a linked list you just need to change two pointers: the pointer for the node at Y-1; and the pointer for the current node to point to the node at Y+1.</p><figure float="none" data-type="figure" class="img-center" style="max-width: null;"><img src="https://storage.googleapis.com/papyrus_images/b5383053ffff2d20671d915b4b8ec8fe03bafd7189ec5bbffb8dea503e03b8df.png" alt="Array vs Linked List insertion example" blurdataurl="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACwAAAAAAQABAAACAkQBADs=" nextheight="600" nextwidth="800" class="image-node embed"><figcaption HTMLAttributes="[object Object]" class="">Array vs Linked List insertion example</figcaption></figure><p>Deletion works similarly.</p><p>Also, because linked lists are dynamic and memory is allocated dynamically according to our needs, we do not waste any memory compared to arrays—which waste memory unless they are full.</p><h2 id="h-ok-cool-now-what-is-a-stack" class="text-3xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0">Ok cool. Now, what is a stack?</h2><p>A stack is a data structure that contains a collection of items &quot;stacked&quot; on top of each other with two main operations: Push and Pop. Push adds another item onto the stack, and Pop removes the top item off the stack.</p><p>Think of a stack like a pile of plates. When you “Push”, you are adding a plate onto the stack, and when you “Pop”, you are taking that plate off.</p><figure float="none" data-type="figure" class="img-center" style="max-width: null;"><img src="https://storage.googleapis.com/papyrus_images/ce937cfabbb4bbf64e85b061cbeefdaa4e34a43b9a8bd6ee612be3dac862687a.png" alt="Diagram of the &quot;Push&quot; operation" blurdataurl="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACwAAAAAAQABAAACAkQBADs=" nextheight="600" nextwidth="800" class="image-node embed"><figcaption HTMLAttributes="[object Object]" class="">Diagram of the &quot;Push&quot; operation</figcaption></figure><h3 id="h-how-are-stacks-useful" class="text-2xl font-header !mt-6 !mb-4 first:!mt-0 first:!mb-0">How are stacks useful?</h3><p>Stacks can be used for many things! In lower level languages, there are no methods such as .reverse() that you can easily use on strings (solidity does not have .reverse!). Instead, to reverse a string, we can use stack and add each letter of the word sequentially. Afterwards, by popping each letter off the stack we reverse the word.</p><p>This is just one, small example. There are plenty more like: storing history (ctrl-z); recursion&apos;; evaluating certain mathematical expressions (Shunting Yard Algorithm);</p><h2 id="h-coming-together" class="text-3xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0">Coming together</h2><p>To create a stack, you can use a single linked-list, where every node has a pointer to the node “under” it.</p><figure float="none" data-type="figure" class="img-center" style="max-width: null;"><img src="https://storage.googleapis.com/papyrus_images/67fcc150d6a8370689f0cdf8ead436d80719b732378985733a805ff5437535cb.png" alt="Stack via linked list example" blurdataurl="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACwAAAAAAQABAAACAkQBADs=" nextheight="600" nextwidth="800" class="image-node embed"><figcaption HTMLAttributes="[object Object]" class="">Stack via linked list example</figcaption></figure><h2 id="h-actual-solidity-code" class="text-3xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0">Actual Solidity Code</h2><p>First, we need to define a struct for a Node, it should contain a value and a next pointer to point to the next node.</p><blockquote><p>When implementing a linked list, you usually use a memory address pointer when defining a node. For example in C++ you can define the Node as a pointer to another Node class instance!</p></blockquote><p>Example of Node class in C++:</p><pre data-type="codeBlock" text="class Node {
    private:
        int data;
        Node * next;
    public:
        Node(int data) {
            this-&gt;data = data;
            this-&gt;next = NULL;
        }
        int getData() {
            return this-&gt;data;
        }
        Node * getNext() {
            return this-&gt;next;
        }
        void setNext(Node * next) {
            this-&gt;next = next;
        }

};
"><code>class Node {
    <span class="hljs-keyword">private</span>:
        <span class="hljs-keyword">int</span> data;
        Node <span class="hljs-operator">*</span> next;
    <span class="hljs-keyword">public</span>:
        Node(<span class="hljs-keyword">int</span> data) {
            <span class="hljs-built_in">this</span><span class="hljs-operator">-</span><span class="hljs-operator">></span>data <span class="hljs-operator">=</span> data;
            <span class="hljs-built_in">this</span><span class="hljs-operator">-</span><span class="hljs-operator">></span>next <span class="hljs-operator">=</span> NULL;
        }
        <span class="hljs-keyword">int</span> getData() {
            <span class="hljs-keyword">return</span> <span class="hljs-built_in">this</span><span class="hljs-operator">-</span><span class="hljs-operator">></span>data;
        }
        Node <span class="hljs-operator">*</span> getNext() {
            <span class="hljs-keyword">return</span> <span class="hljs-built_in">this</span><span class="hljs-operator">-</span><span class="hljs-operator">></span>next;
        }
        void setNext(Node <span class="hljs-operator">*</span> next) {
            <span class="hljs-built_in">this</span><span class="hljs-operator">-</span><span class="hljs-operator">></span>next <span class="hljs-operator">=</span> next;
        }

};
</code></pre><p>In solidity, it is not possible to do this in the same manner. This is because Solidity does not allow recursive structs:</p><pre data-type="codeBlock" text="    struct Node {
        uint256 value;
        Node next;
    }   
"><code>    struct Node {
        uint256 value<span class="hljs-comment">;</span>
        Node next<span class="hljs-comment">;</span>
    }   
</code></pre><p>So instead of pointing to the memory address of the next node, our struct should contain a key in a mapping which points to the next node:</p><pre data-type="codeBlock" text=" struct Node {
        uint256 value;
        bytes32 next;
    }   

 mapping (bytes32 =&gt; Node) nodes;  
"><code> <span class="hljs-keyword">struct</span> <span class="hljs-title">Node</span> {
        <span class="hljs-keyword">uint256</span> value;
        <span class="hljs-keyword">bytes32</span> next;
    }   

 <span class="hljs-keyword">mapping</span> (<span class="hljs-keyword">bytes32</span> <span class="hljs-operator">=</span><span class="hljs-operator">></span> Node) nodes;  
</code></pre><p>The ID for the next node should be something unique, for example taking the hash of the old top’s value, id, and the current block timestamp. By using the OldTop’s next-id, we can make sure that we won’t get overlapping keys within the same block:</p><pre data-type="codeBlock" text="keccak256(
        abi.encodePacked(
             OldTop.value,
             OldTop.next,
             block.timestamp
        )
);
"><code><span class="hljs-built_in">keccak256</span>(
        <span class="hljs-built_in">abi</span>.<span class="hljs-built_in">encodePacked</span>(
             OldTop.<span class="hljs-built_in">value</span>,
             OldTop.next,
             <span class="hljs-built_in">block</span>.<span class="hljs-built_in">timestamp</span>
        )
);
</code></pre><p>Then, we take this ID and map it to the the old top node. Here is the main code for push:</p><pre data-type="codeBlock" text=" function push(uint256 value) public {
        Node memory node;
        node.value = value;

        if (Top.next == 0) {
            // code if the stack is empty
        }  else {
            Node storage OldTop = Top;
            node.next = keccak256(
                abi.encodePacked(
                    OldTop.value,
                    OldTop.next,
                    block.timestamp
                )
            );
            nodes[node.next] = OldTop;
            Top = node;
        }
    }
"><code> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">push</span>(<span class="hljs-params"><span class="hljs-keyword">uint256</span> value</span>) <span class="hljs-title"><span class="hljs-keyword">public</span></span> </span>{
        Node <span class="hljs-keyword">memory</span> node;
        node.<span class="hljs-built_in">value</span> <span class="hljs-operator">=</span> value;

        <span class="hljs-keyword">if</span> (Top.next <span class="hljs-operator">=</span><span class="hljs-operator">=</span> <span class="hljs-number">0</span>) {
            <span class="hljs-comment">// code if the stack is empty</span>
        }  <span class="hljs-keyword">else</span> {
            Node <span class="hljs-keyword">storage</span> OldTop <span class="hljs-operator">=</span> Top;
            node.next <span class="hljs-operator">=</span> <span class="hljs-built_in">keccak256</span>(
                <span class="hljs-built_in">abi</span>.<span class="hljs-built_in">encodePacked</span>(
                    OldTop.<span class="hljs-built_in">value</span>,
                    OldTop.next,
                    <span class="hljs-built_in">block</span>.<span class="hljs-built_in">timestamp</span>
                )
            );
            nodes[node.next] <span class="hljs-operator">=</span> OldTop;
            Top <span class="hljs-operator">=</span> node;
        }
    }
</code></pre><p>So, what is happening in this code block? Lets break it down.</p><p>First, we assigned the current Top value in the stack to OldTop. Then, we create an ID based off of the OldTop values and the current block timestamp.</p><p>Next, we assign this ID to the new Top node, and then we map this ID to the OldTop node in the mapping. After this, we assign the Top node to the new node that is being pushed to the stack.</p><p>This solidity implementation of a linked list works without a counter to count the number of nodes and to use as a key for in the mapping to other nodes in the list.</p><p>The way pop works is very simple:</p><pre data-type="codeBlock" text="    function pop() public returns (uint256) {
        require(Top.next != 0, &quot;Stack is empty&quot;);
        
        Node storage oldTop = Top;
        uint256 oldValue = Top.value;

        Top = nodes[oldTop.next];
        return oldValue;
    }
"><code>    <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">pop</span>(<span class="hljs-params"></span>) <span class="hljs-title"><span class="hljs-keyword">public</span></span> <span class="hljs-title"><span class="hljs-keyword">returns</span></span> (<span class="hljs-params"><span class="hljs-keyword">uint256</span></span>) </span>{
        <span class="hljs-built_in">require</span>(Top.next <span class="hljs-operator">!</span><span class="hljs-operator">=</span> <span class="hljs-number">0</span>, <span class="hljs-string">"Stack is empty"</span>);
        
        Node <span class="hljs-keyword">storage</span> oldTop <span class="hljs-operator">=</span> Top;
        <span class="hljs-keyword">uint256</span> oldValue <span class="hljs-operator">=</span> Top.<span class="hljs-built_in">value</span>;

        Top <span class="hljs-operator">=</span> nodes[oldTop.next];
        <span class="hljs-keyword">return</span> oldValue;
    }
</code></pre><p>If the stack is not empty, the ID for the top node is used to get the node under it, and then that node becomes the new top.</p><p>Also, it is usually a common practice to return the value of the node being popped off the stack, which is why we return the oldValue at the end.</p><p>That’s all folks! There are some other functions such as clear, peek, isEmpty, and size that are not as important to the core design so I chose not to go over them. If you want to see how they work head over to the repo!</p><p><a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://github.com/d3or/ll-stack-solidity/blob/master/src/LinkedListStack.sol">https://github.com/d3or/ll-stack-solidity/blob/master/src/LinkedListStack.sol</a></p><p>This is my first ever article, if you have any feedback you can reach me on twitter</p><p><a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://twitter.com/Deor">https://twitter.com/Deor</a></p>]]></content:encoded>
            <author>deor@newsletter.paragraph.com (Deor)</author>
        </item>
    </channel>
</rss>