UNPKG

ds-algo-study

Version:

Just experimenting with publishing a package

6,987 lines 516 kB
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
  <link href='http://fonts.googleapis.com/css?family=Droid+Sans:700' rel='stylesheet'>
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css"
        integrity="sha384-JcKb8q3iqJ61gNV9KGb8thSsNjpSL0n8PARn9HuZOnIxN0hoP+VmmDGMN5t9UJ0Z" crossorigin="anonymous">
    <link rel="stylesheet" href="./prism.css">
    <script async defer src="./prism.js"></script>

    <link rel="stylesheet" href="./style.css">
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css"
        integrity="sha384-JcKb8q3iqJ61gNV9KGb8thSsNjpSL0n8PARn9HuZOnIxN0hoP+VmmDGMN5t9UJ0Z" crossorigin="anonymous">
    <link href="//netdna.bootstrapcdn.com/bootstrap/3.0.3/css/bootstrap.min.css" rel="stylesheet">
    <script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
    <script src="//netdna.bootstrapcdn.com/bootstrap/3.1.1/js/bootstrap.min.js"></script>
    <link rel="stylesheet" href="./prism.css">
    <script async defer src="./prism.js"></script>
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css"
        integrity="sha384-wvfXpqpZZVQGK6TAh5PVlGOfQNHSoD2xbE+QkPxCAFlNEevoEH3Sl0sibVcOQVnN" crossorigin="anonymous">

    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>

    

    </style>
</head>

<body>

    <div class="container" id="body">

 <h1 id="clarify-the-concept-of-recursion">Clarify the concept of recursion</h1>
 <p>What's the difference and connections between recursion, divide-and-conquer algorithm, dynamic programming, and
     greedy algorithm? If you haven't made it clear. Doesn't matter! I would give you a brief introduction to kick
     off this section.</p>
 <p>Recursion is a programming technique. It's a way of thinking about solving problems. There're two algorithmic
     ideas to solve specific problems: divide-and-conquer algorithm and dynamic programming. They're largely based on
     recursive thinking (although the final version of dynamic programming is rarely recursive, the problem-solving
     idea is still inseparable from recursion). There's also an algorithmic idea called greedy algorithm which can
     efficiently solve some more special problems. And it's a subset of dynamic programming algorithms.</p>
 <p>The divide-and-conquer algorithm will be explained in this section. Taking the most classic merge sort as an
     example, it continuously divides the unsorted array into smaller sub-problems. This is the origin of the word
     <strong>divide and conquer</strong>. Obviously, the sub-problems decomposed by the ranking problem are
     non-repeating. If some of the sub-problems after decomposition are duplicated (the nature of overlapping
     sub-problems), then the dynamic programming algorithm is used to solve them!
 </p>
 <h2 id="recursion-in-detail">Recursion in detail</h2>
 <p>Before introducing divide and conquer algorithm, we must first understand the concept of recursion.</p>
 <p>The basic idea of recursion is that a function calls itself directly or indirectly, which transforms the solution
     of the original problem into many smaller sub-problems of the same nature. All we need is to focus on how to
     divide the original problem into qualified sub-problems, rather than study how this sub-problem is solved. The
     difference between recursion and enumeration is that enumeration divides the problem horizontally and then
     solves the sub-problems one by one, but recursion divides the problem vertically and then solves the
     sub-problems hierarchily.</p>
 <p>The following illustrates my understanding of recursion. <strong>If you don't want to read, please just remember
         how to answer these questions:</strong></p>
 <ol type="1">
     <li>How to sort a bunch of numbers? Answer: Divided into two halves, first align the left half, then the right
         half, and finally merge. As for how to arrange the left and right half, please read this sentence again.
     </li>
     <li>How many hairs does Monkey King have? Answer: One plus the rest.</li>
     <li>How old are you this year? Answer: One year plus my age of last year, I was born in 1999.</li>
 </ol>
 <p>Two of the most important characteristics of recursive code: <strong>end conditions and self-invocation</strong>.
     Self-invocation is aimed at solving sub-problems, and the end condition defines the answer to the simplest
     sub-problem.</p>
 <div class="sourceCode" id="cb1">
     <pre data-filter-output="(out)" class="sourceCode cpp"><code class="sourceCode cpp"><a class="sourceLine" id="cb1-1" title="1"><span class="lang-js dt">int</span> func(How old are you <span class="lang-js kw">this</span> year) {</a>
<a class="sourceLine" id="cb1-2" title="2"></a>
<a class="sourceLine" id="cb1-3" title="3">    <span class="lang-js co">// simplest sub-problem, end condition</span></a>
<a class="sourceLine" id="cb1-4" title="4">    <span class="lang-js cf">if</span> (<span class="lang-js kw">this</span> year equals <span class="lang-js dv">1999</span>) <span class="lang-js cf">return</span> my age <span class="lang-js dv">0</span>;</a>
<a class="sourceLine" id="cb1-5" title="5">    <span class="lang-js co">// self-calling to decompose problem</span></a>
<a class="sourceLine" id="cb1-6" title="6">    <span class="lang-js cf">return</span> func(How old are you last year) + <span class="lang-js dv">1</span>;   </a>
<a class="sourceLine" id="cb1-7" title="7"></a>
<a class="sourceLine" id="cb1-8" title="8">}</a></code></pre>
 </div>
 <p>Actually think about it, <strong>what is the most successful application of recursion? I think it's mathematical
         induction</strong>. Most of us learned mathematical induction in high school. The usage scenario is
     probably: we can't figure out a summation formula, but we tried a few small numbers which seemed containing a
     kinda law, and then we compiled a formula. We ourselves think it shall be the correct answer. However,
     mathematics is very rigorous. Even if you've tried 10,000 cases which are correct, can you guarantee the 10001th
     correct? This requires mathematical induction to exert its power. Assuming that the formula we compiled is true
     at the kth number, furthermore if it is proved correct at the k + 1th, then the formula we have compiled is
     verified correct.</p>
 <p>So what is the connection between mathematical induction and recursion? We just said that the recursive code must
     have an end condition. If not, it will fall into endless self-calling hell until the memory exhausted. The
     difficulty of mathematical proof is that you can try to have a finite number of cases, but it is difficult to
     extend your conclusion to infinity. Here you can see the connection-infinite.</p>
 <p>The essence of recursive code is to call itself to solve smaller sub-problems until the end condition is reached.
     The reason why mathematical induction is useful is to continuously increase our guess by one, and expand the
     size of the conclusion, without end condition. So by extending the conclusion to infinity, the proof of the
     correctness of the guess is completed.</p>
 <h3 id="why-learn-recursion">Why learn recursion</h3>
 <p>First to train the ability to think reversely. Recursive thinking is the thinking of normal people, always
     looking at the problems in front of them and thinking about solutions, and the solution is the future tense;
     Recursive thinking forces us to think reversely, see the end of the problem, and treat the problem-solving
     process as the past tense.</p>
 <p>Second, practice analyzing the structure of the problem. When the problem can be broken down into sub problems of
     the same structure, you can acutely find this feature, and then solve it efficiently.</p>
 <p>Third, go beyond the details and look at the problem as a whole. Let's talk about merge and sort. In fact, you
     can divide the left and right areas without recursion, but the cost is that the code is extremely difficult to
     understand. Take a look at the code below (merge sorting will be described later. You can understand the meaning
     here, and appreciate the beauty of recursion).</p>
 <div class="sourceCode" id="cb2">
     <pre data-filter-output="(out)" class="sourceCode java"><code class="sourceCode java"><a class="sourceLine" id="cb2-1" title="1"><span class="lang-js dt">void</span> <span class="lang-js fu">sort</span>(<span class="lang-js bu">Comparable</span>[] a){    </a>
<a class="sourceLine" id="cb2-2" title="2">    <span class="lang-js dt">int</span> N = a.<span class="lang-js fu">length</span>;</a>
<a class="sourceLine" id="cb2-3" title="3">    <span class="lang-js co">// So complicated! It shows disrespect for sorting. I refuse to study such code.</span></a>
<a class="sourceLine" id="cb2-4" title="4">    <span class="lang-js kw">for</span> (<span class="lang-js dt">int</span> sz = <span class="lang-js dv">1</span>; sz &lt; N; sz = sz + sz)</a>
<a class="sourceLine" id="cb2-5" title="5">        <span class="lang-js kw">for</span> (<span class="lang-js dt">int</span> lo = <span class="lang-js dv">0</span>; lo &lt; N - sz; lo += sz + sz)</a>
<a class="sourceLine" id="cb2-6" title="6">            <span class="lang-js fu">merge</span>(a, lo, lo + sz - <span class="lang-js dv">1</span>, <span class="lang-js bu">Math</span>.<span class="lang-js fu">min</span>(lo + sz + sz - <span class="lang-js dv">1</span>, N - <span class="lang-js dv">1</span>));</a>
<a class="sourceLine" id="cb2-7" title="7">}</a>
<a class="sourceLine" id="cb2-8" title="8"></a>
<a class="sourceLine" id="cb2-9" title="9"><span class="lang-js co">/* I prefer recursion, simple and beautiful */</span></a>
<a class="sourceLine" id="cb2-10" title="10"><span class="lang-js dt">void</span> <span class="lang-js fu">sort</span>(<span class="lang-js bu">Comparable</span>[] a, <span class="lang-js dt">int</span> lo, <span class="lang-js dt">int</span> hi) {</a>
<a class="sourceLine" id="cb2-11" title="11">    <span class="lang-js kw">if</span> (lo &gt;= hi) <span class="lang-js kw">return</span>;</a>
<a class="sourceLine" id="cb2-12" title="12">    <span class="lang-js dt">int</span> mid = lo + (hi - lo) / <span class="lang-js dv">2</span>;</a>
<a class="sourceLine" id="cb2-13" title="13">    <span class="lang-js fu">sort</span>(a, lo, mid); <span class="lang-js co">// soft left part</span></a>
<a class="sourceLine" id="cb2-14" title="14">    <span class="lang-js fu">sort</span>(a, mid + <span class="lang-js dv">1</span>, hi); <span class="lang-js co">// soft right part</span></a>
<a class="sourceLine" id="cb2-15" title="15">    <span class="lang-js fu">merge</span>(a, lo, mid, hi); <span class="lang-js co">// merge the two sides</span></a>
<a class="sourceLine" id="cb2-16" title="16">}</a></code></pre>
 </div>
 <p>Looks simple and beautiful is one aspect, the key is <strong>very interpretable</strong>: sort the left half,
     sort the right half, and finally merge the two sides. The non-recursive version looks unintelligible, full of
     various incomprehensible boundary calculation details, is particularly prone to bugs and difficult to debug.
     Life is short, i prefer the recursive version.</p>
 <p>Obviously, sometimes recursive processing is efficient, such as merge sort, <strong>sometimes
         inefficient</strong>, such as counting the hair of Monkey King, because the stack consumes extra space but
     simple inference does not consume space. Example below gives a linked list header and calculate its length:</p>
 <div class="sourceCode" id="cb3">
     <pre data-filter-output="(out)" class="sourceCode java"><code class="sourceCode java"><a class="sourceLine" id="cb3-1" title="1"><span class="lang-js co">/* Typical recursive traversal framework requires extra space O(1) */</span></a>
<a class="sourceLine" id="cb3-2" title="2"><span class="lang-js kw">public</span> <span class="lang-js dt">int</span> <span class="lang-js fu">size</span>(<span class="lang-js bu">Node</span> head) {</a>
<a class="sourceLine" id="cb3-3" title="3">    <span class="lang-js dt">int</span> size = <span class="lang-js dv">0</span>;</a>
<a class="sourceLine" id="cb3-4" title="4">    <span class="lang-js kw">for</span> (<span class="lang-js bu">Node</span> p = head; p != <span class="lang-js kw">null</span>; p = p.<span class="lang-js fu">next</span>) size++;</a>
<a class="sourceLine" id="cb3-5" title="5">    <span class="lang-js kw">return</span> size;</a>
<a class="sourceLine" id="cb3-6" title="6">}</a>
<a class="sourceLine" id="cb3-7" title="7"><span class="lang-js co">/* I insist on recursion facing every problem. I need extra space O(N) */</span></a>
<a class="sourceLine" id="cb3-8" title="8"><span class="lang-js kw">public</span> <span class="lang-js dt">int</span> <span class="lang-js fu">size</span>(<span class="lang-js bu">Node</span> head) {</a>
<a class="sourceLine" id="cb3-9" title="9">    <span class="lang-js kw">if</span> (head == <span class="lang-js kw">null</span>) <span class="lang-js kw">return</span> <span class="lang-js dv">0</span>;</a>
<a class="sourceLine" id="cb3-10" title="10">    <span class="lang-js kw">return</span> <span class="lang-js fu">size</span>(head.<span class="lang-js fu">next</span>) + <span class="lang-js dv">1</span>;</a>
<a class="sourceLine" id="cb3-11" title="11">}</a></code></pre>
 </div>
 <h3 id="tips-for-writing-recursion">Tips for writing recursion</h3>
 <p>My point of view: <strong>Understand what a function does and believe it can accomplish this task. Don't try to
         jump into the details.</strong> Do not jump into this function to try to explore more details, otherwise you
     will fall into infinite details and cannot extricate yourself. The human brain carries tiny sized stack!</p>
 <p>Let's start with the simplest example: traversing a binary tree.</p>
 <div class="sourceCode" id="cb4">
     <pre data-filter-output="(out)" class="sourceCode cpp"><code class="sourceCode cpp"><a class="sourceLine" id="cb4-1" title="1"><span class="lang-js dt">void</span> traverse(TreeNode* root) {</a>
<a class="sourceLine" id="cb4-2" title="2">    <span class="lang-js cf">if</span> (root == <span class="lang-js kw">nullptr</span>) <span class="lang-js cf">return</span>;</a>
<a class="sourceLine" id="cb4-3" title="3">    traverse(root-&gt;left);</a>
<a class="sourceLine" id="cb4-4" title="4">    traverse(root-&gt;right);</a>
<a class="sourceLine" id="cb4-5" title="5">}</a></code></pre>
 </div>
 <p>Above few lines of code are enough to wipe out any binary tree. What I want to say is that for the recursive
     function <code class="language-javascript">traverse (root)</code> , we just need to believe: give it a root node
     <code class="language-javascript">root</code> , and it
     can traverse the whole tree. Since this function is written for this specific purpose, so we just need to dump
     the left and right nodes of this node to this function, because I believe it can surely complete the task. What
     about traversing an N-fork tree? It's too simple, exactly the same as a binary tree!
 </p>
 <div class="sourceCode" id="cb5">
     <pre data-filter-output="(out)" class="sourceCode cpp"><code class="sourceCode cpp"><a class="sourceLine" id="cb5-1" title="1"><span class="lang-js dt">void</span> traverse(TreeNode* root) {</a>
<a class="sourceLine" id="cb5-2" title="2">    <span class="lang-js cf">if</span> (root == <span class="lang-js kw">nullptr</span>) <span class="lang-js cf">return</span>;</a>
<a class="sourceLine" id="cb5-3" title="3">    <span class="lang-js cf">for</span> (child : root-&gt;children)</a>
<a class="sourceLine" id="cb5-4" title="4">        traverse(child);</a>
<a class="sourceLine" id="cb5-5" title="5">}</a></code></pre>
 </div>
 <p>As for pre-order, mid-order, post-order traversal, they are all obvious. For N-fork tree, there is obviously no
     in-order traversal.</p>
 <p>The following <strong>explains a problem from LeetCode in detail</strong>: Given a binary tree and a target
     value, the values in every node is positive or negative, return the number of paths in the tree that are equal
     to the target value, let you write the pathSum function:</p>
 <pre data-filter-output="(out)" data-role="codeBlock" data-info="js"
     class="language-javascript data-line line-numbers data-user data-host data-prompt data-output"
     data-prismjs-copy="Copy !" data-download-link />
 <code class="language-javascript">/* from LeetCode PathSum III: https://leetcode.com/problems/path-sum-iii/ */
     root = [10,5,-3,3,2,null,11,3,-2,null,1],
     sum = 8

     10
     / \
     5 -3
     / \ \
     3 2 11
     / \ \
     3 -2 1

     Return 3. The paths that sum to 8 are:

     1. 5 -&gt; 3
     2. 5 -&gt; 2 -&gt; 1
     3. -3 -&gt; 11
 </code></pre>
 <div class="sourceCode" id="cb7">
     <pre data-filter-output="(out)" class="sourceCode cpp"><code class="sourceCode cpp"><a class="sourceLine" id="cb7-1" title="1"><span class="lang-js co">/* It doesn&#39;t matter if you don&#39;t understand, there is a more detailed analysis version below, which highlights the conciseness and beauty of recursion. */</span></a>
<a class="sourceLine" id="cb7-2" title="2"><span class="lang-js dt">int</span> pathSum(TreeNode root, <span class="lang-js dt">int</span> sum) {</a>
<a class="sourceLine" id="cb7-3" title="3">    <span class="lang-js cf">if</span> (root == null) <span class="lang-js cf">return</span> <span class="lang-js dv">0</span>;</a>
<a class="sourceLine" id="cb7-4" title="4">    <span class="lang-js cf">return</span> count(root, sum) + </a>
<a class="sourceLine" id="cb7-5" title="5">        pathSum(root.left, sum) + pathSum(root.right, sum);</a>
<a class="sourceLine" id="cb7-6" title="6">}</a>
<a class="sourceLine" id="cb7-7" title="7"><span class="lang-js dt">int</span> count(TreeNode node, <span class="lang-js dt">int</span> sum) {</a>
<a class="sourceLine" id="cb7-8" title="8">    <span class="lang-js cf">if</span> (node == null) <span class="lang-js cf">return</span> <span class="lang-js dv">0</span>;</a>
<a class="sourceLine" id="cb7-9" title="9">    <span class="lang-js cf">return</span> (node.val == sum) + </a>
<a class="sourceLine" id="cb7-10" title="10">        count(node.left, sum - node.val) + count(node.right, sum - node.val);</a>
<a class="sourceLine" id="cb7-11" title="11">}</a></code></pre>
 </div>
 <p>The problem may seem complicated, but the code is extremely concise, which is the charm of recursion. Let me
     briefly summarize the <strong>solution process</strong> of this problem:</p>
 <p>First of all, it is clear that to solve the problem of recursive tree, you must traverse the entire tree. So the
     traversal framework of the binary tree (recursively calling the function itself on the left and right children)
     must appear in the main function pathSum. And then, what should they do for each node? They should see how many
     eligible paths they and their little children have under their feet. Well, this question is clear.</p>
 <p>According to the techniques mentioned earlier, define what each recursive function should do based on the
     analysis just now:</p>
 <p>PathSum function: Give it a node and a target value. It returns the total number of paths in the tree rooted at
     this node and the target value.</p>
 <p>Count function: Give it a node and a target value. It returns a tree rooted at this node, and can make up the
     total number of paths starting with the node and the target value.</p>
 <div class="sourceCode" id="cb8">
     <pre data-filter-output="(out)" class="sourceCode cpp"><code class="sourceCode cpp"><a class="sourceLine" id="cb8-1" title="1"><span class="lang-js co">/* With above tips, comment out the code in detail */</span></a>
<a class="sourceLine" id="cb8-2" title="2"><span class="lang-js dt">int</span> pathSum(TreeNode root, <span class="lang-js dt">int</span> sum) {</a>
<a class="sourceLine" id="cb8-3" title="3">    <span class="lang-js cf">if</span> (root == null) <span class="lang-js cf">return</span> <span class="lang-js dv">0</span>;</a>
<a class="sourceLine" id="cb8-4" title="4">    <span class="lang-js dt">int</span> pathImLeading = count(root, sum); <span class="lang-js co">// Number of paths beginning with itself</span></a>
<a class="sourceLine" id="cb8-5" title="5">    <span class="lang-js dt">int</span> leftPathSum = pathSum(root.left, sum); <span class="lang-js co">// The total number of paths on the left (Believe he can figure it out)</span></a>
<a class="sourceLine" id="cb8-6" title="6">    <span class="lang-js dt">int</span> rightPathSum = pathSum(root.right, sum); <span class="lang-js co">// The total number of paths on the right (Believe he can figure it out)</span></a>
<a class="sourceLine" id="cb8-7" title="7">    <span class="lang-js cf">return</span> leftPathSum + rightPathSum + pathImLeading;</a>
<a class="sourceLine" id="cb8-8" title="8">}</a>
<a class="sourceLine" id="cb8-9" title="9"><span class="lang-js dt">int</span> count(TreeNode node, <span class="lang-js dt">int</span> sum) {</a>
<a class="sourceLine" id="cb8-10" title="10">    <span class="lang-js cf">if</span> (node == null) <span class="lang-js cf">return</span> <span class="lang-js dv">0</span>;</a>
<a class="sourceLine" id="cb8-11" title="11">    <span class="lang-js co">// Can I stand on my own as a separate path?</span></a>
<a class="sourceLine" id="cb8-12" title="12">    <span class="lang-js dt">int</span> isMe = (node.val == sum) ? <span class="lang-js dv">1</span> : <span class="lang-js dv">0</span>;</a>
<a class="sourceLine" id="cb8-13" title="13">    <span class="lang-js co">// Left brother, how many sum-node.val can you put together?</span></a>
<a class="sourceLine" id="cb8-14" title="14">    <span class="lang-js dt">int</span> leftBrother = count(node.left, sum - node.val); </a>
<a class="sourceLine" id="cb8-15" title="15">    <span class="lang-js co">// Right brother, how many sum-node.val can you put together?</span></a>
<a class="sourceLine" id="cb8-16" title="16">    <span class="lang-js dt">int</span> rightBrother = count(node.right, sum - node.val);</a>
<a class="sourceLine" id="cb8-17" title="17">    <span class="lang-js cf">return</span>  isMe + leftBrother + rightBrother; <span class="lang-js co">// all count i can make up</span></a>
<a class="sourceLine" id="cb8-18" title="18">}</a></code></pre>
 </div>
 <p>Again, understand what each function can do and trust that they can do it.</p>
 <p>In summary, the binary tree traversal framework provided by the PathSum function calls the count function for
     each node during the traversal. Can you see the pre-order traversal (the order is the same for this question)?
     The count function is also a binary tree traversal, used to find the target value path starting with this node.
     Understand it deeply!</p>
 <h2 id="divide-and-conquer-algorithm">Divide and conquer algorithm</h2>
 <p><strong>Merge and sort</strong>, typical divide-and-conquer algorithm; divide-and-conquer, typical recursive
     structure.</p>
 <p>The divide-and-conquer algorithm can go in three steps: decomposition-&gt; solve-&gt; merge</p>
 <ol type="1">
     <li>Decompose the original problem into sub-problems with the same structure.</li>
     <li>After decomposing to an easy-to-solve boundary, perform a recursive solution.</li>
     <li>Combine the solutions of the subproblems into the solutions of the original problem.</li>
 </ol>
 <p>To merge and sort, let's call this function <code class="language-javascript">merge_sort</code> . According to
     what we said above, we must
     clarify the responsibility of the function, that is, <strong>sort an incoming array</strong>. OK, can this
     problem be solved? Of course! Sorting an array is just the same to sorting the two halves of the array
     separately, and then merging the two halves.</p>
 <div class="sourceCode" id="cb9">
     <pre data-filter-output="(out)" class="sourceCode cpp"><code class="sourceCode cpp"><a class="sourceLine" id="cb9-1" title="1"><span class="lang-js dt">void</span> merge_sort(an array) {</a>
<a class="sourceLine" id="cb9-2" title="2">    <span class="lang-js cf">if</span> (some tiny array easy to solve) <span class="lang-js cf">return</span>;</a>
<a class="sourceLine" id="cb9-3" title="3">    merge_sort(left half array);</a>
<a class="sourceLine" id="cb9-4" title="4">    merge_sort(right half array);</a>
<a class="sourceLine" id="cb9-5" title="5">    merge(left half array, right half array);</a>
<a class="sourceLine" id="cb9-6" title="6">}</a></code></pre>
 </div>
 <p>Well, this algorithm is like this, there is no difficulty at all. Remember what I said before, believe in the
     function's ability, and pass it to him half of the array, then the half of the array is already sorted. Have you
     found it's a binary tree traversal template? Why it is postorder traversal? Because the routine of our
     divide-and-conquer algorithm is <strong>decomposition-&gt; solve (bottom)-&gt; merge (backtracking)</strong> Ah,
     first left and right decomposition, and then processing merge, backtracking is popping stack, which is
     equivalent to post-order traversal. As for the <code class="language-javascript">merge</code> function,
     referring to the merging of two
     ordered linked lists, they are exactly the same, and the code is directly posted below.</p>
 <p>Let's refer to the Java code in book <code class="language-javascript">Algorithm 4</code> below, which is pretty.
     This shows that not only
     algorithmic thinking is important, but coding skills are also very important! Think more and imitate more.</p>
 <div class="sourceCode" id="cb10">
     <pre data-filter-output="(out)" class="sourceCode java"><code class="sourceCode java"><a class="sourceLine" id="cb10-1" title="1"><span class="lang-js kw">public</span> <span class="lang-js kw">class</span> Merge {</a>
<a class="sourceLine" id="cb10-2" title="2">    <span class="lang-js co">// Do not construct new arrays in the merge function, because the merge function will be called multiple times, affecting performance.Construct a large enough array directly at once, concise and efficient.</span></a>
<a class="sourceLine" id="cb10-3" title="3">    <span class="lang-js kw">private</span> <span class="lang-js dt">static</span> <span class="lang-js bu">Comparable</span>[] aux;</a>
<a class="sourceLine" id="cb10-4" title="4"></a>
<a class="sourceLine" id="cb10-5" title="5">     <span class="lang-js kw">public</span> <span class="lang-js dt">static</span> <span class="lang-js dt">void</span> <span class="lang-js fu">sort</span>(<span class="lang-js bu">Comparable</span>[] a) {</a>
<a class="sourceLine" id="cb10-6" title="6">        aux = <span class="lang-js kw">new</span> <span class="lang-js bu">Comparable</span>[a.<span class="lang-js fu">length</span>];</a>
<a class="sourceLine" id="cb10-7" title="7">        <span class="lang-js fu">sort</span>(a, <span class="lang-js dv">0</span>, a.<span class="lang-js fu">length</span> - <span class="lang-js dv">1</span>);</a>
<a class="sourceLine" id="cb10-8" title="8">    }</a>
<a class="sourceLine" id="cb10-9" title="9"></a>
<a class="sourceLine" id="cb10-10" title="10">    <span class="lang-js kw">private</span> <span class="lang-js dt">static</span> <span class="lang-js dt">void</span> <span class="lang-js fu">sort</span>(<span class="lang-js bu">Comparable</span>[] a, <span class="lang-js dt">int</span> lo, <span class="lang-js dt">int</span> hi) {</a>
<a class="sourceLine" id="cb10-11" title="11">        <span class="lang-js kw">if</span> (lo &gt;= hi) <span class="lang-js kw">return</span>;</a>
<a class="sourceLine" id="cb10-12" title="12">        <span class="lang-js dt">int</span> mid = lo + (hi - lo) / <span class="lang-js dv">2</span>;</a>
<a class="sourceLine" id="cb10-13" title="13">        <span class="lang-js fu">sort</span>(a, lo, mid);</a>
<a class="sourceLine" id="cb10-14" title="14">        <span class="lang-js fu">sort</span>(a, mid + <span class="lang-js dv">1</span>, hi);</a>
<a class="sourceLine" id="cb10-15" title="15">        <span class="lang-js fu">merge</span>(a, lo, mid, hi);</a>
<a class="sourceLine" id="cb10-16" title="16">    }</a>
<a class="sourceLine" id="cb10-17" title="17"></a>
<a class="sourceLine" id="cb10-18" title="18">    <span class="lang-js kw">private</span> <span class="lang-js dt">static</span> <span class="lang-js dt">void</span> <span class="lang-js fu">merge</span>(<span class="lang-js bu">Comparable</span>[] a, <span class="lang-js dt">int</span> lo, <span class="lang-js dt">int</span> mid, <span class="lang-js dt">int</span> hi) {</a>
<a class="sourceLine" id="cb10-19" title="19">        <span class="lang-js dt">int</span> i = lo, j = mid + <span class="lang-js dv">1</span>;</a>
<a class="sourceLine" id="cb10-20" title="20">        <span class="lang-js kw">for</span> (<span class="lang-js dt">int</span> k = lo; k &lt;= hi; k++)</a>
<a class="sourceLine" id="cb10-21" title="21">            aux[k] = a[k];</a>
<a class="sourceLine" id="cb10-22" title="22">        <span class="lang-js kw">for</span> (<span class="lang-js dt">int</span> k = lo; k &lt;= hi; k++) {</a>
<a class="sourceLine" id="cb10-23" title="23">            <span class="lang-js kw">if</span>      (i &gt; mid)              { a[k] = aux[j++]; }</a>
<a class="sourceLine" id="cb10-24" title="24">            <span class="lang-js kw">else</span> <span class="lang-js kw">if</span> (j &gt; hi)               { a[k] = aux[i++]; }</a>
<a class="sourceLine" id="cb10-25" title="25">            <span class="lang-js kw">else</span> <span class="lang-js kw">if</span> (<span class="lang-js fu">less</span>(aux[j], aux[i])) { a[k] = aux[j++]; }</a>
<a class="sourceLine" id="cb10-26" title="26">            <span class="lang-js kw">else</span>                           { a[k] = aux[i++]; }</a>
<a class="sourceLine" id="cb10-27" title="27">        }</a>
<a class="sourceLine" id="cb10-28" title="28">    }</a>
<a class="sourceLine" id="cb10-29" title="29"></a>
<a class="sourceLine" id="cb10-30" title="30">    <span class="lang-js kw">private</span> <span class="lang-js dt">static</span> <span class="lang-js dt">boolean</span> <span class="lang-js fu">less</span>(<span class="lang-js bu">Comparable</span> v, <span class="lang-js bu">Comparable</span> w) {</a>
<a class="sourceLine" id="cb10-31" title="31">        <span class="lang-js kw">return</span> v.<span class="lang-js fu">compareTo</span>(w) &lt; <span class="lang-js dv">0</span>;</a>
<a class="sourceLine" id="cb10-32" title="32">    }</a>
<a class="sourceLine" id="cb10-33" title="33">}</a></code></pre>
 </div>
 <p>LeetCode has a special exercise of the divide-and-conquer algorithm. Copy the link below to web browser and have
     a try:</p>
 <p>https://leetcode.com/tag/divide-and-conquer/</p>


 <p>Prompt: write a function that will reverse a string:</p>
 <p>var reverse = function(string){<br />
     if(string.length &lt; 2){</p>
 <pre data-filter-output="(out)" data-role="codeBlock" data-info="js"
     class="language-javascript data-line line-numbers data-user data-host data-prompt data-output"
     data-prismjs-copy="Copy !" data-download-link />
 <code class="language-javascript">return string; </code></pre>
 <p>}<br />
     var first = string[0]<br />
     var last = string[string.length-1]; return last +reverse(string.slice(1, string.length-1)) + first; };
     reverse('abcdef'); //returns 'fedcba'</p>
 <p><strong>//explain what a recursive function is</strong></p>
 <p><strong><em>A function that calls itself</em></strong> is a recursive function.</p>
 <p>If a function calls itself… then that function calls itself… then that function calls itself… well… then we
     have
     fallen into an infinite loop (a very unproductive place to be). To benefit from recursive calls, we need to
     be
     careful to include to give our interpreter a way to break out of the cycle of recursive function calls; we
     call
     this a <strong><em>base case</em></strong>.</p>
 <p>The base case in the solution code above is as simple as testing that the length of the argument is less than
     2…
     and if it is, returning the the value of that argument.</p>
 <p>Notice how each time we recursively call the reverse function, we are passing it a shorter string argument…
     so
     each recursive call is getting us closer to hitting our <strong><em>base case</em></strong>.</p>
 <p><strong>//visualize the interpreter's path through recursive function calls</strong></p>
 <figure>
     <img src="https://miro.medium.com/max/60/1*J4FL6LpLY1AXy_KPFdREKw.png?q=20" alt="Image for post" />
     <figcaption>Image for post</figcaption>
 </figure>
 <figure>
     <img src="https://miro.medium.com/max/1810/1*J4FL6LpLY1AXy_KPFdREKw.png" alt="Image for post" />
     <figcaption>Image for post</figcaption>
 </figure>
 <p>Slow down and follow the interpreter through its execution of your algorithm (thanks to PythonTutor.com)</p>
 <p>Python Tutor is an excellent resource for learning to visualize and trace variable values through the
     multiple
     execution contexts of a recursive function's invocation.</p>
 <p><em>Try it now with these simple steps:</em></p>
 <ol type="1">
     <li><em>copy the solution code from above</em></li>
     <li><em>go over to</em> <a
             href="http://pythontutor.com/javascript.html#mode=edit"><em>http://pythontutor.com/javascript.html#mode=edit</em></a>
     </li>
     <li><em>paste the solution code into the editor</em></li>
     <li><em>click the "Visualize Execution" button</em></li>
     <li><em>progress through the execution with the "forward" button</em></li>
 </ol>
 <p><strong>//when can a recursive function help me?</strong></p>
 <p>So if I hope that at this point that you are thinking: there is a <strong><em>better</em></strong> way to
     reverse
     a function, or there is a <strong><em>simpler</em></strong> way to reverse a string…</p>
 <p>First off… <strong><em>simpler is better.</em></strong> Writing good code isn't about being clever or fancy;
     good
     code is about writing code that works, that makes sense to as many other minds as possible, that is time
     efficient, and that is memory efficient (in order of importance). As new programers, the first of these
     criteria
     is obvious, and the last two are given way too much weight. It's the second of these criteria that needs to
     carry much more weight in our minds and deserves the most attention. Recursive functions can be a powerful
     tool
     in helping us write clear and simple solutions.</p>
 <p>To be clear: recursion is not about being fancy or clever… it is an important skill to wrestle with early
     because
     there will be many scenarios when employing recursion will allow for a simpler and more reliable solution
     than
     would be possible without recursive functions.</p>
 <p><strong>//more useful example</strong></p>
 <p>Prompt: check to see if a binary-search-tree contains a value</p>
 <p>var searchBST = function(tree, num){<br />
     if(tree.val === num){</p>
 <pre data-filter-output="(out)" data-role="codeBlock" data-info="js"
     class="language-javascript data-line line-numbers data-user data-host data-prompt data-output"
     data-prismjs-copy="Copy !" data-download-link />
 <code class="language-javascript">return true </code></pre>
 <p>} else if(num &gt; tree.val){</p>
 <pre data-filter-output="(out)" data-role="codeBlock" data-info="js"
     class="language-javascript data-line line-numbers data-user data-host data-prompt data-output"
     data-prismjs-copy="Copy !" data-download-link />
 <code class="language-javascript">if(tree.right === null){
     return false;
     } else{
     return searchBST(tree.right, num);
     } </code></pre>
 <p>} else{</p>
 <pre data-filter-output="(out)" data-role="codeBlock" data-info="js"
     class="language-javascript data-line line-numbers data-user data-host data-prompt data-output"
     data-prismjs-copy="Copy !" data-download-link />
 <code class="language-javascript">if(tree.left === null){
     return false;
     } else{
     return searchBST(tree.left, num);
     } </code></pre>
 <p>}<br />
     }; var tree = {val: 9,</p>
 <pre data-filter-output="(out)" data-role="codeBlock" data-info="js"
     class="language-javascript data-line line-numbers data-user data-host data-prompt data-output"
     data-prismjs-copy="Copy !" data-download-link />
 <code class="language-javascript"> left: {val: 5,
     left: null,
     right: {val: 7,
     left: null,
     right: null}
     },
     right: {val: 20,
     left: {val: 16,
     left: null,
     right: {val: 18,
     left: null,
     right: null}
     },
     right: null}
     };searchBST(tree, 18) // return true </code></pre>
 <p>searchBST(tree, 4) // return false</p>
 <p>When traversing trees and many other other non-primative data structures, recursion allows us to define a
     clear
     algorithm that elegantly handles uncertainty and complexity. Without recursion, it would be impossible to
     write
     a single function that could search a binary search tree of any size and state… yet by employing recursion,
     we
     can write a concise algorithm that will traverse any binary search tree and determine if it contains a value
     or
     not.</p>
 <p>Take a moment to analyze how recursion is used in this example by tracing the interpreters path through this
     solution. Just as we did for the reverse function above, paste this binary search tree code snippet into the
     editor at <a
         href="http://pythontutor.com/javascript.html#mode=display">http://pythontutor.com/javascript.html#mode=display</a>
 </p>
 <p>In this function definition, there are three base cases that will return a value instead of recursively
     calling
     the searchBST function… can you find them?</p>
 <p>//now go practice using recursion</p>

        <h1 id="data-structures-and-algorithms" data-ignore="true"><br><em>Data Structures and
                Algorithms</em>
        </h1>
        <hr />
        <!-- code_chunk_output -->

        <p><a href="#big-o-"><strong>Big O </strong></a> <a href="#memoization-and-tabulation-"><strong>Memoization And
                    Tabulation </strong></a>
            - <a href="#recursion-videos">Recursion Videos</a> - <a
                href="#curating-complexity-a-guide-to-big-o-notation">Curating Complexity: A Guide to Big-O Notation</a>
            -
            <a href="#why-big-o">Why Big-O?</a> - <a href="#big-o-notation">Big-O Notation</a> - <a
                href="#common-complexity-classes">Common Complexity Classes</a> - <a href="#the-seven-major-classes">The
                seven major classes</a> - <a href="#memoization">Memoization</a> - <a
                href="#memoizing-factorial">Memoizing
                factorial</a> - <a href="#memoizing-the-fibonacci-generator">Memoizing the Fibonacci generator</a> - <a
                href="#the-memoization-formula">The memoization formula</a> - <a href="#tabulation">Tabulation</a> - <a
                href="#tabulating-the-fibonacci-number">Tabulating the Fibonacci number</a> - <a
                href="#aside-refactoring-for-o1-space">Aside: Refactoring for O(1) Space</a> - <a
                href="#analysis-of-linear-search">Analysis of Linear Search</a> - <a
                href="#analysis-of-binary-search">Analysis of Binary Search</a> - <a
                href="#analysis-of-the-merge-sort">Analysis of the Merge Sort</a> - <a
                href="#analysis-of-bubble-sort">Analysis of Bubble Sort</a> - <a href="#leetcodecom">LeetCode.com</a> -
            <a href="#memoization-problems">Memoization Problems</a> - <a href="#tabulation-problems">Tabulation
                Problems</a>
        </p>
        <p><a href="#sorting-algorithms-"><strong>Sorting Algorithms </strong></a> - <a href="#bubble-sort">Bubble
                Sort</a> - <a href="#_butthenwhy-are-we_"><em>"But…then…why are we…"</em></a>
            -
            <a href="#the-algorithm-bubbles-up">The algorithm bubbles up</a> - <a
                href="#how-does-a-pass-of-bubble-sort-work">How does a pass of Bubble Sort work?</a> - <a
                href="#ending-the-bubble-sort">Ending the Bubble Sort</a> - <a
                href="#pseudocode-for-bubble-sort">Pseudocode
                for Bubble Sort</a> - <a href="#selection-sort">Selection Sort</a> - <a
                href="#the-algorithm-select-the-next-smallest">The algorithm: select the next smallest</a> - <a
                href="#the-pseudocode">The pseudocode</a> - <a href="#insertion-sort">Insertion Sort</a> - <a
                href="#the-algorithm-insert-into-the-sorted-region">The algorithm: insert into the sorted region</a> -
            <a href="#the-steps">The Steps</a> - <a href="#the-pseudocode-1">The pseudocode</a> - <a
                href="#merge-sort">Merge Sort</a> - <a href="#the-algorithm-divide-and-conquer">The algorithm: divide
                and
                conquer</a> - <a href="#quick-sort">Quick Sort</a> - <a href="#how-does-it-work">How does it work?</a> -
            <a href="#the-algorithm-divide-and-conquer-1">The algorithm: divide and conquer</a> - <a
                href="#the-pseudocode-2">The pseudocode</a> - <a href="#binary-search">Binary Search</a> - <a
                href="#the-algorithm-check-the-middle-and-half-the-search-space">The Algorithm: "check the middle and
                half
                the search space"</a> - <a href="#the-pseudocode-3">The pseudocode</a> - <a
                href="#bubble-sort-analysis">Bubble Sort Analysis</a> - <a href="#time-complexity-onsup2sup">Time
                Complexity: O(n2)</a> - <a href="#space-complexity-o1">Space Complexity: O(1)</a> - <a
                href="#when-should-you-use-bubble-sort">When should you use Bubble Sort?</a> - <a
                href="#selection-sort-analysis">Selection Sort Analysis</a> - <a
                href="#selection-sort-js-implementation">Selection Sort JS Implementation</a> - <a
                href="#time-complexity-analysis">Time Complexity Analysis</a> - <a
                href="#space-complexity-analysis-o1">Space Complexity Analysis: O(1)</a> - <a
                href="#when-should-we-use-selection-sort">When should we use Selection Sort?</a> - <a
                href="#insertion-sort-analysis">Insertion Sort Analysis</a> - <a
                href="#time-and-space-complexity-analysis">Time and Space Complexity Analysis</a> - <a
                href="#when-should-you-use-insertion-sort">When should you use Insertion Sort?</a> - <a
                href="#merge-sort-analysis">Merge Sort Analysis</a> - <a href="#full-code">Full code</a> - <a
                href="#merging-two-sorted-arrays">Merging two sorted arrays</a> - <a
                href="#divide-and-conquer-step-by-step">Divide and conquer, step-by-step</a> - <a
                href="#time-and-space-complexity-analysis-1">Time and Space Complexity Analysis</a> - <a
                href="#quick-sort-analysis">Quick Sort Analysis</a> - <a
                href="#time-and-space-complexity-analysis-2">Time
                and Space Complexity Analysis</a> - <a href="#binary-search-analysis">Binary Search Analysis</a> - <a
                href="#time-and-space-complexity-analysis-3">Time and Space Complexity Analysis</a> - <a
                href="#practice-bubble-sort">Practice: Bubble Sort</a> - <a href="#practice-selection-sort">Practice:
                Selection Sort</a> - <a href="#practice-insertion-sort">Practice: Insertion Sort</a> - <a
                href="#practice-merge-sort">Practice: Merge Sort</a> - <a href="#practice-quick-sort-2">Practice: Quick
                Sort</a> - <a href="#practice-binary-search">Practice: Binary Search</a>
        </p>
        <p><a href="#lists-stacks-and-queues-"><strong>Lists, Stacks, and Queues </strong></a> - <a
                href="#linked-lists">Linked Lists</a> - <a href="#what-is-a-linked-list">What is a Linked List?</a> - <a
                href="#types-of-linked-lists">Types of Linked Lists</a> - <a href="#linked-list-methods">Linked List
                Methods</a> - <a href="#time-and-space-complexity-analysis-4">Time and Space Complexity Analysis</a> -
            <a href="#time-complexity-access-and-search">Time Complexity - Access and Search</a> - <a
                href="#time-complexity-insertion-and-deletion">Time Complexity - Insertion and Deletion</a> - <a
                href="#space-complexity-1">Space Complexity</a> - <a href="#stacks-and-queues">Stacks and Queues</a> -
            <a href="#what-is-a-stack">What is a Stack?</a> - <a href="#what-is-a-queue">What is a Queue?</a> - <a
                href="#stack-and-queue-properties">Stack and Queue Properties</a> - <a href="#stack-methods">Stack
                Methods</a> - <a href="#queue-methods">Queue Methods</a> - <a
                href="#time-and-space-complexity-analysis-5">Time and Space Complexity Analysis</a> - <a
                href="#when-should-we-use-stacks-and-queues">When should we use Stacks and Queues?</a> - <a </p>
                <p><a href="#graphs-and-heaps-"><strong>Graphs and Heaps </strong></a> - <a
                        href="#introduction-to-heaps">Introduction to Heaps</a> - <a
                        href="#binary-heap-implementation">Binary
                        Heap
                        Implementation</a> - <a href="#heap-sort">Heap Sort</a> - <a href="#in-place-heap-sort">In-Place
                        Heap
                        Sort</a> - </p>
                <!-- /code_chunk_output -->
                <hr />

                <h1 id="big-o-">Big O </h1>
                <p><strong>The objective of this lesson</strong> is get you comfortable with identifying the time and
                    space
                    complexity of code you see. Being able to diagnose time complexity for algorithms is an essential
                    for
                    interviewing software engineers.</p>
                <p>At the end of this, you will be able to</p>
                <ol type="1">
                    <li>Order the common complexity classes according to their growth rate</li>
                    <li>Identify the complexity classes of common sort methods</li>
                    <li>Identify complexity classes of codeable with identifying the time and space complexity of code
                        you see.
                        Being able to diagnose time complexity for algorithms is an essential for interviewing software
                        engineers.
                    </li>
                </ol>
                <p>At the end of this, you will be able to</p>
                <ol type="1">
                    <li>Order the common complexity classes according to their growth rate</li>
                    <li>Identify the complexity classes of common sort methods</li>
                    <li>Identify complexity classes of code</li>
                </ol>
                <hr />
                <h1 id="memoization-and-tabulation-">Memoization And Tabulation </h1>
                <p><strong>The objective of this lesson</strong> is to give you a couple of ways to optimize a
                    computation
                    (algorithm) from a higher complexity class to a lower complexity class. Being able to optimize
                    algorithms is
                    an
                    essential for interviewing software engineers.</p>
                <p>At the end of this, you will be able to</p>
                <ol type="1">
                    <li>Apply memoization to recursive problems to make them less than polynomial time.</li>
                    <li>Apply tabulation to iterative problems to make them less than polynomial time.** is to give you
                        a couple
                        of
                        ways to optimize a computation (algorithm) from a higher complexity class to a lower complexity
                        class.
                        Being
                        able to optimize algorithms is an essential for interviewing software engineers.</li>
                </ol>
                <p>At the end of this, you will be able to</p>
                <ol type="1">
                    <li>Apply memoization to recursive problems to make them less than polynomial time.</li>
                    <li>Apply tabulation to iterative problems to make them less than polynomial time.</li>
                </ol>
                <hr />
                <h1 id="recursion-videos">Recursion Videos</h1>
                <p>A lot of algorithms that we use in the upcoming days will use recursion. The next two videos are just
                    helpful
                    reminders about recursion so that you can get that thought process back into your brain.</p>
                <hr />
                <h1 id="big-o-by-colt-steele">Big-O By Colt Steele</h1>
                <p>Colt Steele provides a very nice, non-mathy introduction to Big-O notation. Please watch this so you
                    can get
                    the
                    easy introduction. Big-O is, by its very nature, math based. It's good to get an understanding
                    before
                    jumping in
                    to math expressions.</p>
                <p><a href="https://www.youtube.com/embed/kS_gr2_-ws8">Complete Beginner's Guide to Big O Notation</a>
                    by Colt
                    Steele.</p>
                <hr />
                <h1 id="curating-complexity-a-guide-to-big-o-notation">Curating Complexity: A Guide to Big-O Notation
                </h1>
                <p>As software engineers, our goal is not just to solve problems. Rather, our goal is to solve problems
                    efficiently
                    and elegantly. Not all solutions are made equal! In this section we'll explore how to analyze the
                    efficiency
                    of
                    algorithms in terms of their speed (<em>time complexity</em>) and memory consumption (<em>space
                        complexity</em>).</p>
                <blockquote>
                    <p>In this article, we'll use the word <em>efficiency</em> to describe the amount of resources a
                        program
                        needs
                        to execute. The two resources we are concerned with are <em>time</em> and <em>space</em>. Our
                        goal is to
                        <em>minimize</em> the amount of time and space that our programs use.
                    </p>
                </blockquote>
                <p>When you finish this article you will be able to:</p>
                <ul>
                    <li>explain why computer scientists use Big-O notation</li>
                    <li>simplify a mathematical function into Big-O notation</li>
                </ul>
                <h2 id="why-big-o">Why Big-O?</h2>
                <p>Let's begin by understanding what method we should <em>not</em> use when describing the efficiency of
                    our
                    algorithms. Most importantly, we'll want to avoid using absolute units of time when describing
                    speed. When
                    the
                    software engineer exclaims, "My function runs in 0.2 seconds, it's so fast!!!", the computer
                    scientist is
                    not
                    impressed. Skeptical, the computer scientist asks the following questions:</p>
                <ol type="1">
                    <li>What computer did you run it on? <em>Maybe the credit belongs to the hardware and not the
                            software. Some
                            hardware architectures will be better for certain operations than others.</em></li>
                    <li>Were there other background processes running on the computer that could have effected the
                        runtime?
                        <em>It's
                            hard to control the environment during performance experiments.</em>
                    </li>
                    <li>Will your code still be performant if we increase the size of the input? <em>For example,
                            sorting 3
                            numbers
                            is trivial; but how about a million numbers?</em></li>
                </ol>
                <p>The job of the software engineer is to focus on the software detail and not necessarily the hardware
                    it will
                    run
                    on. Because we can't answer points 1 and 2 with total certainty, we'll want to avoid using concrete
                    units
                    like
                    "milliseconds" or "seconds" when describing the efficiency of our algorithms. Instead, we'll opt for
                    a more
                    abstract approach that focuses on point 3. This means that we should focus on how the performance of
                    our
                    algorithm is affected by increasing the size of the input. <strong>In other words, how does our
                        performance
                        scale?</strong></p>
                <blockquote>
                    <p>The argument above focuses on <em>time</em>, but a similar argument could also be made for
                        <em>space</em>.
                        For example, we should not analyze our code in terms of the amount of absolute kilobytes of
                        memory it
                        uses,
                        because this is dependent on the programming language.
                    </p>
                </blockquote>
                <h2 id="big-o-notation">Big-O Notation</h2>
                <p>In Computer Science, we use Big-O notation as a tool for describing the efficiency of algorithms with
                    respect
                    to
                    the size of the input argument(s). We use mathematical functions in Big-O notation, so there are a
                    few big
                    picture ideas that we'll want to keep in mind:</p>
                <ol type="1">
                    <li>The function should be defined in terms of the size of the input(s).</li>
                    <li>A <em>smaller</em> Big-O function is more desirable than a larger one. Intuitively, we want our
                        algorithms
                        to use a minimal amount of time and space.</li>
                    <li>Big-O describes the worst-case scenario for our code, also known as the upper bound. We prepare
                        our
                        algorithm for the worst case, because the best case is a luxury that is not guaranteed.</li>
                    <li>A Big-O function should be simplified to show only its most dominant mathematical term.</li>
                </ol>
                <p>The first 3 points are conceptual, so they are easy to swallow. However, point 4 is typically the
                    biggest
                    source
                    of confusion when learning the notation. Before we apply Big-O to our code, we'll need to first
                    understand
                    the
                    underlying math and simplification process.</p>
                <h3 id="simplifying-math-terms">Simplifying Math Terms</h3>
                <p>We want our Big-O notation to describe the performance of our algorithm with respect to the input
                    size and
                    nothing else. Because of this, we should to simplify our Big-O functions using the following rules:
                </p>
                <ul>
                    <li><strong>Simplify Products:</strong> if the function is a product of many terms, we drop the
                        terms that
                        <em>don't</em> depend on the size of the input.
                    </li>
                    <li><strong>Simplify Sums:</strong> if the function is a sum of many terms, we keep the term with
                        the
                        <em>largest</em> growth rate and drop the other terms.
                    </li>
                </ul>
                <p>We'll look at these rules in action, but first we'll define a few things:</p>
                <ul>
                    <li><strong>n</strong> is the size of the input</li>
                    <li><strong>T(f)</strong> refers to an unsimplified mathematical <strong>f</strong>unction</li>
                    <li><strong>O(f)</strong> refers to the Big-O simplified mathematical <strong>f</strong>unction</li>
                </ul>
                <h3 id="simplifying-a-product">Simplifying a Product</h3>
                <p>If a function consists of a product of many factors, we drop the factors that don't depend on the
                    size of the
                    input, n. The factors that we drop are called constant factors because their size remains consistent
                    as we
                    increase the size of the input. The reasoning behind this simplification is that we make the input
                    large
                    enough,
                    the non-constant factors will overshadow the constant ones. Below are some examples:</p>
                <table>
                    <thead>
                        <tr class="header">
                            <th>Unsimplified</th>
                            <th>Big-O Simplified</th>
                        </tr>
                    </thead>
                    <tbody>
                        <tr class="odd">
                            <td>T( 5 * n<sup>2</sup> )</td>
                            <td>O( n<sup>2</sup> )</td>
                        </tr>
                        <tr class="even">
                            <td>T( 100000 * n )</td>
                            <td>O( n )</td>
                        </tr>
                        <tr class="odd">
                            <td>T( n / 12 )</td>
                            <td>O( n )</td>
                        </tr>
                        <tr class="even">
                            <td>T( 42 * n * log(n) )</td>
                            <td>O( n * log(n) )</td>
                        </tr>
                        <tr class="odd">
                            <td>T( 12 )</td>
                            <td>O( 1 )</td>
                        </tr>
                    </tbody>
                </table>
                <p>Note that in the third example, we can simplify <code class="language-javascript  highlight"
                        id="button">T( n / 12 )</code> to <code class="language-javascript  highlight" id="button">O( n
                        )</code>
                    because we
                    can
                    rewrite a division into an equivalent multiplication. In other words, <code
                        class="language-javascript  highlight" id="button">T( n / 12 ) = T( 1/12 *
                        n ) = O(
                        n
                        )</code>.</p>
                <h3 id="simplifying-a-sum">Simplifying a Sum</h3>
                <p>If the function consists of a sum of many terms, we only need to show the term that grows the
                    fastest,
                    relative
                    to the size of the input. The reasoning behind this simplification is that if we make the input
                    large
                    enough,
                    the fastest growing term will overshadow the other, smaller terms. To understand which term to keep,
                    you'll
                    need
                    to recall the relative size of our common math terms from the previous section. Below are some
                    examples:</p>
                <table>
                    <thead>
                        <tr class="header">
                            <th>Unsimplified</th>
                            <th>Big-O Simplified</th>
                        </tr>
                    </thead>
                    <tbody>
                        <tr class="odd">
                            <td>T( n<sup>3</sup> + n<sup>2</sup> + n )</td>
                            <td>O( n<sup>3</sup> )</td>
                        </tr>
                        <tr class="even">
                            <td>T( log(n) + 2<sup>n</sup> )</td>
                            <td>O( 2<sup>n</sup> )</td>
                        </tr>
                        <tr class="odd">
                            <td>T( n + log(n) )</td>
                            <td>O( n )</td>
                        </tr>
                        <tr class="even">
                            <td>T( n! + 10<sup>n</sup> )</td>
                            <td>O( n! )</td>
                        </tr>
                    </tbody>
                </table>
                <h3 id="putting-it-all-together">Putting it all together</h3>
                <p>The <em>product</em> and <em>sum</em> rules are all we'll need to Big-O simplify any math functions.
                    We just
                    apply the <em>product rule</em> to drop all constants, then apply the <em>sum rule</em> to select
                    the single
                    most dominant term.</p>
                <table>
                    <thead>
                        <tr class="header">
                            <th>Unsimplified</th>
                            <th>Big-O Simplified</th>
                        </tr>
                    </thead>
                    <tbody>
                        <tr class="odd">
                            <td>T( 5n<sup>2</sup> + 99n )</td>
                            <td>O( n<sup>2</sup> )</td>
                        </tr>
                        <tr class="even">
                            <td>T( 2n + nlog(n) )</td>
                            <td>O( nlog(n) )</td>
                        </tr>
                        <tr class="odd">
                            <td>T( 2<sup>n</sup> + 5n<sup>1000</sup>)</td>
                            <td>O( 2<sup>n</sup> )</td>
                        </tr>
                    </tbody>
                </table>
                <blockquote>
                    <p>Aside: We'll often omit the multiplication symbol in expressions as a form of shorthand. For
                        example,
                        we'll
                        write <em>O( 5n<sup>2</sup> )</em> in place of <em>O( 5 * n<sup>2</sup> )</em>.</p>
                </blockquote>
                <h2 id="what-youve-learned">RECAP</h2>
                <p></p>
                <ul>
                    <li>explained why Big-O is the preferred notation used to describe the efficiency of algorithms</li>
                    <li>used the product and sum rules to simplify mathematical functions into Big-O notation</li>
                </ul>
                <hr />
                <h1 id="common-complexity-classes">Common Complexity Classes</h1>
                <p>Analyzing the efficiency of our code seems like a daunting task because there are many different
                    possibilities in
                    how we may choose to implement something. Luckily, most code we write can be categorized into one of
                    a
                    handful
                    of common complexity classes. In this reading, we'll identify the common classes and explore some of
                    the
                    code
                    characteristics that will lead to these classes.</p>
                <p>When you finish this reading, you should be able to:</p>
                <ul>
                    <li>name <em>and</em> order the seven common complexity classes</li>
                    <li>identify the time complexity class of a given code snippet</li>
                </ul>
                <h2 id="the-seven-major-classes">The seven major classes</h2>
                <p>There are seven complexity classes that we will encounter most often. Below is a list of each
                    complexity
                    class as
                    well as its Big-O notation. This list is ordered from <em>smallest to largest</em>. Bear in mind
                    that a
                    "more
                    efficient" algorithm is one with a smaller complexity class, because it requires fewer resources.
                </p>
                <table>
                    <thead>
                        <tr class="header">
                            <th>Big-O</th>
                            <th>Complexity Class Name</th>
                        </tr>
                    </thead>
                    <tbody>
                        <tr class="odd">
                            <td>O(1)</td>
                            <td>constant</td>
                        </tr>
                        <tr class="even">
                            <td>O(log(n))</td>
                            <td>logarithmic</td>
                        </tr>
                        <tr class="odd">
                            <td>O(n)</td>
                            <td>linear</td>
                        </tr>
                        <tr class="even">
                            <td>O(n * log(n))</td>
                            <td>loglinear, linearithmic, quasilinear</td>
                        </tr>
                        <tr class="odd">
                            <td>O(n<sup>c</sup>) - O(n<sup>2</sup>), O(n<sup>3</sup>), etc.</td>
                            <td>polynomial</td>
                        </tr>
                        <tr class="even">
                            <td>O(c<sup>n</sup>) - O(2<sup>n</sup>), O(3<sup>n</sup>), etc.</td>
                            <td>exponential</td>
                        </tr>
                        <tr class="odd">
                            <td>O(n!)</td>
                            <td>factorial</td>
                        </tr>
                    </tbody>
                </table>
                <p>There are more complexity classes that exist, but these are most common. Let's take a closer look at
                    each of
                    these classes to gain some intuition on what behavior their functions define. We'll explore famous
                    algorithms
                    that correspond to these classes further in the course.</p>
                <p>For simplicity, we'll provide small, generic code examples that illustrate the complexity, although
                    they may
                    not
                    solve a practical problem.</p>
                <h3 id="o1---constant">O(1) - Constant</h3>
                <p>Constant complexity means that the algorithm takes roughly the same number of steps for any size
                    input. In a
                    constant time algorithm, there is no relationship between the size of the input and the number of
                    steps
                    required. For example, this means performing the algorithm on a input of size 1 takes the same
                    number of
                    steps
                    as performing it on an input of size 128.</p>
                <h4 id="constant-growth">Constant growth</h4>
                <p>The table below shows the growing behavior of a constant function. Notice that the behavior stays
                    <em>constant</em> for all values of n.
                </p>
                <table>
                    <thead>
                        <tr class="header">
                            <th>n</th>
                            <th>O(1)</th>
                        </tr>
                    </thead>
                    <tbody>
                        <tr class="odd">
                            <td>1</td>
                            <td>~1</td>
                        </tr>
                        <tr class="even">
                            <td>2</td>
                            <td>~1</td>
                        </tr>
                        <tr class="odd">
                            <td>3</td>
                            <td>~1</td>
                        </tr>
                        <tr class="even">
                            <td>…</td>
                            <td>…</td>
                        </tr>
                        <tr class="odd">
                            <td>128</td>
                            <td>~1</td>
                        </tr>
                    </tbody>
                </table>
                <h4 id="example-constant-code">Example Constant code</h4>
                <p>Below is are two examples of functions that have constant runtimes.</p>
                <div class="sourceCode" id="cb1">
                    <pre data-filter-output="(out)" class="sourceCode javascript" class="sourceCode javascript"><code  class="language-javascript  highlight" id="button" class="sourceCode javascript"><a class="sourceLine" id="cb1-1" title="1"><span class="co">// O(1)</span></a>
<a class="sourceLine" id="cb1-2" title="2"><span class="kw">function</span> <span class="at">constant1</span>(n) <span class="op">{</span></a>
<a class="sourceLine" id="cb1-3" title="3">  <span class="cf">return</span> n <span class="op">*</span> <span class="dv">2</span> <span class="op">+</span> <span class="dv">1</span><span class="op">;</span></a>
<a class="sourceLine" id="cb1-4" title="4"><span class="op">}</span></a>
<a class="sourceLine" id="cb1-5" title="5"></a>
<a class="sourceLine" id="cb1-6" title="6"><span class="co">// O(1)</span></a>
<a class="sourceLine" id="cb1-7" title="7"><span class="kw">function</span> <span class="at">constant2</span>(n) <span class="op">{</span></a>
<a class="sourceLine" id="cb1-8" title="8">  <span class="cf">for</span> (<span class="kw">let</span> i <span class="op">=</span> <span class="dv">1</span><span class="op">;</span> i <span class="op">&lt;=</span> <span class="dv">100</span><span class="op">;</span> i<span class="op">++</span>) <span class="op">{</span></a>
<a class="sourceLine" id="cb1-9" title="9">    <span class="va">console</span>.<span class="at">log</span>(i)<span class="op">;</span></a>
<a class="sourceLine" id="cb1-10" title="10">  <span class="op">}</span></a>
<a class="sourceLine" id="cb1-11" title="11"><span class="op">}</span></a></code></pre>
                </div>
                <p>The runtime of the <code class="language-javascript  highlight" id="button">constant1</code> function
                    does not depend on the size of the input, because
                    only two
                    arithmetic operations (multiplication and addition) are always performed. The runtime of the
                    <code class="language-javascript  highlight" id="button">constant2</code> function also does not
                    depend on the size of the input because one-hundred
                    iterations
                    are
                    always performed, irrespective of the input.
                </p>
                <h3 id="ologn---logarithmic">O(log(n)) - Logarithmic</h3>
                <p>Typically, the hidden base of O(log(n)) is 2, meaning O(log<sub>2</sub>(n)). Logarithmic complexity
                    algorithms
                    will usual display a sense of continually "halving" the size of the input. Another tell of a
                    logarithmic
                    algorithm is that we don't have to access every element of the input. O(log<sub>2</sub>(n)) means
                    that every
                    time we double the size of the input, we only require one additional step. Overall, this means that
                    a large
                    increase of input size will increase the number of steps required by a small amount.</p>
                <h4 id="logarithmic-growth">Logarithmic growth</h4>
                <p>The table below shows the growing behavior of a logarithmic runtime function. Notice that doubling
                    the input
                    size
                    will only require only one additional "step".</p>
                <table>
                    <thead>
                        <tr class="header">
                            <th>n</th>
                            <th>O(log<sub>2</sub>(n))</th>
                        </tr>
                    </thead>
                    <tbody>
                        <tr class="odd">
                            <td>2</td>
                            <td>~1</td>
                        </tr>
                        <tr class="even">
                            <td>4</td>
                            <td>~2</td>
                        </tr>
                        <tr class="odd">
                            <td>8</td>
                            <td>~3</td>
                        </tr>
                        <tr class="even">
                            <td>16</td>
                            <td>~4</td>
                        </tr>
                        <tr class="odd">
                            <td>…</td>
                            <td>…</td>
                        </tr>
                        <tr class="even">
                            <td>128</td>
                            <td>~7</td>
                        </tr>
                    </tbody>
                </table>
                <h4 id="example-logarithmic-code">Example logarithmic code</h4>
                <p>Below is an example of two functions with logarithmic runtimes.</p>
                <div class="sourceCode" id="cb2">
                    <pre data-filter-output="(out)" class="sourceCode javascript" class="sourceCode javascript"><code  class="language-javascript  highlight" id="button" class="sourceCode javascript"><a class="sourceLine" id="cb2-1" title="1"><span class="co">// O(log(n))</span></a>
<a class="sourceLine" id="cb2-2" title="2"><span class="kw">function</span> <span class="at">logarithmic1</span>(n) <span class="op">{</span></a>
<a class="sourceLine" id="cb2-3" title="3">  <span class="cf">if</span> (n <span class="op">&lt;=</span> <span class="dv">1</span>) <span class="cf">return</span><span class="op">;</span></a>
<a class="sourceLine" id="cb2-4" title="4">  <span class="at">logarithmic1</span>(n / <span class="dv">2</span>)<span class="op">;</span></a>
<a class="sourceLine" id="cb2-5" title="5"><span class="op">}</span></a>
<a class="sourceLine" id="cb2-6" title="6"></a>
<a class="sourceLine" id="cb2-7" title="7"><span class="co">// O(log(n))</span></a>
<a class="sourceLine" id="cb2-8" title="8"><span class="kw">function</span> <span class="at">logarithmic2</span>(n) <span class="op">{</span></a>
<a class="sourceLine" id="cb2-9" title="9">  <span class="kw">let</span> i <span class="op">=</span> n<span class="op">;</span></a>
<a class="sourceLine" id="cb2-10" title="10">  <span class="cf">while</span> (i <span class="op">&gt;</span> <span class="dv">1</span>) <span class="op">{</span></a>
<a class="sourceLine" id="cb2-11" title="11">    i /<span class="op">=</span> <span class="dv">2</span><span class="op">;</span></a>
<a class="sourceLine" id="cb2-12" title="12">  <span class="op">}</span></a>
<a class="sourceLine" id="cb2-13" title="13"><span class="op">}</span></a></code></pre>
                </div>
                <p>The <code class="language-javascript  highlight" id="button">logarithmic1</code> function has
                    O(log(n)) runtime because the recursion will half the
                    argument, n,
                    each time. In other words, if we pass 8 as the original argument, then the recursive chain would be
                    8 -&gt;
                    4
                    -&gt; 2 -&gt; 1. In a similar way, the <code class="language-javascript  highlight"
                        id="button">logarithmic2</code> function has O(log(n)) runtime
                    because of
                    the
                    number of iterations in the while loop. The while loop depends on the variable <code
                        class="language-javascript  highlight" id="button">i</code>, which
                    will be
                    divided in half each iteration.</p>
                <h3 id="on---linear">O(n) - Linear</h3>
                <p>Linear complexity algorithms will access each item of the input "once" (in the Big-O sense).
                    Algorithms that
                    iterate through the input without nested loops or recurse by reducing the size of the input by "one"
                    each
                    time
                    are typically linear.</p>
                <h4 id="linear-growth">Linear growth</h4>
                <p>The table below shows the growing behavior of a linear runtime function. Notice that a change in
                    input size
                    leads
                    to similar change in the number of steps.</p>
                <table>
                    <thead>
                        <tr class="header">
                            <th>n</th>
                            <th>O(n)</th>
                        </tr>
                    </thead>
                    <tbody>
                        <tr class="odd">
                            <td>1</td>
                            <td>~1</td>
                        </tr>
                        <tr class="even">
                            <td>2</td>
                            <td>~2</td>
                        </tr>
                        <tr class="odd">
                            <td>3</td>
                            <td>~3</td>
                        </tr>
                        <tr class="even">
                            <td>4</td>
                            <td>~4</td>
                        </tr>
                        <tr class="odd">
                            <td>…</td>
                            <td>…</td>
                        </tr>
                        <tr class="even">
                            <td>128</td>
                            <td>~128</td>
                        </tr>
                    </tbody>
                </table>
                <h4 id="example-linear-code">Example linear code</h4>
                <p>Below are examples of three functions that each have linear runtime.</p>
                <div class="sourceCode" id="cb3">
                    <pre data-filter-output="(out)" class="sourceCode javascript" class="sourceCode javascript"><code  class="language-javascript  highlight" id="button" class="sourceCode javascript"><a class="sourceLine" id="cb3-1" title="1"><span class="co">// O(n)</span></a>
<a class="sourceLine" id="cb3-2" title="2"><span class="kw">function</span> <span class="at">linear1</span>(n) <span class="op">{</span></a>
<a class="sourceLine" id="cb3-3" title="3">  <span class="cf">for</span> (<span class="kw">let</span> i <span class="op">=</span> <span class="dv">1</span><span class="op">;</span> i <span class="op">&lt;=</span> n<span class="op">;</span> i<span class="op">++</span>) <span class="op">{</span></a>
<a class="sourceLine" id="cb3-4" title="4">    <span class="va">console</span>.<span class="at">log</span>(i)<span class="op">;</span></a>
<a class="sourceLine" id="cb3-5" title="5">  <span class="op">}</span></a>
<a class="sourceLine" id="cb3-6" title="6"><span class="op">}</span></a>
<a class="sourceLine" id="cb3-7" title="7"></a>
<a class="sourceLine" id="cb3-8" title="8"><span class="co">// O(n), where n is the length of the array</span></a>
<a class="sourceLine" id="cb3-9" title="9"><span class="kw">function</span> <span class="at">linear2</span>(array) <span class="op">{</span></a>
<a class="sourceLine" id="cb3-10" title="10">  <span class="cf">for</span> (<span class="kw">let</span> i <span class="op">=</span> <span class="dv">0</span><span class="op">;</span> i <span class="op">&lt;</span> <span class="va">array</span>.<span class="at">length</span><span class="op">;</span> i<span class="op">++</span>) <span class="op">{</span></a>
<a class="sourceLine" id="cb3-11" title="11">    <span class="va">console</span>.<span class="at">log</span>(i)<span class="op">;</span></a>
<a class="sourceLine" id="cb3-12" title="12">  <span class="op">}</span></a>
<a class="sourceLine" id="cb3-13" title="13"><span class="op">}</span></a>
<a class="sourceLine" id="cb3-14" title="14"></a>
<a class="sourceLine" id="cb3-15" title="15"><span class="co">// O(n)</span></a>
<a class="sourceLine" id="cb3-16" title="16"><span class="kw">function</span> <span class="at">linear3</span>(n) <span class="op">{</span></a>
<a class="sourceLine" id="cb3-17" title="17">  <span class="cf">if</span> (n <span class="op">===</span> <span class="dv">1</span>) <span class="cf">return</span><span class="op">;</span></a>
<a class="sourceLine" id="cb3-18" title="18">  <span class="at">linear3</span>(n <span class="op">-</span> <span class="dv">1</span>)<span class="op">;</span></a>
<a class="sourceLine" id="cb3-19" title="19"><span class="op">}</span></a></code></pre>
                </div>
                <p>The <code class="language-javascript  highlight" id="button">linear1</code> function has O(n) runtime
                    because the for loop will iterate n times. The
                    <code class="language-javascript  highlight" id="button">linear2</code> function has O(n) runtime
                    because the for loop iterates through the array
                    argument. The
                    <code class="language-javascript  highlight" id="button">linear3</code> function has O(n) runtime
                    because each subsequent call in the recursion will
                    decrease
                    the
                    argument by one. In other words, if we pass 8 as the original argument to <code
                        class="language-javascript  highlight" id="button">linear3</code>, the
                    recursive
                    chain would be 8 -&gt; 7 -&gt; 6 -&gt; 5 -&gt; … -&gt; 1.
                </p>
                <h3 id="on-logn---loglinear">O(n * log(n)) - Loglinear</h3>
                <p>This class is a combination of both linear and logarithmic behavior, so features from both classes
                    are
                    evident.
                    Algorithms the exhibit this behavior use both recursion and iteration. Typically, this means that
                    the
                    recursive
                    calls will halve the input each time (logarithmic), but iterations are also performed on the input
                    (linear).
                </p>
                <h4 id="loglinear-growth">Loglinear growth</h4>
                <p>The table below shows the growing behavior of a loglinear runtime function.</p>
                <table>
                    <thead>
                        <tr class="header">
                            <th>n</th>
                            <th>O(n * log<sub>2</sub>(n))</th>
                        </tr>
                    </thead>
                    <tbody>
                        <tr class="odd">
                            <td>2</td>
                            <td>~2</td>
                        </tr>
                        <tr class="even">
                            <td>4</td>
                            <td>~8</td>
                        </tr>
                        <tr class="odd">
                            <td>8</td>
                            <td>~24</td>
                        </tr>
                        <tr class="even">
                            <td>…</td>
                            <td>…</td>
                        </tr>
                        <tr class="odd">
                            <td>128</td>
                            <td>~896</td>
                        </tr>
                    </tbody>
                </table>
                <h4 id="example-loglinear-code">Example loglinear code</h4>
                <p>Below is an example of a function with a loglinear runtime.</p>
                <div class="sourceCode" id="cb4">
                    <pre data-filter-output="(out)" class="sourceCode javascript" class="sourceCode javascript"><code  class="language-javascript  highlight" id="button" class="sourceCode javascript"><a class="sourceLine" id="cb4-1" title="1"><span class="co">// O(n * log(n))</span></a>
<a class="sourceLine" id="cb4-2" title="2"><span class="kw">function</span> <span class="at">loglinear</span>(n) <span class="op">{</span></a>
<a class="sourceLine" id="cb4-3" title="3">  <span class="cf">if</span> (n <span class="op">&lt;=</span> <span class="dv">1</span>) <span class="cf">return</span><span class="op">;</span></a>
<a class="sourceLine" id="cb4-4" title="4"></a>
<a class="sourceLine" id="cb4-5" title="5">  <span class="cf">for</span> (<span class="kw">let</span> i <span class="op">=</span> <span class="dv">1</span><span class="op">;</span> i <span class="op">&lt;=</span> n<span class="op">;</span> i<span class="op">++</span>) <span class="op">{</span></a>
<a class="sourceLine" id="cb4-6" title="6">    <span class="va">console</span>.<span class="at">log</span>(i)<span class="op">;</span></a>
<a class="sourceLine" id="cb4-7" title="7">  <span class="op">}</span></a>
<a class="sourceLine" id="cb4-8" title="8"></a>
<a class="sourceLine" id="cb4-9" title="9">  <span class="at">loglinear</span>(n / <span class="dv">2</span>)<span class="op">;</span></a>
<a class="sourceLine" id="cb4-10" title="10">  <span class="at">loglinear</span>(n / <span class="dv">2</span>)<span class="op">;</span></a>
<a class="sourceLine" id="cb4-11" title="11"><span class="op">}</span></a></code></pre>
                </div>
                <p>The <code class="language-javascript  highlight" id="button">loglinear</code> function has O(n *
                    log(n)) runtime because the for loop iterates linearly
                    (n)
                    through
                    the input and the recursive chain behaves logarithmically (log(n)).</p>
                <h3 id="onc---polynomial">O(n<sup>c</sup>) - Polynomial</h3>
                <p>Polynomial complexity refers to complexity of the form O(n<sup>c</sup>) where <code
                        class="language-javascript  highlight" id="button">n</code> is the
                    size of
                    the
                    input and <code class="language-javascript  highlight" id="button">c</code> is some fixed constant.
                    For example, O(n<sup>3</sup>) is a larger/worse
                    function
                    than
                    O(n<sup>2</sup>), but they belong to the same complexity class. Nested loops are usually the
                    indicator of
                    this
                    complexity class.</p>
                <h4 id="polynomial-growth">Polynomial growth</h4>
                <p>Below are tables showing the growth for O(n<sup>2</sup>) and O(n<sup>3</sup>).</p>
                <table>
                    <thead>
                        <tr class="header">
                            <th>n</th>
                            <th>O(n<sup>2</sup>)</th>
                        </tr>
                    </thead>
                    <tbody>
                        <tr class="odd">
                            <td>1</td>
                            <td>~1</td>
                        </tr>
                        <tr class="even">
                            <td>2</td>
                            <td>~4</td>
                        </tr>
                        <tr class="odd">
                            <td>3</td>
                            <td>~9</td>
                        </tr>
                        <tr class="even">
                            <td>…</td>
                            <td>…</td>
                        </tr>
                        <tr class="odd">
                            <td>128</td>
                            <td>~16,384</td>
                        </tr>
                    </tbody>
                </table>
                <table>
                    <thead>
                        <tr class="header">
                            <th>n</th>
                            <th>O(n<sup>3</sup>)</th>
                        </tr>
                    </thead>
                    <tbody>
                        <tr class="odd">
                            <td>1</td>
                            <td>~1</td>
                        </tr>
                        <tr class="even">
                            <td>2</td>
                            <td>~8</td>
                        </tr>
                        <tr class="odd">
                            <td>3</td>
                            <td>~27</td>
                        </tr>
                        <tr class="even">
                            <td>…</td>
                            <td>…</td>
                        </tr>
                        <tr class="odd">
                            <td>128</td>
                            <td>~2,097,152</td>
                        </tr>
                    </tbody>
                </table>
                <h4 id="example-polynomial-code">Example polynomial code</h4>
                <p>Below are examples of two functions with polynomial runtimes.</p>
                <div class="sourceCode" id="cb5">
                    <pre data-filter-output="(out)" class="sourceCode javascript" class="sourceCode javascript"><code  class="language-javascript  highlight" id="button" class="sourceCode javascript"><a class="sourceLine" id="cb5-1" title="1"><span class="co">// O(n^2)</span></a>
<a class="sourceLine" id="cb5-2" title="2"><span class="kw">function</span> <span class="at">quadratic</span>(n) <span class="op">{</span></a>
<a class="sourceLine" id="cb5-3" title="3">  <span class="cf">for</span> (<span class="kw">let</span> i <span class="op">=</span> <span class="dv">1</span><span class="op">;</span> i <span class="op">&lt;=</span> n<span class="op">;</span> i<span class="op">++</span>) <span class="op">{</span></a>
<a class="sourceLine" id="cb5-4" title="4">    <span class="cf">for</span> (<span class="kw">let</span> j <span class="op">=</span> <span class="dv">1</span><span class="op">;</span> j <span class="op">&lt;=</span> n<span class="op">;</span> j<span class="op">++</span>) <span class="op">{}</span></a>
<a class="sourceLine" id="cb5-5" title="5">  <span class="op">}</span></a>
<a class="sourceLine" id="cb5-6" title="6"><span class="op">}</span></a>
<a class="sourceLine" id="cb5-7" title="7"></a>
<a class="sourceLine" id="cb5-8" title="8"><span class="co">// O(n^3)</span></a>
<a class="sourceLine" id="cb5-9" title="9"><span class="kw">function</span> <span class="at">cubic</span>(n) <span class="op">{</span></a>
<a class="sourceLine" id="cb5-10" title="10">  <span class="cf">for</span> (<span class="kw">let</span> i <span class="op">=</span> <span class="dv">1</span><span class="op">;</span> i <span class="op">&lt;=</span> n<span class="op">;</span> i<span class="op">++</span>) <span class="op">{</span></a>
<a class="sourceLine" id="cb5-11" title="11">    <span class="cf">for</span> (<span class="kw">let</span> j <span class="op">=</span> <span class="dv">1</span><span class="op">;</span> j <span class="op">&lt;=</span> n<span class="op">;</span> j<span class="op">++</span>) <span class="op">{</span></a>
<a class="sourceLine" id="cb5-12" title="12">      <span class="cf">for</span> (<span class="kw">let</span> k <span class="op">=</span> <span class="dv">1</span><span class="op">;</span> k <span class="op">&lt;=</span> n<span class="op">;</span> k<span class="op">++</span>) <span class="op">{}</span></a>
<a class="sourceLine" id="cb5-13" title="13">    <span class="op">}</span></a>
<a class="sourceLine" id="cb5-14" title="14">  <span class="op">}</span></a>
<a class="sourceLine" id="cb5-15" title="15"><span class="op">}</span></a></code></pre>
                </div>
                <p>The <code class="language-javascript  highlight" id="button">quadratic</code> function has
                    O(n<sup>2</sup>) runtime because there are nested loops. The
                    outer
                    loop
                    iterates n times and the inner loop iterates n times. This leads to n * n total number of
                    iterations. In a
                    similar way, the <code class="language-javascript  highlight" id="button">cubic</code> function has
                    O(n<sup>3</sup>) runtime because it has triply
                    nested loops
                    that lead to a total of n * n * n iterations.</p>
                <h3 id="ocn---exponential">O(c<sup>n</sup>) - Exponential</h3>
                <p>Exponential complexity refers to Big-O functions of the form O(c<sup>n</sup>) where <code
                        class="language-javascript  highlight" id="button">n</code> is
                    the
                    size of
                    the input and <code class="language-javascript  highlight" id="button">c</code> is some fixed
                    constant. For example, O(3<sup>n</sup>) is a larger/worse
                    function
                    than O(2<sup>n</sup>), but they both belong to the exponential complexity class. A common indicator
                    of this
                    complexity class is recursive code where there is a constant number of recursive calls in each stack
                    frame.
                    The
                    <code class="language-javascript  highlight" id="button">c</code> will be the number of recursive
                    calls made in each stack frame. Algorithms with this
                    complexity
                    are considered quite slow.
                </p>
                <h4 id="exponential-growth">Exponential growth</h4>
                <p>Below are tables showing the growth for O(2<sup>n</sup>) and O(3<sup>n</sup>). Notice how these grow
                    large,
                    quickly.</p>
                <table>
                    <thead>
                        <tr class="header">
                            <th>n</th>
                            <th>O(2<sup>n</sup>)</th>
                        </tr>
                    </thead>
                    <tbody>
                        <tr class="odd">
                            <td>1</td>
                            <td>~2</td>
                        </tr>
                        <tr class="even">
                            <td>2</td>
                            <td>~4</td>
                        </tr>
                        <tr class="odd">
                            <td>3</td>
                            <td>~8</td>
                        </tr>
                        <tr class="even">
                            <td>4</td>
                            <td>~16</td>
                        </tr>
                        <tr class="odd">
                            <td>…</td>
                            <td>…</td>
                        </tr>
                        <tr class="even">
                            <td>128</td>
                            <td>~3.4028 * 10<sup>38</sup></td>
                        </tr>
                    </tbody>
                </table>
                <table>
                    <thead>
                        <tr class="header">
                            <th>n</th>
                            <th>O(3<sup>n</sup>)</th>
                        </tr>
                    </thead>
                    <tbody>
                        <tr class="odd">
                            <td>1</td>
                            <td>~3</td>
                        </tr>
                        <tr class="even">
                            <td>2</td>
                            <td>~9</td>
                        </tr>
                        <tr class="odd">
                            <td>3</td>
                            <td>~27</td>
                        </tr>
                        <tr class="even">
                            <td>3</td>
                            <td>~81</td>
                        </tr>
                        <tr class="odd">
                            <td>…</td>
                            <td>…</td>
                        </tr>
                        <tr class="even">
                            <td>128</td>
                            <td>~1.1790 * 10<sup>61</sup></td>
                        </tr>
                    </tbody>
                </table>
                <h4 id="exponential-code-example">Exponential code example</h4>
                <p>Below are examples of two functions with exponential runtimes.</p>
                <div class="sourceCode" id="cb6">
                    <pre data-filter-output="(out)" class="sourceCode javascript" class="sourceCode javascript"><code  class="language-javascript  highlight" id="button" class="sourceCode javascript"><a class="sourceLine" id="cb6-1" title="1"><span class="co">// O(2^n)</span></a>
<a class="sourceLine" id="cb6-2" title="2"><span class="kw">function</span> <span class="at">exponential2n</span>(n) <span class="op">{</span></a>
<a class="sourceLine" id="cb6-3" title="3">  <span class="cf">if</span> (n <span class="op">===</span> <span class="dv">1</span>) <span class="cf">return</span><span class="op">;</span></a>
<a class="sourceLine" id="cb6-4" title="4">  <span class="at">exponential_2n</span>(n <span class="op">-</span> <span class="dv">1</span>)<span class="op">;</span></a>
<a class="sourceLine" id="cb6-5" title="5">  <span class="at">exponential_2n</span>(n <span class="op">-</span> <span class="dv">1</span>)<span class="op">;</span></a>
<a class="sourceLine" id="cb6-6" title="6"><span class="op">}</span></a>
<a class="sourceLine" id="cb6-7" title="7"></a>
<a class="sourceLine" id="cb6-8" title="8"><span class="co">// O(3^n)</span></a>
<a class="sourceLine" id="cb6-9" title="9"><span class="kw">function</span> <span class="at">exponential3n</span>(n) <span class="op">{</span></a>
<a class="sourceLine" id="cb6-10" title="10">  <span class="cf">if</span> (n <span class="op">===</span> <span class="dv">0</span>) <span class="cf">return</span><span class="op">;</span></a>
<a class="sourceLine" id="cb6-11" title="11">  <span class="at">exponential_3n</span>(n <span class="op">-</span> <span class="dv">1</span>)<span class="op">;</span></a>
<a class="sourceLine" id="cb6-12" title="12">  <span class="at">exponential_3n</span>(n <span class="op">-</span> <span class="dv">1</span>)<span class="op">;</span></a>
<a class="sourceLine" id="cb6-13" title="13">  <span class="at">exponential_3n</span>(n <span class="op">-</span> <span class="dv">1</span>)<span class="op">;</span></a>
<a class="sourceLine" id="cb6-14" title="14"><span class="op">}</span></a></code></pre>
                </div>
                <p>The <code class="language-javascript  highlight" id="button">exponential2n</code> function has
                    O(2<sup>n</sup>) runtime because each call will make two
                    more
                    recursive calls. The <code class="language-javascript  highlight" id="button">exponential3n</code>
                    function has O(3<sup>n</sup>) runtime because each
                    call will
                    make three more recursive calls.</p>
                <h3 id="on---factorial">O(n!) - Factorial</h3>
                <p>Recall that <code class="language-javascript  highlight" id="button">n! = (n) * (n - 1) * (n - 2) *
                        ... * 1</code>. This complexity is typically the
                    largest/worst
                    that we will end up implementing. An indicator of this complexity class is recursive code that has a
                    variable
                    number of recursive calls in each stack frame. Note that <em>factorial</em> is worse than
                    <em>exponential</em>
                    because <em>factorial</em> algorithms have a <em>variable</em> amount of recursive calls in each
                    stack
                    frame,
                    whereas <em>exponential</em> algorithms have a <em>constant</em> amount of recursive calls in each
                    frame.
                </p>
                <h4 id="factorial-growth">Factorial growth</h4>
                <p>Below is a table showing the growth for O(n!). Notice how this has a more aggressive growth than
                    exponential
                    behavior.</p>
                <table>
                    <thead>
                        <tr class="header">
                            <th>n</th>
                            <th>O(n!)</th>
                        </tr>
                    </thead>
                    <tbody>
                        <tr class="odd">
                            <td>1</td>
                            <td>~1</td>
                        </tr>
                        <tr class="even">
                            <td>2</td>
                            <td>~2</td>
                        </tr>
                        <tr class="odd">
                            <td>3</td>
                            <td>~6</td>
                        </tr>
                        <tr class="even">
                            <td>4</td>
                            <td>~24</td>
                        </tr>
                        <tr class="odd">
                            <td>…</td>
                            <td>…</td>
                        </tr>
                        <tr class="even">
                            <td>128</td>
                            <td>~3.8562 * 10<sup>215</sup></td>
                        </tr>
                    </tbody>
                </table>
                <h4 id="factorial-code-example">Factorial code example</h4>
                <p>Below is an example of a function with factorial runtime.</p>
                <div class="sourceCode" id="cb7">
                    <pre data-filter-output="(out)" class="sourceCode javascript" class="sourceCode javascript"><code  class="language-javascript  highlight" id="button" class="sourceCode javascript"><a class="sourceLine" id="cb7-1" title="1"><span class="co">// O(n!)</span></a>
<a class="sourceLine" id="cb7-2" title="2"><span class="kw">function</span> <span class="at">factorial</span>(n) <span class="op">{</span></a>
<a class="sourceLine" id="cb7-3" title="3">  <span class="cf">if</span> (n <span class="op">===</span> <span class="dv">1</span>) <span class="cf">return</span><span class="op">;</span></a>
<a class="sourceLine" id="cb7-4" title="4"></a>
<a class="sourceLine" id="cb7-5" title="5">  <span class="cf">for</span> (<span class="kw">let</span> i <span class="op">=</span> <span class="dv">1</span><span class="op">;</span> i <span class="op">&lt;=</span> n<span class="op">;</span> i<span class="op">++</span>) <span class="op">{</span></a>
<a class="sourceLine" id="cb7-6" title="6">    <span class="at">factorial</span>(n <span class="op">-</span> <span class="dv">1</span>)<span class="op">;</span></a>
<a class="sourceLine" id="cb7-7" title="7">  <span class="op">}</span></a>
<a class="sourceLine" id="cb7-8" title="8"><span class="op">}</span></a></code></pre>
                </div>
                <p>The <code class="language-javascript  highlight" id="button">factorial</code> function has O(n!)
                    runtime because the code is <em>recursive</em> but the
                    number
                    of
                    recursive calls made in a single stack frame depends on the input. This contrasts with an
                    <em>exponential</em>
                    function because exponential functions have a <em>fixed</em> number of calls in each stack frame.
                </p>
                <p>You may it difficult to identify the complexity class of a given code snippet, especially if the code
                    falls
                    into
                    the loglinear, exponential, or factorial classes. In the upcoming videos, we'll explain the analysis
                    of
                    these
                    functions in greater detail. For now, you should focus on the <em>relative order</em> of these seven
                    complexity
                    classes!</p>
                <h2 id="what-youve-learned-1">RECAP</h2>
                <p>In this reading, we listed the seven common complexity classes and saw some example code for each. In
                    order
                    of
                    ascending growth, the seven classes are:</p>
                <ol type="1">
                    <li>Constant</li>
                    <li>Logarithmic</li>
                    <li>Linear</li>
                    <li>Loglinear</li>
                    <li>Polynomial</li>
                    <li>Exponential</li>
                    <li>Factorial</li>
                </ol>
                <hr />
                <hr>
                
                
                
                
                  <h2 id="linear-recursion">Self-Similarity</h2>
                  <blockquote>
                      <p>Recursion is the root of computation since it trades description for time.—Alan Perlis, <a
                              href="http://www.cs.yale.edu/homes/perlis-alan/quotes.html">Epigrams in Programming</a>
                      </p>
                  </blockquote>
                  <p>In <a href="#arraysanddestructuring">Arrays and Destructuring Arguments</a>, we worked with the
                      basic idea that
                      putting an array together with a literal array expression was the reverse or opposite of taking it
                      apart with a
                      destructuring assignment.</p>
                  <p>We saw that the basic idea that putting an array together with a literal array expression was the
                      reverse or
                      opposite of taking it apart with a destructuring assignment.</p>
                  <p>Let's be more specific. Some data structures, like lists, can obviously be seen as a collection of
                      items. Some
                      are empty, some have three items, some forty-two, some contain numbers, some contain strings, some
                      a mixture of
                      elements, there are all kinds of lists.</p>
                  <p>But we can also define a list by describing a rule for building lists. One of the simplest, and
                      longest-standing
                      in computer science, is to say that a list is:</p>
                  <ol start="0" type="1">
                      <li>Empty, or;</li>
                      <li>Consists of an element concatenated with a list .</li>
                  </ol>
                  <p>Let's convert our rules to array literals. The first rule is simple: <code
                          class="language-javascript">[]</code>
                      is a list. How about the
                      second rule? We can express that using a spread. Given an element <code
                          class="language-javascript">e</code> and
                      a list <code class="language-javascript">list</code> ,
                      <code class="language-javascript">[e, ...list]</code> is a list. We can test this manually by
                      building up a
                      list:
                  </p>
                  <pre data-filter-output="(out)" data-role="codeBlock" data-info="js"
                      class="language-javascript data-line line-numbers data-user data-host data-prompt data-output"
                      data-prismjs-copy="Copy !" data-download-link />
                  <code class="language-javascript">[]
                      //=&gt; []

                      [&quot;baz&quot;, ...[]]
                      //=&gt; [&quot;baz&quot;]

                      [&quot;bar&quot;, ...[&quot;baz&quot;]]
                      //=&gt; [&quot;bar&quot;,&quot;baz&quot;]

                      [&quot;foo&quot;, ...[&quot;bar&quot;, &quot;baz&quot;]]
                      //=&gt; [&quot;foo&quot;,&quot;bar&quot;,&quot;baz&quot;]</code></pre>
                  <p>Thanks to the parallel between array literals + spreads with destructuring + rests, we can also use
                      the same
                      rules to decompose lists:</p>
                  <pre data-filter-output="(out)" data-role="codeBlock" data-info="js"
                      class="language-javascript data-line line-numbers data-user data-host data-prompt data-output"
                      data-prismjs-copy="Copy !" data-download-link />
                  <code class="language-javascript">const [first, ...rest] = [];
                      first
                      //=&gt; undefined
                      rest
                      //=&gt; []:

                      const [first, ...rest] = [&quot;foo&quot;];
                      first
                      //=&gt; &quot;foo&quot;
                      rest
                      //=&gt; []

                      const [first, ...rest] = [&quot;foo&quot;, &quot;bar&quot;];
                      first
                      //=&gt; &quot;foo&quot;
                      rest
                      //=&gt; [&quot;bar&quot;]

                      const [first, ...rest] = [&quot;foo&quot;, &quot;bar&quot;, &quot;baz&quot;];
                      first
                      //=&gt; &quot;foo&quot;
                      rest
                      //=&gt; [&quot;bar&quot;,&quot;baz&quot;]</code></pre>
                  <p>For the purpose of this exploration, we will presume the following:<a href="#fn1"
                          class="footnote-ref" id="fnref1"><sup>1</sup></a></p>
                  <pre data-filter-output="(out)" data-role="codeBlock" data-info="js"
                      class="language-javascript data-line line-numbers data-user data-host data-prompt data-output"
                      data-prismjs-copy="Copy !" data-download-link />
                  <code class="language-javascript">const isEmpty = ([first, ...rest]) =&gt; first === undefined;

                      isEmpty([])
                      //=&gt; true

                      isEmpty([0])
                      //=&gt; false

                      isEmpty([[]])
                      //=&gt; false</code></pre>
                  <p>Armed with our definition of an empty list and with what we've already learned, we can build a
                      great many
                      functions that operate on arrays. We know that we can get the length of an array using its <code
                          class="language-javascript">.length</code>
                      . But as an exercise, how would we write a <code class="language-javascript">length</code>
                      function using just
                      what we have already?</p>
                  <p>First, we pick what we call a <em>terminal case</em>. What is the length of an empty array? <code
                          class="language-javascript">0</code> . So
                      let's start our function with the observation that if an array is empty, the length is <code
                          class="language-javascript">0</code> :</p>
                  <pre data-filter-output="(out)" data-role="codeBlock" data-info="js"
                      class="language-javascript data-line line-numbers data-user data-host data-prompt data-output"
                      data-prismjs-copy="Copy !" data-download-link />
                  <code class="language-javascript">const length = ([first, ...rest]) =&gt;
                      first === undefined
                      ? 0
                      : // ???</code></pre>
                  <p>We need something for when the array isn't empty. If an array is not empty, and we break it into
                      two pieces,
                      <code class="language-javascript">first</code> and <code class="language-javascript">rest</code> ,
                      the length of
                      our array is going to be <code class="language-javascript">length(first) +
                          length(rest)</code> . Well, the length of <code class="language-javascript">first</code> is
                      <code class="language-javascript">1</code> , there's just one element at
                      the front. But we don't know the length of <code class="language-javascript">rest</code> . If only
                      there was a
                      function we could call… Like
                      <code class="language-javascript">length</code> !
                  </p>
                  <pre data-filter-output="(out)" data-role="codeBlock" data-info="js"
                      class="language-javascript data-line line-numbers data-user data-host data-prompt data-output"
                      data-prismjs-copy="Copy !" data-download-link />
                  <code class="language-javascript">const length = ([first, ...rest]) =&gt;
                      first === undefined
                      ? 0
                      : 1 + length(rest); </code></pre>
                  <p>Let's try it!</p>
                  <pre data-filter-output="(out)" data-role="codeBlock" data-info="js"
                      class="language-javascript data-line line-numbers data-user data-host data-prompt data-output"
                      data-prismjs-copy="Copy !" data-download-link />
                  <code class="language-javascript">length([])
                      //=&gt; 0


                      length([&quot;foo&quot;])
                      //=&gt; 1


                      length([&quot;foo&quot;, &quot;bar&quot;, &quot;baz&quot;])
                      //=&gt; 3</code></pre>
                  <p>Our <code class="language-javascript">length</code> function is <em>recursive</em>, it calls
                      itself. This makes
                      sense because our definition
                      of a list is recursive, and if a list is self-similar, it is natural to create an algorithm that
                      is also
                      self-similar.</p>
                  <h3 id="linear-recursion-1">linear recursion</h3>
                  <p>"Recursion" sometimes seems like an elaborate party trick. There's even a joke about this:</p>
                  <blockquote>
                      <p>When promising students are trying to choose between pure mathematics and applied engineering,
                          they are given
                          a two-part aptitude test. In the first part, they are led to a laboratory bench and told to
                          follow the
                          instructions printed on the card. They find a bunsen burner, a sparker, a tap, an empty
                          beaker, a stand, and
                          a card with the instructions "boil water."</p>
                  </blockquote>
                  <blockquote>
                      <p>Of course, all the students know what to do: They fill the beaker with water, place the stand
                          on the burner
                          and the beaker on the stand, then they turn the burner on and use the sparker to ignite the
                          flame. After a
                          bit the water boils, and they turn off the burner and are lead to a second bench.</p>
                  </blockquote>
                  <blockquote>
                      <p>Once again, there is a card that reads, "boil water." But this time, the beaker is on the stand
                          over the
                          burner, as left behind by the previous student. The engineers light the burner immediately.
                          Whereas the
                          mathematicians take the beaker off the stand and empty it, thus reducing the situation to a
                          problem they
                          have already solved.</p>
                  </blockquote>
                  <p>There is more to recursive solutions that simply functions that invoke themselves. Recursive
                      algorithms follow
                      the "divide and conquer" strategy for solving a problem:</p>
                  <ol start="0" type="1">
                      <li>Divide the problem into smaller problems</li>
                      <li>If a smaller problem is solvable, solve the small problem</li>
                      <li>If a smaller problem is not solvable, divide and conquer that problem</li>
                      <li>When all small problems have been solved, compose the solutions into one big solution</li>
                  </ol>
                  <p>The big elements of divide and conquer are a method for decomposing a problem into smaller
                      problems, a test for
                      the smallest possible problem, and a means of putting the pieces back together. Our solutions are
                      a little
                      simpler in that we don't really break a problem down into multiple pieces, we break a piece off
                      the problem that
                      may or may not be solvable, and solve that before sticking it onto a solution for the rest of the
                      problem.</p>
                  <p>This simpler form of "divide and conquer" is called <em>linear recursion</em>. It's very useful and
                      simple to
                      understand. Let's take another example. Sometimes we want to <em>flatten</em> an array, that is,
                      an array of
                      arrays needs to be turned into one array of elements that aren't arrays.<a href="#fn2"
                          class="footnote-ref" id="fnref2"><sup>2</sup></a></p>
                  <p>We already know how to divide arrays into smaller pieces. How do we decide whether a smaller
                      problem is solvable?
                      We need a test for the terminal case. Happily, there is something along these lines provided for
                      us:</p>
                  <pre data-filter-output="(out)" data-role="codeBlock" data-info="js"
                      class="language-javascript data-line line-numbers data-user data-host data-prompt data-output"
                      data-prismjs-copy="Copy !" data-download-link />
                  <code class="language-javascript">Array.isArray(&quot;foo&quot;)
                      //=&gt; false

                      Array.isArray([&quot;foo&quot;])
                      //=&gt; true
                  </code></pre>
                  <p>The usual "terminal case" will be that flattening an empty array will produce an empty array. The
                      next terminal
                      case is that if an element isn't an array, we don't flatten it, and can put it together with the
                      rest of our
                      solution directly. Whereas if an element is an array, we'll flatten it and put it together with
                      the rest of our
                      solution.</p>
                  <p>So our first cut at a <code class="language-javascript">flatten</code> function will look like
                      this:</p>
                  <pre data-filter-output="(out)" data-role="codeBlock" data-info="js"
                      class="language-javascript data-line line-numbers data-user data-host data-prompt data-output"
                      data-prismjs-copy="Copy !" data-download-link />
                  <code class="language-javascript">const flatten = ([first, ...rest]) =&gt; {
                      if (first === undefined) {
                      return [];
                      }
                      else if (! Array.isArray(first)) {
                      return [first, ...flatten(rest)];
                      }
                      else {
                      return [...flatten(first), ...flatten(rest)];
                      }
                      }



                      flatten([&quot;foo&quot;, [3, 4, []]])
                      //=&gt; [&quot;foo&quot;, 3, 4]
                  </code></pre>
                  <p>Once again, the solution directly displays the important elements: Dividing a problem into
                      subproblems, detecting
                      terminal cases, solving the terminal cases, and composing a solution from the solved portions.</p>
                  <h3 id="mapping">mapping</h3>
                  <p>Another common problem is applying a function to every element of an array. JavaScript has a
                      built-in function
                      for this, but let's write our own using linear recursion.</p>
                  <p>If we want to square each number in a list, we could write:</p>
                  <pre data-filter-output="(out)" data-role="codeBlock" data-info="js"
                      class="language-javascript data-line line-numbers data-user data-host data-prompt data-output"
                      data-prismjs-copy="Copy !" data-download-link />
                  <code class="language-javascript">const squareAll = ([first, ...rest]) =&gt; first === undefined
                      ? []
                      : [first * first, ...squareAll(rest)];

                      squareAll([1, 2, 3, 4, 5])
                      //=&gt; [1,4,9,16,25]</code></pre>
                  <p>And if we wanted to "truthify" each element in a list, we could write:</p>
                  <pre data-filter-output="(out)" data-role="codeBlock" data-info="js"
                      class="language-javascript data-line line-numbers data-user data-host data-prompt data-output"
                      data-prismjs-copy="Copy !" data-download-link />
                  <code class="language-javascript">const truthyAll = ([first, ...rest]) =&gt; first === undefined
                      ? []
                      : [!!first, ...truthyAll(rest)];

                      truthyAll([null, true, 25, false, &quot;foo&quot;])
                      //=&gt; [false,true,true,false,true]
                  </code></pre>
                  <p>This specific case of linear recursion is called "mapping," and it is not necessary to constantly
                      write out the
                      same pattern again and again. Functions can take functions as arguments, so let's "extract" the
                      thing to do to
                      each element and separate it from the business of taking an array apart, doing the thing, and
                      putting the array
                      back together.</p>
                  <p>Given the signature:</p>
                  <pre data-filter-output="(out)" data-role="codeBlock" data-info="js"
                      class="language-javascript data-line line-numbers data-user data-host data-prompt data-output"
                      data-prismjs-copy="Copy !" data-download-link />
                  <code class="language-javascript">const mapWith = (fn, array) =&gt; // ...</code></pre>
                  <p>We can write it out using a ternary operator. Even in this small function, we can identify the
                      terminal
                      condition, the piece being broken off, and recomposing the solution.</p>
                  <pre data-filter-output="(out)" data-role="codeBlock" data-info="js"
                      class="language-javascript data-line line-numbers data-user data-host data-prompt data-output"
                      data-prismjs-copy="Copy !" data-download-link />
                  <code class="language-javascript">const mapWith = (fn, [first, ...rest]) =&gt;
                      first === undefined
                      ? []
                      : [fn(first), ...mapWith(fn, rest)];

                      mapWith((x) =&gt; x * x, [1, 2, 3, 4, 5])
                      //=&gt; [1,4,9,16,25]

                      mapWith((x) =&gt; !!x, [null, true, 25, false, &quot;foo&quot;])
                      //=&gt; [false,true,true,false,true]</code></pre>
                  <h3 id="folding">folding</h3>
                  <p>With the exception of the <code class="language-javascript">length</code> example at the beginning,
                      our examples
                      so far all involve
                      rebuilding a solution using spreads. But they needn't. A function to compute the sum of the
                      squares of a list of
                      numbers might look like this:</p>
                  <pre data-filter-output="(out)" data-role="codeBlock" data-info="js"
                      class="language-javascript data-line line-numbers data-user data-host data-prompt data-output"
                      data-prismjs-copy="Copy !" data-download-link />
                  <code class="language-javascript">const sumSquares = ([first, ...rest]) =&gt; first === undefined
                      ? 0
                      : first * first + sumSquares(rest);

                      sumSquares([1, 2, 3, 4, 5])
                      //=&gt; 55</code></pre>
                  <p>There are two differences between <code class="language-javascript">sumSquares</code> and our maps
                      above:</p>
                  <ol start="0" type="1">
                      <li>Given the terminal case of an empty list, we return a <code
                              class="language-javascript">0</code> instead of
                          an empty list, and;</li>
                      <li>We catenate the square of each element to the result of applying <code
                              class="language-javascript">sumSquares</code> to the rest of the
                          elements.</li>
                  </ol>
                  <p>Let's rewrite <code class="language-javascript">mapWith</code> so that we can use it to sum
                      squares.</p>
                  <pre data-filter-output="(out)" data-role="codeBlock" data-info="js"
                      class="language-javascript data-line line-numbers data-user data-host data-prompt data-output"
                      data-prismjs-copy="Copy !" data-download-link />
                  <code class="language-javascript">const foldWith = (fn, terminalValue, [first, ...rest]) =&gt;
                      first === undefined
                      ? terminalValue
                      : fn(first, foldWith(fn, terminalValue, rest));
                  </code></pre>
                  <p>And now we supply a function that does slightly more than our mapping functions:</p>
                  <pre data-filter-output="(out)" data-role="codeBlock" data-info="js"
                      class="language-javascript data-line line-numbers data-user data-host data-prompt data-output"
                      data-prismjs-copy="Copy !" data-download-link />
                  <code class="language-javascript">foldWith((number, rest) =&gt; number * number + rest, 0, [1, 2, 3,
                      4, 5])
                      //=&gt; 55</code></pre>
                  <p>Our <code class="language-javascript">foldWith</code> function is a generalization of our <code
                          class="language-javascript">mapWith</code> function. We can represent a
                      map as a fold, we just need to supply the array rebuilding code:</p>
                  <pre data-filter-output="(out)" data-role="codeBlock" data-info="js"
                      class="language-javascript data-line line-numbers data-user data-host data-prompt data-output"
                      data-prismjs-copy="Copy !" data-download-link />
                  <code class="language-javascript">const squareAll = (array) =&gt; foldWith((first, rest) =&gt; [first
                      * first,
                      ...rest], [], array);



                      squareAll([1, 2, 3, 4, 5])
                      //=&gt; [1, 4, 9, 16, 25]</code></pre>
                  <p>And if we like, we can write <code class="language-javascript">mapWith</code> using <code
                          class="language-javascript">foldWith</code> :</p>
                  <pre data-filter-output="(out)" data-role="codeBlock" data-info="js"
                      class="language-javascript data-line line-numbers data-user data-host data-prompt data-output"
                      data-prismjs-copy="Copy !" data-download-link />
                  <code class="language-javascript">const mapWith = (fn, array) =&gt; foldWith((first, rest) =&gt;
                      [fn(first),
                      ...rest], [], array),
                      squareAll = (array) =&gt; mapWith((x) =&gt; x * x, array);



                      squareAll([1, 2, 3, 4, 5])
                      //=&gt; [1, 4, 9, 16, 25]
                  </code></pre>
                  <p>And to return to our first example, our version of <code class="language-javascript">length</code>
                      can be written
                      as a fold:</p>
                  <pre data-filter-output="(out)" data-role="codeBlock" data-info="js"
                      class="language-javascript data-line line-numbers data-user data-host data-prompt data-output"
                      data-prismjs-copy="Copy !" data-download-link />
                  <code class="language-javascript">const length = (array) =&gt; foldWith((first, rest) =&gt; 1 + rest,
                      0, array);



                      length([1, 2, 3, 4, 5])
                      //=&gt; 5
                  </code></pre>
                  <h3 id="summary">summary</h3>
                  <p>Linear recursion is a basic building block of algorithms. Its basic form parallels the way linear
                      data structures
                      like lists are constructed: This helps make it understandable. Its specialized cases of mapping
                      and folding are
                      especially useful and can be used to build other functions. And finally, while folding is a
                      special case of
                      linear recursion, mapping is a special case of folding.</p>
                  <section class="footnotes">
                      <hr />
                      <ol>
                          <li id="fn1">
                              <p>Well, actually, this does not work for arrays that contain <code
                                      class="language-javascript">undefined</code> as a value, but we
                                  are not going to see that in our examples. A more robust implementation would be <code
                                      class="language-javascript">(array) =&gt;
                                      array.length === 0</code> , but we are doing backflips to keep this within a very
                                  small and
                                  contrived playground.<a href="#fnref1" class="footnote-back">↩</a></p>
                          </li>
                          <li id="fn2">
                              <p><code class="language-javascript">flatten</code> is a very simple <a
                                      href="https://en.wikipedia.org/wiki/Anamorphism">unfold</a>,
                                  a function that takes a seed value and turns it into an array. Unfolds can be thought
                                  of a "path"
                                  through a data structure, and flattening a tree is equivalent to a depth-first
                                  traverse.<a href="#fnref2" class="footnote-back">↩</a></p>
                          </li>
                      </ol>
                  </section>
                
                
                
                
                
                
                <hr>
                
                <h1 id="memoization">Memoization</h1>
                <p><strong>Memoization</strong> is a design pattern used to reduce the overall number of calculations
                    that can
                    occur
                    in algorithms that use recursive strategies to solve.</p>
                <p>Recall that recursion solves a large problem by dividing it into smaller sub-problems that are more
                    manageable.
                    Memoization will store the results of the sub-problems in some other data structure, meaning that
                    you avoid
                    duplicate calculations and only "solve" each subproblem once. There are two features that comprise
                    memoization:
                </p>
                <ul>
                    <li>the function is recursive</li>
                    <li>the additional data structure used is typically an object (we refer to this as the memo!)</li>
                </ul>
                <p>This is a trade-off between the time it takes to run an algorithm (without memoization) and the
                    memory used
                    to
                    run the algorithm (with memoization). Usually memoization is a good trade-off when dealing with
                    large data
                    or
                    calculations.</p>
                <p>You cannot always apply this technique to recursive problems. The problem must have an "overlapping
                    subproblem
                    structure" for memoization to be effective.</p>
                <p>Here's an example of a problem that has such a structure:</p>
                <blockquote>
                    <p>Using pennies, nickels, dimes, and quarters, what is the smallest combination of coins that total
                        27
                        cents?
                    </p>
                </blockquote>
                <p>You'll explore this exact problem in depth later on. For now, here is some food for thought. Along
                    the way to
                    calculating the smallest coin combination of 27 cents, you should also calculate the smallest coin
                    combination
                    of say, 25 cents as a component of that problem. This is the essence of an overlapping subproblem
                    structure.
                </p>
                <h2 id="memoizing-factorial">Memoizing factorial</h2>
                <p>Here's an example of a function that computes the factorial of the number passed into it.</p>
                <div class="sourceCode" id="cb8">
                    <pre data-filter-output="(out)" class="sourceCode javascript"
                        class="sourceCode javascript"><code  class="language-javascript  highlight" id="button" class="sourceCode javascript"><a class="sourceLine" id="cb8-1" title="1"><span class="kw">function</span> <span class="at">factorial</span>(n) <span class="op">{</span></a>
<a class="sourceLine" id="cb8-2" title="2">  <span class="cf">if</span> (n <span class="op">===</span> <span class="dv">1</span>) <span class="cf">return</span> <span class="dv">1</span><span class="op">;</span></a>
<a class="sourceLine" id="cb8-3" title="3">  <span class="cf">return</span> n <span class="op">*</span> <span class="at">factorial</span>(n <span class="op">-</span> <span class="dv">1</span>)<span class="op">;</span></a>
<a class="sourceLine" id="cb8-4" title="4"><span class="op">}</span></a>
<a class="sourceLine" id="cb8-5" title="5"></a>
<a class="sourceLine" id="cb8-6" title="6"><span class="at">factorial</span>(<span class="dv">6</span>)<span class="op">;</span>       <span class="co">// =&gt; 720, requires 6 calls</span></a>
<a class="sourceLine" id="cb8-7" title="7"><span class="at">factorial</span>(<span class="dv">6</span>)<span class="op">;</span>       <span class="co">// =&gt; 720, requires 6 calls</span></a>
<a class="sourceLine" id="cb8-8" title="8"><span class="at">factorial</span>(<span class="dv">5</span>)<span class="op">;</span>       <span class="co">// =&gt; 120, requires 5 calls</span></a>
<a class="sourceLine" id="cb8-9" title="9"><span class="at">factorial</span>(<span class="dv">7</span>)<span class="op">;</span>       <span class="co">// =&gt; 5040, requires 7 calls</span></a></code></pre>
                </div>
                <p>From this plain <code class="language-javascript  highlight" id="button">factorial</code> above, it
                    is clear that every time you call
                    <code class="language-javascript  highlight" id="button">factorial(6)</code>
                    you
                    should get the same result of <code class="language-javascript  highlight" id="button">720</code>
                    each time. The code is somewhat inefficient because
                    you must
                    go
                    down the full recursive stack for each top level call to <code
                        class="language-javascript  highlight" id="button">factorial(6)</code>. It would be
                    great if you
                    could store the result of <code class="language-javascript  highlight"
                        id="button">factorial(6)</code> the first time you calculate it, then on
                    subsequent
                    calls to
                    <code class="language-javascript  highlight" id="button">factorial(6)</code> you simply fetch the
                    stored result in constant time. You can accomplish
                    exactly
                    this
                    by memoizing with an object!
                </p>
                <div class="sourceCode" id="cb9">
                    <pre data-filter-output="(out)" class="sourceCode javascript"
                        class="sourceCode javascript"><code  class="language-javascript  highlight" id="button" class="sourceCode javascript"><a class="sourceLine" id="cb9-1" title="1"><span class="kw">let</span> memo <span class="op">=</span> <span class="op">{}</span></a>
<a class="sourceLine" id="cb9-2" title="2"></a>
<a class="sourceLine" id="cb9-3" title="3"><span class="kw">function</span> <span class="at">factorial</span>(n) <span class="op">{</span></a>
<a class="sourceLine" id="cb9-4" title="4">  <span class="co">// if this function has calculated factorial(n) previously,</span></a>
<a class="sourceLine" id="cb9-5" title="5">  <span class="co">// fetch the stored result in memo</span></a>
<a class="sourceLine" id="cb9-6" title="6">  <span class="cf">if</span> (n <span class="kw">in</span> memo) <span class="cf">return</span> memo[n]<span class="op">;</span></a>
<a class="sourceLine" id="cb9-7" title="7">  <span class="cf">if</span> (n <span class="op">===</span> <span class="dv">1</span>) <span class="cf">return</span> <span class="dv">1</span><span class="op">;</span></a>
<a class="sourceLine" id="cb9-8" title="8"></a>
<a class="sourceLine" id="cb9-9" title="9">  <span class="co">// otherwise, it havs not calculated factorial(n) previously,</span></a>
<a class="sourceLine" id="cb9-10" title="10">  <span class="co">// so calculate it now, but store the result in case it is</span></a>
<a class="sourceLine" id="cb9-11" title="11">  <span class="co">// needed again in the future</span></a>
<a class="sourceLine" id="cb9-12" title="12">  memo[n] <span class="op">=</span> n <span class="op">*</span> <span class="at">factorial</span>(n <span class="op">-</span> <span class="dv">1</span>)<span class="op">;</span></a>
<a class="sourceLine" id="cb9-13" title="13">  <span class="cf">return</span> memo[n]</a>
<a class="sourceLine" id="cb9-14" title="14"><span class="op">}</span></a>
<a class="sourceLine" id="cb9-15" title="15"></a>
<a class="sourceLine" id="cb9-16" title="16"><span class="at">factorial</span>(<span class="dv">6</span>)<span class="op">;</span>       <span class="co">// =&gt; 720, requires 6 calls</span></a>
<a class="sourceLine" id="cb9-17" title="17"><span class="at">factorial</span>(<span class="dv">6</span>)<span class="op">;</span>       <span class="co">// =&gt; 720, requires 1 call</span></a>
<a class="sourceLine" id="cb9-18" title="18"><span class="at">factorial</span>(<span class="dv">5</span>)<span class="op">;</span>       <span class="co">// =&gt; 120, requires 1 call</span></a>
<a class="sourceLine" id="cb9-19" title="19"><span class="at">factorial</span>(<span class="dv">7</span>)<span class="op">;</span>       <span class="co">// =&gt; 5040, requires 2 calls</span></a>
<a class="sourceLine" id="cb9-20" title="20"></a>
<a class="sourceLine" id="cb9-21" title="21">memo<span class="op">;</span>   <span class="co">// =&gt; { &#39;2&#39;: 2, &#39;3&#39;: 6, &#39;4&#39;: 24, &#39;5&#39;: 120, &#39;6&#39;: 720, &#39;7&#39;: 5040 }</span></a></code></pre>
                </div>
                <p>The <code class="language-javascript  highlight" id="button">memo</code> object above will map an
                    argument of <code class="language-javascript  highlight" id="button">factorial</code> to its return
                    value. That
                    is,
                    the keys will be arguments and their values will be the corresponding results returned. By using the
                    memo,
                    you
                    are able to avoid duplicate recursive calls!</p>
                <p>Here's some food for thought: By the time your first call to <code
                        class="language-javascript  highlight" id="button">factorial(6)</code> returns, you
                    will not
                    have
                    just the argument <code class="language-javascript  highlight" id="button">6</code> stored in the
                    memo. Rather, you will have <em>all</em> arguments 2
                    to 6
                    stored
                    in the memo.</p>
                <p>Hopefully you sense the efficiency you can get by memoizing your functions, but maybe you are not
                    convinced
                    by
                    the last example for two reasons:</p>
                <ul>
                    <li>You didn't improve the speed of the algorithm by an order of Big-O (it is still O(n)).</li>
                    <li>The code uses some global variable, so it's kind of ugly.</li>
                </ul>
                <p>Both of those points are true, so take a look at a more advanced example that benefits from
                    memoization.</p>
                <h2 id="memoizing-the-fibonacci-generator">Memoizing the Fibonacci generator</h2>
                <p>Here's a <em>naive</em> implementation of a function that calculates the Fibonacci number for a given
                    input.
                </p>
                <div class="sourceCode" id="cb10">
                    <pre data-filter-output="(out)" class="sourceCode javascript"
                        class="sourceCode javascript"><code  class="language-javascript  highlight" id="button" class="sourceCode javascript"><a class="sourceLine" id="cb10-1" title="1"><span class="kw">function</span> <span class="at">fib</span>(n) <span class="op">{</span></a>
<a class="sourceLine" id="cb10-2" title="2">  <span class="cf">if</span> (n <span class="op">===</span> <span class="dv">1</span> <span class="op">||</span> n <span class="op">===</span> <span class="dv">2</span>) <span class="cf">return</span> <span class="dv">1</span><span class="op">;</span></a>
<a class="sourceLine" id="cb10-3" title="3">  <span class="cf">return</span> <span class="at">fib</span>(n <span class="op">-</span> <span class="dv">1</span>) <span class="op">+</span> <span class="at">fib</span>(n <span class="op">-</span> <span class="dv">2</span>)<span class="op">;</span></a>
<a class="sourceLine" id="cb10-4" title="4"><span class="op">}</span></a>
<a class="sourceLine" id="cb10-5" title="5"></a>
<a class="sourceLine" id="cb10-6" title="6"><span class="at">fib</span>(<span class="dv">6</span>)<span class="op">;</span>     <span class="co">// =&gt; 8</span></a></code></pre>
                </div>
                <p>Before you optimize this, ask yourself what complexity class it falls into in the first place.</p>
                <p>The time complexity of this function is not super intuitive to describe because the code branches
                    twice
                    recursively. Fret not! You'll find it useful to visualize the calls needed to do this with a tree.
                    When
                    reasoning about the time complexity for recursive functions, draw a tree that helps you see the
                    calls. Every
                    node of the tree represents a call of the recursion:</p>
                <figure>
                    <img src="images/fib_tree.png" alt="fib_tree" />
                    <figcaption>fib_tree</figcaption>
                </figure>
                <p>In general, the height of this tree will be <code class="language-javascript  highlight"
                        id="button">n</code>. You derive this by following the path
                    going
                    straight
                    down the left side of the tree. You can also see that each internal node leads to two more nodes.
                    Overall,
                    this
                    means that the tree will have roughly 2<sup>n</sup> nodes which is the same as saying that the
                    <code class="language-javascript  highlight" id="button">fib</code>
                    function has an exponential time complexity of 2<sup>n</sup>. That is very slow! See for yourself,
                    try
                    running
                    <code class="language-javascript  highlight" id="button">fib(50)</code> - you'll be waiting for
                    quite a while (it took 3 minutes on the author's
                    machine).
                </p>
                <p>Okay. So the <code class="language-javascript  highlight" id="button">fib</code> function is slow. Is
                    there anyway to speed it up? Take a look at the
                    tree
                    above.
                    Can you find any repetitive regions of the tree?</p>
                <figure>
                    <img src="images/fib_tree_duplicates.png" alt="fib_tree_duplicates" />
                    <figcaption>fib_tree_duplicates</figcaption>
                </figure>
                <p>As the <code class="language-javascript  highlight" id="button">n</code> grows bigger, the number of
                    duplicate sub-trees grows exponentially. Luckily
                    you can
                    fix
                    this using memoization by using a similar object strategy as before. You can use some JavaScript
                    default
                    arguments to clean things up:</p>
                <div class="sourceCode" id="cb11">
                    <pre data-filter-output="(out)" class="sourceCode javascript"
                        class="sourceCode javascript"><code  class="language-javascript  highlight" id="button" class="sourceCode javascript"><a class="sourceLine" id="cb11-1" title="1"><span class="kw">function</span> <span class="at">fastFib</span>(n<span class="op">,</span> memo <span class="op">=</span> <span class="op">{}</span>) <span class="op">{</span></a>
<a class="sourceLine" id="cb11-2" title="2">  <span class="cf">if</span> (n <span class="kw">in</span> memo) <span class="cf">return</span> memo[n]<span class="op">;</span></a>
<a class="sourceLine" id="cb11-3" title="3">  <span class="cf">if</span> (n <span class="op">===</span> <span class="dv">1</span> <span class="op">||</span> n <span class="op">===</span> <span class="dv">2</span>) <span class="cf">return</span> <span class="dv">1</span><span class="op">;</span></a>
<a class="sourceLine" id="cb11-4" title="4"></a>
<a class="sourceLine" id="cb11-5" title="5">  memo[n] <span class="op">=</span> <span class="at">fastFib</span>(n <span class="op">-</span> <span class="dv">1</span><span class="op">,</span> memo) <span class="op">+</span> <span class="at">fastFib</span>(n <span class="op">-</span> <span class="dv">2</span><span class="op">,</span> memo)<span class="op">;</span></a>
<a class="sourceLine" id="cb11-6" title="6">  <span class="cf">return</span> memo[n]<span class="op">;</span></a>
<a class="sourceLine" id="cb11-7" title="7"><span class="op">}</span></a>
<a class="sourceLine" id="cb11-8" title="8"></a>
<a class="sourceLine" id="cb11-9" title="9"><span class="at">fastFib</span>(<span class="dv">6</span>)<span class="op">;</span>     <span class="co">// =&gt; 8</span></a>
<a class="sourceLine" id="cb11-10" title="10"><span class="at">fastFib</span>(<span class="dv">50</span>)<span class="op">;</span>    <span class="co">// =&gt; 12586269025</span></a></code></pre>
                </div>
                <p>The code above can calculate the 50th Fibonacci number almost instantly! Thanks to the
                    <code class="language-javascript  highlight" id="button">memo</code>
                    object,
                    you only need to explore a subtree fully once. Visually, the <code
                        class="language-javascript  highlight" id="button">fastFib</code> recursion has this
                    structure:
                </p>
                <figure>
                    <img src="images/fib_memoized.png" alt="fib_memoized" />
                    <figcaption>fib_memoized</figcaption>
                </figure>
                <p>You can see the marked nodes (function calls) that access the memo in green. It's easy to see that
                    this
                    version
                    of the Fibonacci generator will do far less computations as <code
                        class="language-javascript  highlight" id="button">n</code> grows larger! In fact,
                    this
                    memoization has brought the time complexity down to linear <code
                        class="language-javascript  highlight" id="button">O(n)</code> time because the tree
                    only
                    branches
                    on the left side. This is an enormous gain if you recall the complexity class hierarchy.</p>
                <h2 id="the-memoization-formula">The memoization formula</h2>
                <p>Now that you understand memoization, when should you apply it? Memoization is useful when attacking
                    recursive
                    problems that have many overlapping sub-problems. You'll find it most useful to draw out the visual
                    tree
                    first.
                    If you notice duplicate sub-trees, time to memoize. Here are the hard and fast rules you can use to
                    memoize
                    a
                    slow function:</p>
                <ol type="1">
                    <li>Write the unoptimized, brute force recursion and make sure it works.</li>
                    <li>Add the memo object as an additional argument to the function. The keys will represent unique
                        arguments
                        to
                        the function, and their values will represent the results for those arguments.</li>
                    <li>Add a base case condition to the function that returns the stored value if the function's
                        argument is in
                        the
                        memo.</li>
                    <li>Before you return the result of the recursive case, store it in the memo as a value and make the
                        function's
                        argument it's key.</li>
                </ol>
                <h2 id="what-you-learned">What you learned</h2>
                <p>You learned a secret to possibly changing an algorithm of one complexity class to a lower complexity
                    class by
                    using memory to store intermediate results. This is a powerful technique to use to make sure your
                    programs
                    that
                    must do recursive calculations can benefit from running much faster.</p>
                <hr />
                <h1 id="tabulation">Tabulation</h1>
                <p>Now that you are familiar with <em>memoization</em>, you can explore a related method of algorithmic
                    optimization: <strong>Tabulation</strong>. There are two main features that comprise the Tabulation
                    strategy:
                </p>
                <ul>
                    <li>the function is iterative and <em>not</em> recursive</li>
                    <li>the additional data structure used is typically an array, commonly referred to as the table</li>
                </ul>
                <p>Many problems that can be solved with memoization can also be solved with tabulation as long as you
                    convert
                    the
                    recursion to iteration. The first example is the canonical example of recursion, calculating the
                    Fibonacci
                    number for an input. However, in the example, you'll see the iteration version of it for a fresh
                    start!</p>
                <h2 id="tabulating-the-fibonacci-number">Tabulating the Fibonacci number</h2>
                <p>Tabulation is all about creating a table (array) and filling it out with elements. In general, you
                    will
                    complete
                    the table by filling entries from "left to right". This means that the first entry of the table
                    (first
                    element
                    of the array) will correspond to the smallest subproblem. Naturally, the final entry of the table
                    (last
                    element
                    of the array) will correspond to the largest problem, which is also the final answer.</p>
                <p>Here's a way to use tabulation to store the intermediary calculations so that later calculations can
                    refer
                    back
                    to the table.</p>
                <div class="sourceCode" id="cb12">
                    <pre data-filter-output="(out)" class="sourceCode javascript"
                        class="sourceCode javascript"><code  class="language-javascript  highlight" id="button" class="sourceCode javascript"><a class="sourceLine" id="cb12-1" title="1"><span class="kw">function</span> <span class="at">tabulatedFib</span>(n) <span class="op">{</span></a>
<a class="sourceLine" id="cb12-2" title="2">  <span class="co">// create a blank array with n reserved spots</span></a>
<a class="sourceLine" id="cb12-3" title="3">  <span class="kw">let</span> table <span class="op">=</span> <span class="kw">new</span> <span class="at">Array</span>(n)<span class="op">;</span></a>
<a class="sourceLine" id="cb12-4" title="4"></a>
<a class="sourceLine" id="cb12-5" title="5">  <span class="co">// seed the first two values</span></a>
<a class="sourceLine" id="cb12-6" title="6">  table[<span class="dv">0</span>] <span class="op">=</span> <span class="dv">0</span><span class="op">;</span></a>
<a class="sourceLine" id="cb12-7" title="7">  table[<span class="dv">1</span>] <span class="op">=</span> <span class="dv">1</span><span class="op">;</span></a>
<a class="sourceLine" id="cb12-8" title="8"></a>
<a class="sourceLine" id="cb12-9" title="9">  <span class="co">// complete the table by moving from left to right,</span></a>
<a class="sourceLine" id="cb12-10" title="10">  <span class="co">// following the fibonacci pattern</span></a>
<a class="sourceLine" id="cb12-11" title="11">  <span class="cf">for</span> (<span class="kw">let</span> i <span class="op">=</span> <span class="dv">2</span><span class="op">;</span> i <span class="op">&lt;=</span> n<span class="op">;</span> i <span class="op">+=</span> <span class="dv">1</span>) <span class="op">{</span></a>
<a class="sourceLine" id="cb12-12" title="12">    table[i] <span class="op">=</span> table[i <span class="op">-</span> <span class="dv">1</span>] <span class="op">+</span> table[i <span class="op">-</span> <span class="dv">2</span>]<span class="op">;</span></a>
<a class="sourceLine" id="cb12-13" title="13">  <span class="op">}</span></a>
<a class="sourceLine" id="cb12-14" title="14"></a>
<a class="sourceLine" id="cb12-15" title="15">  <span class="cf">return</span> table[n]<span class="op">;</span></a>
<a class="sourceLine" id="cb12-16" title="16"><span class="op">}</span></a>
<a class="sourceLine" id="cb12-17" title="17"></a>
<a class="sourceLine" id="cb12-18" title="18"><span class="va">console</span>.<span class="at">log</span>(<span class="at">tabulatedFib</span>(<span class="dv">7</span>))<span class="op">;</span>      <span class="co">// =&gt; 13</span></a></code></pre>
                </div>
                <p>When you initialized the table and seeded the first two values, it looked like this:</p>
                <table>
                    <thead>
                        <tr class="header">
                            <th>i</th>
                            <th>0</th>
                            <th>1</th>
                            <th>2</th>
                            <th>3</th>
                            <th>4</th>
                            <th>5</th>
                            <th>6</th>
                            <th>7</th>
                        </tr>
                    </thead>
                    <tbody>
                        <tr class="odd">
                            <td><code class="language-javascript  highlight" id="button">table[i]</code></td>
                            <td><code class="language-javascript  highlight" id="button">0</code></td>
                            <td><code class="language-javascript  highlight" id="button">1</code></td>
                            <td></td>
                            <td></td>
                            <td></td>
                            <td></td>
                            <td></td>
                            <td></td>
                        </tr>
                    </tbody>
                </table>
                <p>After the loop finishes, the final table will be:</p>
                <table>
                    <thead>
                        <tr class="header">
                            <th>i</th>
                            <th>0</th>
                            <th>1</th>
                            <th>2</th>
                            <th>3</th>
                            <th>4</th>
                            <th>5</th>
                            <th>6</th>
                            <th>7</th>
                        </tr>
                    </thead>
                    <tbody>
                        <tr class="odd">
                            <td><code class="language-javascript  highlight" id="button">table[i]</code></td>
                            <td><code class="language-javascript  highlight" id="button">0</code></td>
                            <td><code class="language-javascript  highlight" id="button">1</code></td>
                            <td><code class="language-javascript  highlight" id="button">1</code></td>
                            <td><code class="language-javascript  highlight" id="button">2</code></td>
                            <td><code class="language-javascript  highlight" id="button">3</code></td>
                            <td><code class="language-javascript  highlight" id="button">5</code></td>
                            <td><code class="language-javascript  highlight" id="button">8</code></td>
                            <td><code class="language-javascript  highlight" id="button">13</code></td>
                        </tr>
                    </tbody>
                </table>
                <p>Similar to the previous <code class="language-javascript  highlight" id="button">memo</code>, by the
                    time the function completes, the <code class="language-javascript  highlight"
                        id="button">table</code>
                    will
                    contain the final solution as well as all sub-solutions calculated along the way.</p>
                <p>To compute the complexity class of this <code class="language-javascript  highlight"
                        id="button">tabulatedFib</code> is very straightforward since the
                    code is
                    iterative. The dominant operation in the function is the loop used to fill out the entire table. The
                    length
                    of
                    the table is roughly <code class="language-javascript  highlight" id="button">n</code> elements
                    long, so the algorithm will have an <em>O(n)</em>
                    runtime. The
                    space taken by our algorithm is also <em>O(n)</em> due to the size of the table. Overall, this
                    should be a
                    satisfying solution for the efficiency of the algorithm.</p>
                <h2 id="aside-refactoring-for-o1-space">Aside: Refactoring for O(1) Space</h2>
                <p>You may notice that you can cut down on the space used by the function. At any point of the loop, the
                    calculation
                    really only need the previous two subproblems' results. There is little utility to storing the full
                    array.
                    This
                    refactor is easy to do by using two variables:</p>
                <div class="sourceCode" id="cb13">
                    <pre data-filter-output="(out)" class="sourceCode javascript" class="sourceCode javascript"><code  class="language-javascript  highlight" id="button" class="sourceCode javascript"><a class="sourceLine" id="cb13-1" title="1"><span class="kw">function</span> <span class="at">fib</span>(n) <span class="op">{</span></a>
<a class="sourceLine" id="cb13-2" title="2">  <span class="kw">let</span> mostRecentCalcs <span class="op">=</span> [<span class="dv">0</span><span class="op">,</span> <span class="dv">1</span>]<span class="op">;</span></a>
<a class="sourceLine" id="cb13-3" title="3"></a>
<a class="sourceLine" id="cb13-4" title="4">  <span class="cf">if</span> (n <span class="op">===</span> <span class="dv">0</span>) <span class="cf">return</span> mostRecentCalcs[<span class="dv">0</span>]<span class="op">;</span></a>
<a class="sourceLine" id="cb13-5" title="5"></a>
<a class="sourceLine" id="cb13-6" title="6">  <span class="cf">for</span> (<span class="kw">let</span> i <span class="op">=</span> <span class="dv">2</span><span class="op">;</span> i <span class="op">&lt;=</span> n<span class="op">;</span> i<span class="op">++</span>) <span class="op">{</span></a>
<a class="sourceLine" id="cb13-7" title="7">    <span class="kw">const</span> [ secondLast<span class="op">,</span> last ] <span class="op">=</span> mostRecentCalcs<span class="op">;</span></a>
<a class="sourceLine" id="cb13-8" title="8">    mostRecentCalcs <span class="op">=</span> [ last<span class="op">,</span> secondLast <span class="op">+</span> last ]<span class="op">;</span></a>
<a class="sourceLine" id="cb13-9" title="9">  <span class="op">}</span></a>
<a class="sourceLine" id="cb13-10" title="10"></a>
<a class="sourceLine" id="cb13-11" title="11">  <span class="cf">return</span> mostRecentCalcs[<span class="dv">1</span>]<span class="op">;</span></a>
<a class="sourceLine" id="cb13-12" title="12"><span class="op">}</span></a></code></pre>
                </div>
                <p>Bam! You now have O(n) runtime and O(1) space. This is the most optimal algorithm for calculating a
                    Fibonacci
                    number. Note that this strategy is a pared down form of tabulation, since it uses only the last two
                    values.
                </p>
                <h3 id="the-tabulation-formula">The Tabulation Formula</h3>
                <p>Here are the general guidelines for implementing the tabulation strategy. This is just a general
                    recipe, so
                    adjust for taste depending on your problem:</p>
                <ol type="1">
                    <li>Create the table array based off of the size of the input, which isn't always straightforward if
                        you
                        have
                        multiple input values</li>
                    <li>Initialize some values in the table that "answer" the trivially small subproblem usually by
                        initializing
                        the
                        first entry (or entries) of the table</li>
                    <li>Iterate through the array and fill in remaining entries, using previous entries in the table to
                        perform
                        the
                        current calculation</li>
                    <li>Your final answer is (usually) the last entry in the table</li>
                </ol>
                <h2 id="what-you-learned-1">What you learned</h2>
                <p>You learned another way of possibly changing an algorithm of one complexity class to a lower
                    complexity class
                    by
                    using memory to store intermediate results. This is a powerful technique to use to make sure your
                    programs
                    that
                    must do iterative calculations can benefit from running much faster.</p>
                <hr />
                <h1 id="analysis-of-linear-search">Analysis of Linear Search</h1>
                <p>Consider the following search algorithm known as <strong>linear search</strong>.</p>
                <div class="sourceCode" id="cb14">
                    <pre data-filter-output="(out)" class="sourceCode javascript" class="sourceCode javascript"><code  class="language-javascript  highlight" id="button" class="sourceCode javascript"><a class="sourceLine" id="cb14-1" title="1"><span class="kw">function</span> <span class="at">search</span>(array<span class="op">,</span> term) <span class="op">{</span></a>
<a class="sourceLine" id="cb14-2" title="2">  <span class="cf">for</span> (<span class="kw">let</span> i <span class="op">=</span> <span class="dv">0</span><span class="op">;</span> i <span class="op">&lt;</span> <span class="va">array</span>.<span class="at">length</span><span class="op">;</span> i<span class="op">++</span>) <span class="op">{</span></a>
<a class="sourceLine" id="cb14-3" title="3">    <span class="cf">if</span> (array[i] <span class="op">==</span> term) <span class="op">{</span></a>
<a class="sourceLine" id="cb14-4" title="4">      <span class="cf">return</span> i<span class="op">;</span></a>
<a class="sourceLine" id="cb14-5" title="5">    <span class="op">}</span></a>
<a class="sourceLine" id="cb14-6" title="6">  <span class="op">}</span></a>
<a class="sourceLine" id="cb14-7" title="7">  <span class="cf">return</span> <span class="dv">-1</span><span class="op">;</span></a>
<a class="sourceLine" id="cb14-8" title="8"><span class="op">}</span></a></code></pre>
                </div>
                <p>Most Big-O analysis is done on the "worst-case scenario" and provides an upper bound. In the worst
                    case
                    analysis,
                    you calculate the upper bound on running time of an algorithm. You must know the case that causes
                    the
                    maximum
                    number of operations to be executed.</p>
                <p>For <em>linear search</em>, the worst case happens when the element to be searched (<code
                        class="language-javascript  highlight" id="button">term</code>
                    in the
                    above code) is not present in the array. When <code class="language-javascript  highlight"
                        id="button">term</code> is not present, the
                    <code class="language-javascript  highlight" id="button">search</code>
                    function
                    compares it with all the elements of <code class="language-javascript  highlight"
                        id="button">array</code> one by one. Therefore, the worst-case time
                    complexity of
                    linear search would be O(n).
                </p>
                <hr />
                <h1 id="analysis-of-binary-search">Analysis of Binary Search</h1>
                <p>Consider the following search algorithm known as the <strong>binary search</strong>. This kind of
                    search only
                    works if the array is already sorted.</p>
                <div class="sourceCode" id="cb15">
                    <pre data-filter-output="(out)" class="sourceCode javascript" class="sourceCode javascript"><code  class="language-javascript  highlight" id="button" class="sourceCode javascript"><a class="sourceLine" id="cb15-1" title="1"><span class="kw">function</span> <span class="at">binarySearch</span>(arr<span class="op">,</span> x<span class="op">,</span> start<span class="op">,</span> end) <span class="op">{</span></a>
<a class="sourceLine" id="cb15-2" title="2">  <span class="cf">if</span> (start <span class="op">&gt;</span> end) <span class="cf">return</span> <span class="kw">false</span><span class="op">;</span></a>
<a class="sourceLine" id="cb15-3" title="3"></a>
<a class="sourceLine" id="cb15-4" title="4">  <span class="kw">let</span> mid <span class="op">=</span> <span class="va">Math</span>.<span class="at">floor</span>((start <span class="op">+</span> end) / <span class="dv">2</span>)<span class="op">;</span></a>
<a class="sourceLine" id="cb15-5" title="5">  <span class="cf">if</span> (arr[mid] <span class="op">===</span> x) <span class="cf">return</span> <span class="kw">true</span><span class="op">;</span></a>
<a class="sourceLine" id="cb15-6" title="6"></a>
<a class="sourceLine" id="cb15-7" title="7">  <span class="cf">if</span> (arr[mid] <span class="op">&gt;</span> x) <span class="op">{</span></a>
<a class="sourceLine" id="cb15-8" title="8">    <span class="cf">return</span> <span class="at">binarySearch</span>(arr<span class="op">,</span> x<span class="op">,</span> start<span class="op">,</span> mid <span class="op">-</span> <span class="dv">1</span>)<span class="op">;</span></a>
<a class="sourceLine" id="cb15-9" title="9">  <span class="op">}</span> <span class="cf">else</span> <span class="op">{</span></a>
<a class="sourceLine" id="cb15-10" title="10">    <span class="cf">return</span> <span class="at">binarySearch</span>(arr<span class="op">,</span> x<span class="op">,</span> mid <span class="op">+</span> <span class="dv">1</span><span class="op">,</span> end)<span class="op">;</span></a>
<a class="sourceLine" id="cb15-11" title="11">  <span class="op">}</span></a>
<a class="sourceLine" id="cb15-12" title="12"><span class="op">}</span></a></code></pre>
                </div>
                <p>For the <em>binary search</em>, you cut the search space in half every time. This means that it
                    reduces the
                    number of searches you must do by half, every time. That means the number of steps it takes to get
                    to the
                    desired item (if it exists in the array), in the worst case takes the same amount of steps for every
                    number
                    within a range defined by the powers of 2.</p>
                <ul>
                    <li>7 -&gt; 4 -&gt; 2 -&gt; 1</li>
                    <li>8 -&gt; 4 -&gt; 2 -&gt; 1</li>
                    <li>9 -&gt; 5 -&gt; 3 -&gt; 2 -&gt; 1</li>
                    <li>15 -&gt; 8 -&gt; 4 -&gt; 2 -&gt; 1</li>
                    <li>16 -&gt; 8 -&gt; 4 -&gt; 2 -&gt; 1</li>
                    <li>17 -&gt; 9 -&gt; 5 -&gt; 3 -&gt; 2 -&gt; 1</li>
                    <li>31 -&gt; 16 -&gt; 8 -&gt; 4 -&gt; 2 -&gt; 1</li>
                    <li>32 -&gt; 16 -&gt; 8 -&gt; 4 -&gt; 2 -&gt; 1</li>
                    <li>33 -&gt; 17 -&gt; 9 -&gt; 5 -&gt; 3 -&gt; 2 -&gt; 1</li>
                </ul>
                <p>So, for any number of items in the sorted array between 2<sup>n-1</sup> and 2<sup>n</sup>, it takes
                    <em>n</em>
                    number of steps. That means if you have <em>k</em> items in the array, then it will take
                    <i>log</i><sub><i>2</i></sub><i>k</i>.
                </p>
                <p>Binary searches are <i>O</i>(<i>log</i><sub><i>2</i></sub><i>n</i>).</p>
                <hr />
                <h1 id="analysis-of-the-merge-sort">Analysis of the Merge Sort</h1>
                <p>Consider the following divide-and-conquer sort method known as the <strong>merge sort</strong>.</p>
                <div class="sourceCode" id="cb16">
                    <pre data-filter-output="(out)" class="sourceCode javascript" class="sourceCode javascript"><code  class="language-javascript  highlight" id="button" class="sourceCode javascript"><a class="sourceLine" id="cb16-1" title="1"><span class="kw">function</span> <span class="at">merge</span>(leftArray<span class="op">,</span> rightArray) <span class="op">{</span></a>
<a class="sourceLine" id="cb16-2" title="2">  <span class="kw">const</span> sorted <span class="op">=</span> []<span class="op">;</span></a>
<a class="sourceLine" id="cb16-3" title="3">  <span class="cf">while</span> (<span class="va">leftArray</span>.<span class="at">length</span> <span class="op">&gt;</span> <span class="dv">0</span> <span class="op">&amp;&amp;</span> <span class="va">rightArray</span>.<span class="at">length</span> <span class="op">&gt;</span> <span class="dv">0</span>) <span class="op">{</span></a>
<a class="sourceLine" id="cb16-4" title="4">    <span class="kw">const</span> leftItem <span class="op">=</span> leftArray[<span class="dv">0</span>]<span class="op">;</span></a>
<a class="sourceLine" id="cb16-5" title="5">    <span class="kw">const</span> rightItem <span class="op">=</span> rightArray[<span class="dv">0</span>]<span class="op">;</span></a>
<a class="sourceLine" id="cb16-6" title="6"></a>
<a class="sourceLine" id="cb16-7" title="7">    <span class="cf">if</span> (leftItem <span class="op">&gt;</span> rightItem) <span class="op">{</span></a>
<a class="sourceLine" id="cb16-8" title="8">      <span class="va">sorted</span>.<span class="at">push</span>(rightItem)<span class="op">;</span></a>
<a class="sourceLine" id="cb16-9" title="9">      <span class="va">rightArray</span>.<span class="at">shift</span>()<span class="op">;</span></a>
<a class="sourceLine" id="cb16-10" title="10">    <span class="op">}</span> <span class="cf">else</span> <span class="op">{</span></a>
<a class="sourceLine" id="cb16-11" title="11">      <span class="va">sorted</span>.<span class="at">push</span>(leftItem)<span class="op">;</span></a>
<a class="sourceLine" id="cb16-12" title="12">      <span class="va">leftArray</span>.<span class="at">shift</span>()<span class="op">;</span></a>
<a class="sourceLine" id="cb16-13" title="13">    <span class="op">}</span></a>
<a class="sourceLine" id="cb16-14" title="14">  <span class="op">}</span></a>
<a class="sourceLine" id="cb16-15" title="15"></a>
<a class="sourceLine" id="cb16-16" title="16">  <span class="cf">while</span> (<span class="va">leftArray</span>.<span class="at">length</span> <span class="op">!==</span> <span class="dv">0</span>) <span class="op">{</span></a>
<a class="sourceLine" id="cb16-17" title="17">    <span class="kw">const</span> value <span class="op">=</span> <span class="va">leftArray</span>.<span class="at">shift</span>()<span class="op">;</span></a>
<a class="sourceLine" id="cb16-18" title="18">    <span class="va">sorted</span>.<span class="at">push</span>(value)<span class="op">;</span></a>
<a class="sourceLine" id="cb16-19" title="19">  <span class="op">}</span></a>
<a class="sourceLine" id="cb16-20" title="20"></a>
<a class="sourceLine" id="cb16-21" title="21">  <span class="cf">while</span> (<span class="va">rightArray</span>.<span class="at">length</span> <span class="op">!==</span> <span class="dv">0</span>) <span class="op">{</span></a>
<a class="sourceLine" id="cb16-22" title="22">    <span class="kw">const</span> value <span class="op">=</span> <span class="va">rightArray</span>.<span class="at">shift</span>()<span class="op">;</span></a>
<a class="sourceLine" id="cb16-23" title="23">    <span class="va">sorted</span>.<span class="at">push</span>(value)<span class="op">;</span></a>
<a class="sourceLine" id="cb16-24" title="24">  <span class="op">}</span></a>
<a class="sourceLine" id="cb16-25" title="25"></a>
<a class="sourceLine" id="cb16-26" title="26">  <span class="cf">return</span> sorted</a>
<a class="sourceLine" id="cb16-27" title="27"><span class="op">}</span></a>
<a class="sourceLine" id="cb16-28" title="28"></a>
<a class="sourceLine" id="cb16-29" title="29"><span class="kw">function</span> <span class="at">mergeSort</span>(array) <span class="op">{</span></a>
<a class="sourceLine" id="cb16-30" title="30">  <span class="kw">const</span> length <span class="op">=</span> <span class="va">array</span>.<span class="at">length</span><span class="op">;</span></a>
<a class="sourceLine" id="cb16-31" title="31">  <span class="cf">if</span> (length <span class="op">==</span> <span class="dv">1</span>) <span class="op">{</span></a>
<a class="sourceLine" id="cb16-32" title="32">    <span class="cf">return</span> array<span class="op">;</span></a>
<a class="sourceLine" id="cb16-33" title="33">  <span class="op">}</span></a>
<a class="sourceLine" id="cb16-34" title="34"></a>
<a class="sourceLine" id="cb16-35" title="35">  <span class="kw">const</span> middleIndex <span class="op">=</span> <span class="va">Math</span>.<span class="at">ceil</span>(length / <span class="dv">2</span>)<span class="op">;</span></a>
<a class="sourceLine" id="cb16-36" title="36">  <span class="kw">const</span> leftArray <span class="op">=</span> <span class="va">array</span>.<span class="at">slice</span>(<span class="dv">0</span><span class="op">,</span> middleIndex)<span class="op">;</span></a>
<a class="sourceLine" id="cb16-37" title="37">  <span class="kw">const</span> rightArray <span class="op">=</span> <span class="va">array</span>.<span class="at">slice</span>(middleIndex<span class="op">,</span> length)<span class="op">;</span></a>
<a class="sourceLine" id="cb16-38" title="38"></a>
<a class="sourceLine" id="cb16-39" title="39">  leftArray <span class="op">=</span> <span class="at">mergeSort</span>(leftArray)<span class="op">;</span></a>
<a class="sourceLine" id="cb16-40" title="40">  rightArray <span class="op">=</span> <span class="at">mergeSort</span>(rightArray)<span class="op">;</span></a>
<a class="sourceLine" id="cb16-41" title="41"></a>
<a class="sourceLine" id="cb16-42" title="42">  <span class="cf">return</span> <span class="at">merge</span>(leftArray<span class="op">,</span> rightArray)<span class="op">;</span></a>
<a class="sourceLine" id="cb16-43" title="43"><span class="op">}</span></a></code></pre>
                </div>
                <p>For the <em>merge sort</em>, you cut the sort space in half every time. In each of those halves, you
                    have to
                    loop
                    through the number of items in the array. That means that, for the worst case, you get that same
                    <i>log</i><sub><i>2</i></sub><i>n</i> but it must be multiplied by the number of elements in the
                    array,
                    <em>n</em>.
                </p>
                <p>Merge sorts are <i>O</i>(<i>n*log</i><sub><i>2</i></sub><i>n</i>).</p>
                <hr />
                <h1 id="analysis-of-bubble-sort">Analysis of Bubble Sort</h1>
                <p>Consider the following sort algorithm known as the <strong>bubble sort</strong>.</p>
                <div class="sourceCode" id="cb17">
                    <pre data-filter-output="(out)" class="sourceCode javascript" class="sourceCode javascript"><code  class="language-javascript  highlight" id="button" class="sourceCode javascript"><a class="sourceLine" id="cb17-1" title="1"><span class="kw">function</span> <span class="at">bubbleSort</span>(items) <span class="op">{</span></a>
<a class="sourceLine" id="cb17-2" title="2">  <span class="kw">var</span> length <span class="op">=</span> <span class="va">items</span>.<span class="at">length</span><span class="op">;</span></a>
<a class="sourceLine" id="cb17-3" title="3">  <span class="cf">for</span> (<span class="kw">var</span> i <span class="op">=</span> <span class="dv">0</span><span class="op">;</span> i <span class="op">&lt;</span> length<span class="op">;</span> i<span class="op">++</span>) <span class="op">{</span></a>
<a class="sourceLine" id="cb17-4" title="4">    <span class="cf">for</span> (<span class="kw">var</span> j <span class="op">=</span> <span class="dv">0</span><span class="op">;</span> j <span class="op">&lt;</span> (length <span class="op">-</span> i <span class="op">-</span> <span class="dv">1</span>)<span class="op">;</span> j<span class="op">++</span>) <span class="op">{</span></a>
<a class="sourceLine" id="cb17-5" title="5">      <span class="cf">if</span> (items[j] <span class="op">&gt;</span> items[j <span class="op">+</span> <span class="dv">1</span>]) <span class="op">{</span></a>
<a class="sourceLine" id="cb17-6" title="6">        <span class="kw">var</span> tmp <span class="op">=</span> items[j]<span class="op">;</span></a>
<a class="sourceLine" id="cb17-7" title="7">        items[j] <span class="op">=</span> items[j <span class="op">+</span> <span class="dv">1</span>]<span class="op">;</span></a>
<a class="sourceLine" id="cb17-8" title="8">        items[j <span class="op">+</span> <span class="dv">1</span>] <span class="op">=</span> tmp<span class="op">;</span></a>
<a class="sourceLine" id="cb17-9" title="9">      <span class="op">}</span></a>
<a class="sourceLine" id="cb17-10" title="10">    <span class="op">}</span></a>
<a class="sourceLine" id="cb17-11" title="11">  <span class="op">}</span></a>
<a class="sourceLine" id="cb17-12" title="12"><span class="op">}</span></a></code></pre>
                </div>
                <p>For the <em>bubble sort</em>, the worst case is the same as the best case because it always makes
                    nested
                    loops.
                    So, the outer loop loops the number of times of the items in the array. For each one of those loops,
                    the
                    inner
                    loop loops again a number of times for the items in the array. So, if there are <em>n</em> values in
                    the
                    array,
                    then a loop inside a loop is <em>n</em> * <em>n</em>. So, this is O(n<sup>2</sup>). That's
                    polynomial, which
                    ain't that good.</p>
                <hr />
                <h1 id="leetcode.com">LeetCode.com</h1>
                <p> use the LeetCode platform to check your work rather than
                    relying
                    on local mocha tests. If you don't already have an account at LeetCode.com, please click
                    https://leetcode.com/accounts/signup/ to sign up for a free account.</p>
                <p>After you sign up for the account, please verify the account with the email address that you used so
                    that you
                    can
                    actually run your solution on LeetCode.com.</p>
                <p>In the projects, you will see files that are named "leet_code_«number».js". When you open those, you
                    will see
                    a
                    link in the file that you can use to go directly to the corresponding problem on LeetCode.com.</p>
                <p>Use the local JavaScript file in Visual Studio Code to collaborate on the solution. Then, you can run
                    the
                    proposed solution in the LeetCode.com code runner to validate its correctness.</p>
                <hr />
                <h1 id="memoization-problems">Memoization Problems</h1>
                <p>This project contains two test-driven problems and one problem on LeetCode.com.</p>
                <ul>
                    <li>Clone the project from https://github.com/appacademy-starters/algorithms-memoization-project.
                    </li>
                    <li><code class="language-javascript  highlight" id="button">cd</code> into the project folder</li>
                    <li><code class="language-javascript  highlight" id="button">npm install</code> to install
                        dependencies in the project root directory</li>
                    <li><code class="language-javascript  highlight" id="button">npx test</code> to run the specs</li>
                    <li>You can view the test cases in <code class="language-javascript  highlight"
                            id="button">/test/test.js</code>. Your job is to write code in the
                        <code class="language-javascript  highlight" id="button">/lib</code> files to pass all specs.
                        <ul>
                            <li>In <code class="language-javascript  highlight" id="button">problems.js</code>, you will
                                write code to make the
                                <code class="language-javascript  highlight" id="button">lucasNumberMemo</code> and
                                <code class="language-javascript  highlight" id="button">minChange</code> functions
                                pass.
                            </li>
                            <li>In <code class="language-javascript  highlight" id="button">leet_code_518.js</code>, you
                                will use that file as a scratch pad to work on the
                                LeetCode.com problem at https://leetcode.com/problems/coin-change-2/.</li>
                        </ul>
                    </li>
                </ul>
                <hr />
                <h1 id="tabulation-problems">Tabulation Problems</h1>
                <p>This project contains two test-driven problems and one problem on LeetCode.com.</p>
                <ul>
                    <li>Clone the project from https://github.com/appacademy-starters/algorithms-tabulation-project.
                    </li>
                    <li><code class="language-javascript  highlight" id="button">cd</code> into the project folder</li>
                    <li><code class="language-javascript  highlight" id="button">npm install</code> to install
                        dependencies in the project root directory</li>
                    <li><code class="language-javascript  highlight" id="button">npx test</code> to run the specs</li>
                    <li>You can view the test cases in <code class="language-javascript  highlight"
                            id="button">/test/test.js</code>. Your job is to write code in the
                        <code class="language-javascript  highlight" id="button">/lib</code> files to pass all specs.
                        <ul>
                            <li>In <code class="language-javascript  highlight" id="button">problems.js</code>, you will
                                write code to make the <code class="language-javascript  highlight"
                                    id="button">stepper</code>,
                                <code class="language-javascript  highlight" id="button">maxNonAdjacentSum</code>, and
                                <code class="language-javascript  highlight" id="button">minChange</code> functions
                                pass.
                            </li>
                            <li>In <code class="language-javascript  highlight" id="button">leet_code_64.js</code>, you
                                will use that file as a scratch pad to work on the
                                LeetCode.com
                                problem at https://leetcode.com/problems/minimum-path-sum/.</li>
                            <li>In <code class="language-javascript  highlight" id="button">leet_code_70.js</code>, you
                                will use that file as a scratch pad to work on the
                                LeetCode.com
                                problem at https://leetcode.com/problems/climbing-stairs/.</li>
                        </ul>
                    </li>
                </ul>
                <hr />
                <h1 id="week-07-day-3-sorting-algorithms" data-ignore="true">WEEK-07 DAY-3<br><em>Sorting
                        Algorithms</em></h1>
                <hr />
                <h1 id="sorting-algorithms-">Sorting Algorithms </h1>
                <p><strong>The objective of this lesson</strong> is for you to get experience implementing common
                    sorting
                    algorithms
                    that will come up during a lot of interviews. It is also important for you to understand how
                    different
                    sorting
                    algorithms behave when given output.</p>
                <p>At the end of this, you will be able to</p>
                <ol type="1">
                    <li>Explain the complexity of and write a function that performs <code
                            class="language-javascript  highlight" id="button">bubble sort</code> on an
                        array of
                        numbers.</li>
                    <li>Explain the complexity of and write a function that performs <code
                            class="language-javascript  highlight" id="button">selection sort</code> on an
                        array of
                        numbers.</li>
                    <li>Explain the complexity of and write a function that performs <code
                            class="language-javascript  highlight" id="button">insertion sort</code> on an
                        array of
                        numbers.</li>
                    <li>Explain the complexity of and write a function that performs <code
                            class="language-javascript  highlight" id="button">merge sort</code> on an array
                        of
                        numbers.
                    </li>
                    <li>Explain the complexity of and write a function that performs <code
                            class="language-javascript  highlight" id="button">quick sort</code> on an array
                        of
                        numbers.
                    </li>
                    <li>Explain the complexity of and write a function that performs a binary search on a sorted array
                        of
                        numbers.nce implementing common sorting algorithms that will come up during a lot of interviews.
                        It is
                        also
                        important for you to understand how different sorting algorithms behave when given output.</li>
                </ol>
                <p>At the end of this, you will be able to</p>
                <ol type="1">
                    <li>Explain the complexity of and write a function that performs <code
                            class="language-javascript  highlight" id="button">bubble sort</code> on an
                        array of
                        numbers.</li>
                    <li>Explain the complexity of and write a function that performs <code
                            class="language-javascript  highlight" id="button">selection sort</code> on an
                        array of
                        numbers.</li>
                    <li>Explain the complexity of and write a function that performs <code
                            class="language-javascript  highlight" id="button">insertion sort</code> on an
                        array of
                        numbers.</li>
                    <li>Explain the complexity of and write a function that performs <code
                            class="language-javascript  highlight" id="button">merge sort</code> on an array
                        of
                        numbers.
                    </li>
                    <li>Explain the complexity of and write a function that performs <code
                            class="language-javascript  highlight" id="button">quick sort</code> on an array
                        of
                        numbers.
                    </li>
                    <li>Explain the complexity of and write a function that performs a binary search on a sorted array
                        of
                        numbers.
                    </li>
                </ol>
                <hr />
                <h1 id="bubble-sort">Bubble Sort</h1>
                <p>Bubble Sort is generally the first major sorting algorithm to come up in most introductory
                    programming
                    courses.
                    Learning about this algorithm is useful educationally, as it provides a good introduction to the
                    challenges
                    you
                    face when tasked with converting unsorted data into sorted data, such as conducting logical
                    comparisons,
                    making
                    swaps while iterating, and making optimizations. It's also quite simple to implement, and can be
                    done
                    quickly.
                </p>
                <p>Bubble Sort is <em>almost never</em> a good choice in production. simply because:</p>
                <ul>
                    <li>It is not efficient</li>
                    <li>It is not commonly used</li>
                    <li>There is a stigma attached to using it</li>
                </ul>
                <h2 id="butthenwhy-are-we"><em>"But…then…why are we…"</em></h2>
                <p>It is <em>quite useful</em> as an educational base for you, and as a conversational base for you
                    while
                    interviewing, because you can discuss how other more elegant and efficient algorithms improve upon
                    it.
                    Taking
                    naive code and improving upon it by weighing the technical tradeoffs of your other options is 100%
                    the name
                    of
                    the game when trying to level yourself up from a junior engineer to a senior engineer.</p>
                <h2 id="the-algorithm-bubbles-up">The algorithm bubbles up</h2>
                <p>As you progress through the algorithms and data structures of this course, you'll eventually notice
                    that
                    there
                    are some recurring funny terms. "Bubbling up" is one of those terms.</p>
                <p>When someone writes that an item in a collection "bubbles up," you should infer that:</p>
                <ul>
                    <li>The item is <em>in motion</em></li>
                    <li>The item is moving <em>in some direction</em></li>
                    <li>The item <em>has some final resting destination</em></li>
                </ul>
                <p>When invoking Bubble Sort to sort an array of integers in ascending order, the largest integers will
                    "bubble
                    up"
                    to the "top" (the end) of the array, one at a time.</p>
                <p>The largest values are captured, put into motion in the direction defined by the desired sort
                    (ascending
                    right
                    now), and traverse the array until they arrive at their end destination. See if you can observe this
                    behavior in
                    the following animation (courtesy http://visualgo.net):</p>
                <figure>
                    <img src="images/BubbleSort.gif" alt="bubble sort" />
                    <figcaption>bubble sort</figcaption>
                </figure>
                <p>As the algorithm iterates through the array, it compares each element to the element's right
                    neighbor. If the
                    current element is larger than its neighbor, the algorithm swaps them. This continues until all
                    elements in
                    the
                    array are sorted.</p>
                <h2 id="how-does-a-pass-of-bubble-sort-work">How does a pass of Bubble Sort work?</h2>
                <p>Bubble sort works by performing multiple <em>passes</em> to move elements closer to their final
                    positions. A
                    single pass will iterate through the entire array once.</p>
                <p>A pass works by scanning the array from left to right, two elements at a time, and checking if they
                    are
                    ordered
                    correctly. To be ordered correctly the first element must be less than or equal to the second. If
                    the two
                    elements are not ordered properly, then we swap them to correct their order. Afterwards, it scans
                    the next
                    two
                    numbers and continue repeat this process until we have gone through the entire array.</p>
                <p>See one pass of bubble sort on the array <code class="language-javascript  highlight" id="button">[2,
                        8, 5, 2, 6]</code>. On each step the elements
                    currently
                    being
                    scanned are in <strong>bold</strong>.</p>
                <ul>
                    <li>[<strong>2</strong>, <strong>8</strong>, 5, 2, 6] - ordered, so leave them alone</li>
                    <li>[2, <strong>8</strong>, <strong>5</strong>, 2, 6] - not ordered, so swap</li>
                    <li>[2, 5, <strong>8</strong>, <strong>2</strong>, 6] - not ordered, so swap</li>
                    <li>[2, 5, 2, <strong>8</strong>, <strong>6</strong>] - not ordered, so swap</li>
                    <li>[2, 5, 2, 6, 8] - the first pass is complete</li>
                </ul>
                <p>Because at least one swap occurred, the algorithm knows that it wasn't sorted. It needs to make
                    another pass.
                    It
                    starts over again at the first entry and goes to the next-to-last entry doing the comparisons,
                    again. It
                    only
                    needs to go to the next-to-last entry because the previous "bubbling" put the largest entry in the
                    last
                    position.</p>
                <ul>
                    <li>[<strong>2</strong>, <strong>5</strong>, 2, 6, 8] - ordered, so leave them alone</li>
                    <li>[2, <strong>5</strong>, <strong>2</strong>, 6, 8] - not ordered, so swap</li>
                    <li>[2, 2, <strong>5</strong>, <strong>6</strong>, 8] - ordered, so leave them alone</li>
                    <li>[2, 2, 5, 6, 8] - the second pass is complete</li>
                </ul>
                <p>Because at least one swap occurred, the algorithm knows that it wasn't sorted. Now, it can bubble
                    from the
                    first
                    position to the last-2 position because the last two values are sorted.</p>
                <ul>
                    <li>[<strong>2</strong>, <strong>2</strong>, 5, 6, 8] - ordered, so leave them alone</li>
                    <li>[2, <strong>2</strong>, <strong>5</strong>, 6, 8] - ordered, so leave them alone</li>
                    <li>[2, 2, 5, 6, 8] - the third pass is complete</li>
                </ul>
                <p>No swap occurred, so the Bubble Sort stops.</p>
                <h2 id="ending-the-bubble-sort">Ending the Bubble Sort</h2>
                <p>During Bubble Sort, you can tell if the array is in sorted order by checking if a swap was made
                    during the
                    previous pass performed. If a swap was not performed during the previous pass, then the array must
                    be
                    totally
                    sorted and the algorithm can stop.</p>
                <p>You're probably wondering why that makes sense. Recall that a pass of Bubble Sort checks if any
                    adjacent
                    elements
                    are <strong>out of order</strong> and swaps them if they are. If we don't make any swaps during a
                    pass, then
                    everything must be already <strong>in order</strong>, so our job is done. Let that marinate for a
                    bit.</p>
                <h2 id="pseudocode-for-bubble-sort">Pseudocode for Bubble Sort</h2>
                <pre data-filter-output="(out)" class="sourceCode javascript"><code  class="language-javascript  highlight" id="button">Bubble Sort: (array)
  n := length(array)
  repeat
  swapped = false
  for i := 1 to n - 1 inclusive do

      /* if this pair is out of order */
      if array[i - 1] &gt; array[i] then

        /* swap them and remember something changed */
        swap(array, i - 1, i)
        swapped := true

      end if
    end for
  until not swapped</code></pre>
                <hr />
                <h1 id="selection-sort">Selection Sort</h1>
                <p>Selection Sort is very similar to Bubble Sort. The major difference between the two is that Bubble
                    Sort
                    bubbles
                    the <em>largest</em> elements up to the end of the array, while Selection Sort selects the
                    <em>smallest</em>
                    elements of the array and directly places them at the beginning of the array in sorted position.
                    Selection
                    sort
                    will utilize swapping just as bubble sort did. Let's carefully break this sorting algorithm down.
                </p>
                <h2 id="the-algorithm-select-the-next-smallest">The algorithm: select the next smallest</h2>
                <p>Selection sort works by maintaining a sorted region on the left side of the input array; this sorted
                    region
                    will
                    grow by one element with every "pass" of the algorithm. A single "pass" of selection sort will
                    select the
                    next
                    smallest element of unsorted region of the array and move it to the sorted region. Because a single
                    pass of
                    selection sort will move an element of the unsorted region into the sorted region, this means a
                    single pass
                    will
                    shrink the unsorted region by 1 element whilst increasing the sorted region by 1 element. Selection
                    sort is
                    complete when the sorted region spans the entire array and the unsorted region is empty!</p>
                <figure>
                    <img src="images/SelectionSort.gif" alt="selection sort" />
                    <figcaption>selection sort</figcaption>
                </figure>
                <p>The algorithm can be summarized as the following:</p>
                <ol type="1">
                    <li>Set MIN to location 0</li>
                    <li>Search the minimum element in the list</li>
                    <li>Swap with value at location MIN</li>
                    <li>Increment MIN to point to next element</li>
                    <li>Repeat until list is sorted</li>
                </ol>
                <h2 id="the-pseudocode">The pseudocode</h2>
                <p>In pseudocode, the Selection Sort can be written as this.</p>
                <pre data-filter-output="(out)" class="sourceCode javascript"><code  class="language-javascript  highlight" id="button">procedure selection sort
   list  : array of items
   n     : size of list

   for i = 1 to n - 1
   /* set current element as minimum*/
      min = i

      /* check the element to be minimum */

      for j = i+1 to n
         if list[j] &lt; list[min] then
            min = j;
         end if
      end for

      /* swap the minimum element with the current element*/
      if indexMin != i  then
         swap list[min] and list[i]
      end if
   end for
end procedure</code></pre>
                <hr />
                <h1 id="insertion-sort">Insertion Sort</h1>
                <p>With Bubble Sort and Selection Sort now in your tool box, you're starting to get some experience
                    points under
                    your belt! Time to learn one more "naive" sorting algorithm before you get to the efficient sorting
                    algorithms.
                </p>
                <h2 id="the-algorithm-insert-into-the-sorted-region">The algorithm: insert into the sorted region</h2>
                <p>Insertion Sort is similar to Selection Sort in that it gradually builds up a larger and larger sorted
                    region
                    at
                    the left-most end of the array.</p>
                <p>However, Insertion Sort differs from Selection Sort because this algorithm does not focus on
                    searching for
                    the
                    right element to place (the next smallest in our Selection Sort) on each pass through the array.
                    Instead, it
                    focuses on sorting each element in the order they appear from left to right, regardless of their
                    value, and
                    inserting them in the most appropriate position in the sorted region.</p>
                <p>See if you can observe the behavior described above in the following animation:</p>
                <figure>
                    <img src="images/InsertionSort.gif" alt="insertion sort" />
                    <figcaption>insertion sort</figcaption>
                </figure>
                <h2 id="the-steps">The Steps</h2>
                <p>Insertion Sort grows a sorted array on the left side of the input array by:</p>
                <ol type="1">
                    <li>If it is the first element, it is already sorted. return 1;</li>
                    <li>Pick next element</li>
                    <li>Compare with all elements in the sorted sub-list</li>
                    <li>Shift all the elements in the sorted sub-list that is greater than the value to be sorted</li>
                    <li>Insert the value</li>
                    <li>Repeat until list is sorted</li>
                </ol>
                <p>These steps are easy to confuse with selection sort, so you'll want to watch the video lecture and
                    drawing
                    that
                    accompanies this reading as always!</p>
                <h2 id="the-pseudocode-1">The pseudocode</h2>
                <pre data-filter-output="(out)" class="sourceCode javascript"><code  class="language-javascript  highlight" id="button">procedure insertionSort( A : array of items )
   int holePosition
   int valueToInsert

   for i = 1 to length(A) inclusive do:

      /* select value to be inserted */
      valueToInsert = A[i]
      holePosition = i

      /*locate hole position for the element to be inserted */

      while holePosition &gt; 0 and A[holePosition-1] &gt; valueToInsert do:
         A[holePosition] = A[holePosition-1]
         holePosition = holePosition -1
      end while

      /* insert the number at hole position */
      A[holePosition] = valueToInsert

   end for

end procedure</code></pre>
                <hr />
                <h1 id="merge-sort">Merge Sort</h1>
                <p>You've explored a few sorting algorithms already, all of them being quite slow with a runtime of
                    O(n<sup>2</sup>). It's time to level up and learn your first time-efficient sorting algorithm!
                    You'll
                    explore
                    <strong>merge sort</strong> in detail soon, but first, you should jot down some key ideas for now.
                    The
                    following
                    points are not steps to an algorithm yet; rather, they are ideas that will motivate how you can
                    derive this
                    algorithm.
                </p>
                <ul>
                    <li>it is easy to merge elements of two sorted arrays into a single sorted array</li>
                    <li>you can consider an array containing only a single element as already trivially sorted</li>
                    <li>you can also consider an empty array as trivially sorted</li>
                </ul>
                <h2 id="the-algorithm-divide-and-conquer">The algorithm: divide and conquer</h2>
                <p>You're going to need a helper function that solves the first major point from above. How might you
                    merge two
                    sorted arrays? In other words you want a <code class="language-javascript  highlight"
                        id="button">merge</code> function that will behave like so:</p>
                <div class="sourceCode" id="cb21">
                    <pre data-filter-output="(out)" class="sourceCode javascript"
                        class="sourceCode javascript"><code  class="language-javascript  highlight" id="button" class="sourceCode javascript"><a class="sourceLine" id="cb21-1" title="1"><span class="kw">let</span> arr1 <span class="op">=</span> [<span class="dv">1</span><span class="op">,</span> <span class="dv">5</span><span class="op">,</span> <span class="dv">10</span><span class="op">,</span> <span class="dv">15</span>]<span class="op">;</span></a>
<a class="sourceLine" id="cb21-2" title="2"><span class="kw">let</span> arr2 <span class="op">=</span> [<span class="dv">0</span><span class="op">,</span> <span class="dv">2</span><span class="op">,</span> <span class="dv">3</span><span class="op">,</span> <span class="dv">7</span><span class="op">,</span> <span class="dv">10</span>]<span class="op">;</span></a>
<a class="sourceLine" id="cb21-3" title="3"><span class="at">merge</span>(arr1<span class="op">,</span> arr2)<span class="op">;</span> <span class="co">// =&gt; [0, 1, 2, 3, 5, 7, 10, 10, 15]</span></a></code></pre>
                </div>
                <p>Once you have that, you get to the "divide and conquer" bit.</p>
                <p>The algorithm for merge sort is actually <em>really</em> simple.</p>
                <ol type="1">
                    <li>if there is only one element in the list, it is already sorted. return that array.</li>
                    <li>otherwise, divide the list recursively into two halves until it can no more be divided.</li>
                    <li>merge the smaller lists into new list in sorted order.</li>
                </ol>
                <p>The process is visualized below. When elements are moved to the bottom of the picture, they are going
                    through
                    the
                    <code class="language-javascript  highlight" id="button">merge</code> step:
                </p>
                <figure>
                    <img src="images/MergeSort.gif" alt="merge sort" />
                    <figcaption>merge sort</figcaption>
                </figure>
                <p>The pseudocode for the algorithm is as follows.</p>
                <pre data-filter-output="(out)" class="sourceCode javascript"><code  class="language-javascript  highlight" id="button">procedure mergesort( a as array )
   if ( n == 1 ) return a

   /* Split the array into two */
   var l1 as array = a[0] ... a[n/2]
   var l2 as array = a[n/2+1] ... a[n]

   l1 = mergesort( l1 )
   l2 = mergesort( l2 )

   return merge( l1, l2 )
end procedure

procedure merge( a as array, b as array )
   var result as array
   while ( a and b have elements )
      if ( a[0] &gt; b[0] )
         add b[0] to the end of result
         remove b[0] from b
      else
         add a[0] to the end of result
         remove a[0] from a
      end if
   end while

   while ( a has elements )
      add a[0] to the end of result
      remove a[0] from a
   end while

   while ( b has elements )
      add b[0] to the end of result
      remove b[0] from b
   end while

   return result
end procedure</code></pre>
                <hr />
                <h1 id="quick-sort">Quick Sort</h1>
                <p>Quick Sort has a similar "divide and conquer" strategy to Merge Sort. Here are a few key ideas that
                    will
                    motivate
                    the design:</p>
                <ul>
                    <li>it is easy to sort elements of an array relative to a particular target value</li>
                    <li>an array of 0 or 1 elements is already trivially sorted</li>
                </ul>
                <p>Regarding that first point, for example given <code class="language-javascript  highlight"
                        id="button">[7, 3, 8, 9, 2]</code> and a target of
                    <code class="language-javascript  highlight" id="button">5</code>, we
                    know <code class="language-javascript  highlight" id="button">[3, 2]</code> are numbers less than
                    <code class="language-javascript  highlight" id="button">5</code> and <code
                        class="language-javascript  highlight" id="button">[7, 8, 9]</code> are numbers
                    greater
                    than <code class="language-javascript  highlight" id="button">5</code>.
                </p>
                <h2 id="how-does-it-work">How does it work?</h2>
                <p>In general, the strategy is to divide the input array into two subarrays: one with the smaller
                    elements, and
                    one
                    with the larger elements. Then, it recursively operates on the two new subarrays. It continues this
                    process
                    until of dividing into smaller arrays until it reaches subarrays of length 1 or smaller. As you have
                    seen
                    with
                    Merge Sort, arrays of such length are automatically sorted.</p>
                <p>The steps, when discussed on a high level, are simple:</p>
                <ol type="1">
                    <li>choose an element called "the pivot", how that's done is up to the implementation</li>
                    <li>take two variables to point left and right of the list excluding pivot</li>
                    <li>left points to the low index</li>
                    <li>right points to the high</li>
                    <li>while value at left is less than pivot move right</li>
                    <li>while value at right is greater than pivot move left</li>
                    <li>if both step 5 and step 6 does not match swap left and right</li>
                    <li>if left ≥ right, the point where they met is new pivot</li>
                    <li>repeat, recursively calling this for smaller and smaller arrays</li>
                </ol>
                <p>Before we move forward, see if you can observe the behavior described above in the following
                    animation:</p>
                <figure>
                    <img src="images/QuickSort.gif" alt="quick sort" />
                    <figcaption>quick sort</figcaption>
                </figure>
                <h2 id="the-algorithm-divide-and-conquer-1">The algorithm: divide and conquer</h2>
                <p>Formally, we want to partition elements of an array relative to a pivot value. That is, we want
                    elements less
                    than the pivot to be separated from elements that are greater than or equal to the pivot. Our goal
                    is to
                    create
                    a function with this behavior:</p>
                <div class="sourceCode" id="cb23">
                    <pre data-filter-output="(out)" class="sourceCode javascript"
                        class="sourceCode javascript"><code  class="language-javascript  highlight" id="button" class="sourceCode javascript"><a class="sourceLine" id="cb23-1" title="1"><span class="kw">let</span> arr <span class="op">=</span> [<span class="dv">7</span><span class="op">,</span> <span class="dv">3</span><span class="op">,</span> <span class="dv">8</span><span class="op">,</span> <span class="dv">9</span><span class="op">,</span> <span class="dv">2</span>]<span class="op">;</span></a>
<a class="sourceLine" id="cb23-2" title="2"><span class="at">partition</span>(arr<span class="op">,</span> <span class="dv">5</span>)<span class="op">;</span>  <span class="co">// =&gt; [[3, 2], [7,8,9]]</span></a></code></pre>
                </div>
                <h3 id="partition">Partition</h3>
                <p>Seems simple enough! Let's implement it in JavaScript:</p>
                <div class="sourceCode" id="cb24">
                    <pre data-filter-output="(out)" class="sourceCode javascript" class="sourceCode javascript"><code  class="language-javascript  highlight" id="button" class="sourceCode javascript"><a class="sourceLine" id="cb24-1" title="1"><span class="co">// nothing fancy</span></a>
<a class="sourceLine" id="cb24-2" title="2"><span class="kw">function</span> <span class="at">partition</span>(array<span class="op">,</span> pivot) <span class="op">{</span></a>
<a class="sourceLine" id="cb24-3" title="3">  <span class="kw">let</span> left <span class="op">=</span> []<span class="op">;</span></a>
<a class="sourceLine" id="cb24-4" title="4">  <span class="kw">let</span> right <span class="op">=</span> []<span class="op">;</span></a>
<a class="sourceLine" id="cb24-5" title="5"></a>
<a class="sourceLine" id="cb24-6" title="6">  <span class="va">array</span>.<span class="at">forEach</span>(el <span class="kw">=&gt;</span> <span class="op">{</span></a>
<a class="sourceLine" id="cb24-7" title="7">    <span class="cf">if</span> (el <span class="op">&lt;</span> pivot) <span class="op">{</span></a>
<a class="sourceLine" id="cb24-8" title="8">      <span class="va">left</span>.<span class="at">push</span>(el)<span class="op">;</span></a>
<a class="sourceLine" id="cb24-9" title="9">    <span class="op">}</span> <span class="cf">else</span> <span class="op">{</span></a>
<a class="sourceLine" id="cb24-10" title="10">      <span class="va">right</span>.<span class="at">push</span>(el)<span class="op">;</span></a>
<a class="sourceLine" id="cb24-11" title="11">    <span class="op">}</span></a>
<a class="sourceLine" id="cb24-12" title="12">  <span class="op">}</span>)<span class="op">;</span></a>
<a class="sourceLine" id="cb24-13" title="13"></a>
<a class="sourceLine" id="cb24-14" title="14">  <span class="cf">return</span> [ left<span class="op">,</span> right ]<span class="op">;</span></a>
<a class="sourceLine" id="cb24-15" title="15"><span class="op">}</span></a>
<a class="sourceLine" id="cb24-16" title="16"></a>
<a class="sourceLine" id="cb24-17" title="17"><span class="co">// if you fancy</span></a>
<a class="sourceLine" id="cb24-18" title="18"><span class="kw">function</span> <span class="at">partition</span>(array<span class="op">,</span> pivot) <span class="op">{</span></a>
<a class="sourceLine" id="cb24-19" title="19">  <span class="kw">let</span> left <span class="op">=</span> <span class="va">array</span>.<span class="at">filter</span>(el <span class="kw">=&gt;</span> el <span class="op">&lt;</span> pivot)<span class="op">;</span></a>
<a class="sourceLine" id="cb24-20" title="20">  <span class="kw">let</span> right <span class="op">=</span> <span class="va">array</span>.<span class="at">filter</span>(el <span class="kw">=&gt;</span> el <span class="op">&gt;=</span> pivot)<span class="op">;</span></a>
<a class="sourceLine" id="cb24-21" title="21">  <span class="cf">return</span> [ left<span class="op">,</span> right ]<span class="op">;</span></a>
<a class="sourceLine" id="cb24-22" title="22"><span class="op">}</span></a></code></pre>
                </div>
                <p>You don't have to use an explicit <code class="language-javascript  highlight"
                        id="button">partition</code> helper function in your Quick Sort
                    implementation;
                    however, we will borrow heavily from this pattern. As you design algorithms, it helps to think about
                    key
                    patterns in isolation, although your solution may not feature that exact helper. Some would say we
                    like to
                    divide and conquer.</p>
                <h2 id="the-pseudocode-2">The pseudocode</h2>
                <p>It is <em>so</em> small, this algorithm. It's amazing that it performs so well with so little code!
                </p>
                <pre data-filter-output="(out)" class="sourceCode javascript"><code  class="language-javascript  highlight" id="button">procedure quickSort(left, right)

  if the length of the array is 0 or 1, return the array

  set the pivot to the first element of the array
  remove the first element of the array

  put all values less than the pivot value into an array called left
  put all values greater than the pivot value into an array called right

  call quick sort on left and assign the return value to leftSorted
  call quick sort on right and assign the return value to rightSorted

  return the concatenation of leftSorted, the pivot value, and rightSorted

end procedure</code></pre>
                <hr />
                <h1 id="binary-search">Binary Search</h1>
                <p>We've explored many ways to sort arrays so far, but why did we go through all of that trouble? By
                    sorting
                    elements of an array, we are organizing the data in a way that gives us a quick way to look up
                    elements
                    later
                    on. For simplicity, we have been using arrays of numbers up until this point. However, these sorting
                    concepts
                    can be generalized to other data types. For example, it would be easy to modify our comparison-based
                    sorting
                    algorithms to sort strings: instead of leveraging facts like <code
                        class="language-javascript  highlight" id="button">0 &lt; 1</code>, we can say
                    <code class="language-javascript  highlight" id="button">'A'
                        &lt;
                        'B'</code>.
                </p>
                <p>Think of a dictionary. A dictionary contains alphabetically sorted words and their definitions. A
                    dictionary
                    is
                    pretty much only useful if it is ordered in this way. Let's say you wanted to look up the definition
                    of
                    "stupendous." What steps might you take?</p>
                <ul>
                    <li>you open up the dictionary at the roughly middle page
                        <ul>
                            <li>you land in the "m" section</li>
                        </ul>
                    </li>
                    <li>you know "s" comes somewhere after "m" in the book, so you disregard all pages before the "m"
                        section.
                        Instead, you flip to the roughly middle page between "m" and "z"
                        <ul>
                            <li>you land in the "u" section</li>
                        </ul>
                    </li>
                    <li>you know "s" comes somewhere before "u", so you can disregard all pages after the "u" section.
                        Instead,
                        you
                        flip to the roughly middle page between the previous "m" page and "u"</li>
                    <li>…</li>
                </ul>
                <p>You are essentially using the <code class="language-javascript  highlight"
                        id="button">binarySearch</code> algorithm in the real world.</p>
                <h2 id="the-algorithm-check-the-middle-and-half-the-search-space">The Algorithm: "check the middle and
                    half the
                    search space"</h2>
                <p>Formally, our <code class="language-javascript  highlight" id="button">binarySearch</code> will seek
                    to solve the following problem:</p>
                <pre data-filter-output="(out)"
                    class="sourceCode javascript"><code  class="language-javascript  highlight" id="button">Given a sorted array of numbers and a target num, return a boolean indicating whether or not that target is contained in the array.</code></pre>
                <p>Programmatically, we want to satisfy the following behavior:</p>
                <div class="sourceCode" id="cb27">
                    <pre data-filter-output="(out)" class="sourceCode javascript"
                        class="sourceCode javascript"><code  class="language-javascript  highlight" id="button" class="sourceCode javascript"><a class="sourceLine" id="cb27-1" title="1"><span class="at">binarySearch</span>([<span class="dv">5</span><span class="op">,</span> <span class="dv">10</span><span class="op">,</span> <span class="dv">12</span><span class="op">,</span> <span class="dv">15</span><span class="op">,</span> <span class="dv">20</span><span class="op">,</span> <span class="dv">30</span><span class="op">,</span> <span class="dv">70</span>]<span class="op">,</span> <span class="dv">12</span>)<span class="op">;</span>  <span class="co">// =&gt; true</span></a>
<a class="sourceLine" id="cb27-2" title="2"><span class="at">binarySearch</span>([<span class="dv">5</span><span class="op">,</span> <span class="dv">10</span><span class="op">,</span> <span class="dv">12</span><span class="op">,</span> <span class="dv">15</span><span class="op">,</span> <span class="dv">20</span><span class="op">,</span> <span class="dv">30</span><span class="op">,</span> <span class="dv">70</span>]<span class="op">,</span> <span class="dv">24</span>)<span class="op">;</span>  <span class="co">// =&gt; false</span></a></code></pre>
                </div>
                <p>Before we move on, really internalize the fact that <code class="language-javascript  highlight"
                        id="button">binarySearch</code> will only work on
                    <strong>sorted</strong> arrays! Obviously we can search any array, sorted or unsorted, in
                    <code class="language-javascript  highlight" id="button">O(n)</code>
                    time. But now our goal is be able to search the array with a sub-linear time complexity (less than
                    <code class="language-javascript  highlight" id="button">O(n)</code>).
                </p>
                <h2 id="the-pseudocode-3">The pseudocode</h2>
                <pre data-filter-output="(out)" class="sourceCode javascript"><code  class="language-javascript  highlight" id="button">procedure binary search (list, target)
  parameter list: a list of sorted value
  parameter target: the value to search for

  if the list has zero length, then return false

  determine the slice point:
    if the list has an even number of elements,
      the slice point is the number of elements
      divided by two
    if the list has an odd number of elements,
      the slice point is the number of elements
      minus one divided by two

  create an list of the elements from 0 to the
    slice point, not including the slice point,
    which is known as the &quot;left half&quot;
  create an list of the elements from the
    slice point to the end of the list which is
    known as the &quot;right half&quot;

  if the target is less than the value in the
    original array at the slice point, then
    return the binary search of the &quot;left half&quot;
    and the target
  if the target is greater than the value in the
    original array at the slice point, then
    return the binary search of the &quot;right half&quot;
    and the target
  if neither of those is true, return true
end procedure binary search</code></pre>
                <hr />
                <h1 id="bubble-sort-analysis">Bubble Sort Analysis</h1>
                <p>Bubble Sort manipulates the array by swapping the position of two elements. To implement Bubble Sort
                    in JS,
                    you'll need to perform this operation. It helps to have a function to do that. A key detail in this
                    function
                    is
                    that you need an extra variable to store one of the elements since you will be overwriting them in
                    the
                    array:
                </p>
                <div class="sourceCode" id="cb29">
                    <pre data-filter-output="(out)" class="sourceCode javascript" class="sourceCode js"><code  class="language-javascript  highlight" id="button" class="sourceCode javascript"><a class="sourceLine" id="cb29-1" title="1"><span class="kw">function</span> <span class="at">swap</span>(array<span class="op">,</span> idx1<span class="op">,</span> idx2) <span class="op">{</span></a>
<a class="sourceLine" id="cb29-2" title="2">  <span class="kw">let</span> temp <span class="op">=</span> array[idx1]<span class="op">;</span>     <span class="co">// save a copy of the first value</span></a>
<a class="sourceLine" id="cb29-3" title="3">  array[idx1] <span class="op">=</span> array[idx2]<span class="op">;</span>  <span class="co">// overwrite the first value with the second value</span></a>
<a class="sourceLine" id="cb29-4" title="4">  array[idx2] <span class="op">=</span> temp<span class="op">;</span>         <span class="co">// overwrite the second value with the first value</span></a>
<a class="sourceLine" id="cb29-5" title="5"><span class="op">}</span></a></code></pre>
                </div>
                <p>Note that the swap function does not create or return a new array. It mutates the original array:</p>
                <div class="sourceCode" id="cb30">
                    <pre data-filter-output="(out)" class="sourceCode javascript"
                        class="sourceCode js"><code  class="language-javascript  highlight" id="button" class="sourceCode javascript"><a class="sourceLine" id="cb30-1" title="1"><span class="kw">let</span> arr1 <span class="op">=</span> [<span class="dv">2</span><span class="op">,</span> <span class="dv">8</span><span class="op">,</span> <span class="dv">5</span><span class="op">,</span> <span class="dv">2</span><span class="op">,</span> <span class="dv">6</span>]<span class="op">;</span></a>
<a class="sourceLine" id="cb30-2" title="2"><span class="at">swap</span>(arr1<span class="op">,</span> <span class="dv">1</span><span class="op">,</span> <span class="dv">2</span>)<span class="op">;</span></a>
<a class="sourceLine" id="cb30-3" title="3">arr1<span class="op">;</span> <span class="co">// =&gt; [ 2, 5, 8, 2, 6 ]</span></a></code></pre>
                </div>
                <h3 id="bubble-sort-js-implementation">Bubble Sort JS Implementation</h3>
                <p>Take a look at the snippet below and try to understand how it corresponds to the conceptual
                    understanding of
                    the
                    algorithm. Scroll down to the commented version when you get stuck.</p>
                <div class="sourceCode" id="cb31">
                    <pre data-filter-output="(out)" class="sourceCode javascript" class="sourceCode js"><code  class="language-javascript  highlight" id="button" class="sourceCode javascript"><a class="sourceLine" id="cb31-1" title="1"><span class="kw">function</span> <span class="at">bubbleSort</span>(array) <span class="op">{</span></a>
<a class="sourceLine" id="cb31-2" title="2">  <span class="kw">let</span> swapped <span class="op">=</span> <span class="kw">true</span><span class="op">;</span></a>
<a class="sourceLine" id="cb31-3" title="3"></a>
<a class="sourceLine" id="cb31-4" title="4">  <span class="cf">while</span>(swapped) <span class="op">{</span></a>
<a class="sourceLine" id="cb31-5" title="5">    swapped <span class="op">=</span> <span class="kw">false</span><span class="op">;</span></a>
<a class="sourceLine" id="cb31-6" title="6"></a>
<a class="sourceLine" id="cb31-7" title="7">    <span class="cf">for</span> (<span class="kw">let</span> i <span class="op">=</span> <span class="dv">0</span><span class="op">;</span> i <span class="op">&lt;</span> <span class="va">array</span>.<span class="at">length</span> <span class="op">-</span> <span class="dv">1</span><span class="op">;</span> i<span class="op">++</span>) <span class="op">{</span></a>
<a class="sourceLine" id="cb31-8" title="8">      <span class="cf">if</span> (array[i] <span class="op">&gt;</span> array[i<span class="op">+</span><span class="dv">1</span>]) <span class="op">{</span></a>
<a class="sourceLine" id="cb31-9" title="9">        <span class="at">swap</span>(array<span class="op">,</span> i<span class="op">,</span> i<span class="op">+</span><span class="dv">1</span>)<span class="op">;</span></a>
<a class="sourceLine" id="cb31-10" title="10">        swapped <span class="op">=</span> <span class="kw">true</span><span class="op">;</span></a>
<a class="sourceLine" id="cb31-11" title="11">      <span class="op">}</span></a>
<a class="sourceLine" id="cb31-12" title="12">    <span class="op">}</span></a>
<a class="sourceLine" id="cb31-13" title="13">  <span class="op">}</span></a>
<a class="sourceLine" id="cb31-14" title="14"></a>
<a class="sourceLine" id="cb31-15" title="15">  <span class="cf">return</span> array<span class="op">;</span></a>
<a class="sourceLine" id="cb31-16" title="16"><span class="op">}</span></a></code></pre>
                </div>
                <div class="sourceCode" id="cb32">
                    <pre data-filter-output="(out)" class="sourceCode javascript" class="sourceCode js"><code  class="language-javascript  highlight" id="button" class="sourceCode javascript"><a class="sourceLine" id="cb32-1" title="1"><span class="co">// commented</span></a>
<a class="sourceLine" id="cb32-2" title="2"><span class="kw">function</span> <span class="at">bubbleSort</span>(array) <span class="op">{</span></a>
<a class="sourceLine" id="cb32-3" title="3">  <span class="co">// this variable will be used to track whether or not we</span></a>
<a class="sourceLine" id="cb32-4" title="4">  <span class="co">// made a swap on the previous pass. If we did not make</span></a>
<a class="sourceLine" id="cb32-5" title="5">  <span class="co">// any swap on the previous pass, then the array must</span></a>
<a class="sourceLine" id="cb32-6" title="6">  <span class="co">// already be sorted</span></a>
<a class="sourceLine" id="cb32-7" title="7">  <span class="kw">let</span> swapped <span class="op">=</span> <span class="kw">true</span><span class="op">;</span></a>
<a class="sourceLine" id="cb32-8" title="8"></a>
<a class="sourceLine" id="cb32-9" title="9">  <span class="co">// this while will keep doing passes if a swap was made</span></a>
<a class="sourceLine" id="cb32-10" title="10">  <span class="co">// on the previous pass</span></a>
<a class="sourceLine" id="cb32-11" title="11">  <span class="cf">while</span>(swapped) <span class="op">{</span></a>
<a class="sourceLine" id="cb32-12" title="12">    swapped <span class="op">=</span> <span class="kw">false</span><span class="op">;</span>  <span class="co">// reset swap to false</span></a>
<a class="sourceLine" id="cb32-13" title="13"></a>
<a class="sourceLine" id="cb32-14" title="14">    <span class="co">// this for will perform a single pass</span></a>
<a class="sourceLine" id="cb32-15" title="15">    <span class="cf">for</span> (<span class="kw">let</span> i <span class="op">=</span> <span class="dv">0</span><span class="op">;</span> i <span class="op">&lt;</span> <span class="va">array</span>.<span class="at">length</span><span class="op">;</span> i<span class="op">++</span>) <span class="op">{</span></a>
<a class="sourceLine" id="cb32-16" title="16"></a>
<a class="sourceLine" id="cb32-17" title="17">      <span class="co">// if the two value are not ordered...</span></a>
<a class="sourceLine" id="cb32-18" title="18">      <span class="cf">if</span> (array[i] <span class="op">&gt;</span> array[i<span class="op">+</span><span class="dv">1</span>]) <span class="op">{</span></a>
<a class="sourceLine" id="cb32-19" title="19"></a>
<a class="sourceLine" id="cb32-20" title="20">        <span class="co">// swap the two values</span></a>
<a class="sourceLine" id="cb32-21" title="21">        <span class="at">swap</span>(array<span class="op">,</span> i<span class="op">,</span> i<span class="op">+</span><span class="dv">1</span>)<span class="op">;</span></a>
<a class="sourceLine" id="cb32-22" title="22"></a>
<a class="sourceLine" id="cb32-23" title="23">        <span class="co">// since you made a swap, remember that you did so</span></a>
<a class="sourceLine" id="cb32-24" title="24">        <span class="co">// b/c we should perform another pass after this one</span></a>
<a class="sourceLine" id="cb32-25" title="25">        swapped <span class="op">=</span> <span class="kw">true</span><span class="op">;</span></a>
<a class="sourceLine" id="cb32-26" title="26">      <span class="op">}</span></a>
<a class="sourceLine" id="cb32-27" title="27">    <span class="op">}</span></a>
<a class="sourceLine" id="cb32-28" title="28">  <span class="op">}</span></a>
<a class="sourceLine" id="cb32-29" title="29"></a>
<a class="sourceLine" id="cb32-30" title="30">  <span class="cf">return</span> array<span class="op">;</span></a>
<a class="sourceLine" id="cb32-31" title="31"><span class="op">}</span></a></code></pre>
                </div>
                <h2 id="time-complexity-on2">Time Complexity: O(n<sup>2</sup>)</h2>
                <p>Picture the worst case scenario where the input array is completely unsorted. Say it's sorted in
                    fully
                    decreasing
                    order, but the goal is to sort it in increasing order:</p>
                <ul>
                    <li>n is the length of the input array</li>
                    <li>The inner <code class="language-javascript  highlight" id="button">for</code> loop along
                        contributes <em>O(n)</em> in isolation</li>
                    <li>The outer while loop contributes <em>O(n)</em> in isolation because a single iteration of the
                        while loop
                        will bring one element to its final resting position. In other words, it keeps running the while
                        loop
                        until
                        the array is fully sorted. To fully sort the array we will need to bring all <code
                            class="language-javascript  highlight" id="button">n</code>
                        elements
                        into
                        their final resting positions.</li>
                    <li>Those two loops are nested so the total time complexity is O(n * n) = O(n<sup>2</sup>).</li>
                </ul>
                <p>It's worth mentioning that the best case scenario is when the input array is already fully sorted.
                    This will
                    cause our for loop to conduct a single pass without performing any swap, so the <code
                        class="language-javascript  highlight" id="button">while</code>
                    loop will
                    not
                    trigger further iterations. This means best case time complexity is <em>O(n)</em> for bubble sort.
                    This best
                    case linear time is probably the only advantage of bubble sort. Programmers are usually interested
                    only in
                    the
                    worst-case analysis and ignore best-case analysis.</p>
                <h2 id="space-complexity-o1">Space Complexity: O(1)</h2>
                <p>Bubble Sort is a constant space, O(1), algorithm. The amount of memory consumed by the algorithm does
                    not
                    increase relative to the size of the input array. It uses the same amount of memory and create the
                    same
                    amount
                    of variables regardless of the size of the input, making this algorithm quite space efficient. The
                    space
                    efficiency mostly comes from the fact that it mutates the input array in-place. This is known as a
                    <strong>destructive sort</strong> because it "destroys" the positions of the values in the array.
                </p>
                <h2 id="when-should-you-use-bubble-sort">When should you use Bubble Sort?</h2>
                <p>Nearly never, but it may be a good choice in the following list of special cases:</p>
                <ul>
                    <li>When sorting really small arrays where run time will be negligible no matter what algorithm you
                        choose.
                    </li>
                    <li>When sorting arrays that you expect to already be nearly sorted.</li>
                    <li>At parties</li>
                </ul>
                <hr />
                <h1 id="selection-sort-analysis">Selection Sort Analysis</h1>
                <p>Since a component of Selection Sort requires us to locate the smallest value in the array, let's
                    focus on
                    that
                    pattern in isolation:</p>
                <div class="sourceCode" id="cb33">
                    <pre data-filter-output="(out)" class="sourceCode javascript" class="sourceCode javascript"><code  class="language-javascript  highlight" id="button" class="sourceCode javascript"><a class="sourceLine" id="cb33-1" title="1"><span class="kw">function</span> <span class="at">minumumValueIndex</span>(arr) <span class="op">{</span></a>
<a class="sourceLine" id="cb33-2" title="2">    <span class="kw">let</span> minIndex <span class="op">=</span> <span class="dv">0</span><span class="op">;</span></a>
<a class="sourceLine" id="cb33-3" title="3"></a>
<a class="sourceLine" id="cb33-4" title="4">    <span class="cf">for</span> (<span class="kw">let</span> j <span class="op">=</span> <span class="dv">0</span><span class="op">;</span> j <span class="op">&lt;</span> <span class="va">arr</span>.<span class="at">length</span><span class="op">;</span> j<span class="op">++</span>) <span class="op">{</span></a>
<a class="sourceLine" id="cb33-5" title="5">        <span class="cf">if</span> (arr[minIndex] <span class="op">&gt;</span> arr[j]) <span class="op">{</span></a>
<a class="sourceLine" id="cb33-6" title="6">            minIndex <span class="op">=</span> j<span class="op">;</span></a>
<a class="sourceLine" id="cb33-7" title="7">        <span class="op">}</span></a>
<a class="sourceLine" id="cb33-8" title="8">    <span class="op">}</span></a>
<a class="sourceLine" id="cb33-9" title="9"></a>
<a class="sourceLine" id="cb33-10" title="10">    <span class="cf">return</span> minIndex<span class="op">;</span></a>
<a class="sourceLine" id="cb33-11" title="11"><span class="op">}</span></a></code></pre>
                </div>
                <p>Pretty basic code right? We won't use this explicit helper function to solve selection sort, however
                    we will
                    borrow from this pattern soon.</p>
                <h2 id="selection-sort-js-implementation">Selection Sort JS Implementation</h2>
                <p>We'll also utilize the classic swap pattern that we introduced in the bubble sort. To refresh:</p>
                <div class="sourceCode" id="cb34">
                    <pre data-filter-output="(out)" class="sourceCode javascript" class="sourceCode javascript"><code  class="language-javascript  highlight" id="button" class="sourceCode javascript"><a class="sourceLine" id="cb34-1" title="1"><span class="kw">function</span> <span class="at">swap</span>(arr<span class="op">,</span> index1<span class="op">,</span> index2) <span class="op">{</span></a>
<a class="sourceLine" id="cb34-2" title="2">  <span class="kw">let</span> temp <span class="op">=</span> arr[index1]<span class="op">;</span></a>
<a class="sourceLine" id="cb34-3" title="3">  arr[index1] <span class="op">=</span> arr[index2]<span class="op">;</span></a>
<a class="sourceLine" id="cb34-4" title="4">  arr[index2] <span class="op">=</span> temp<span class="op">;</span></a>
<a class="sourceLine" id="cb34-5" title="5"><span class="op">}</span></a></code></pre>
                </div>
                <p>Now for the punchline! Take a look at the snippet below and try to understand how it corresponds to
                    our
                    conceptual understanding of the selection sort algorithm. Scroll down to the commented version when
                    you get
                    stuck.</p>
                <div class="sourceCode" id="cb35">
                    <pre data-filter-output="(out)" class="sourceCode javascript" class="sourceCode javascript"><code  class="language-javascript  highlight" id="button" class="sourceCode javascript"><a class="sourceLine" id="cb35-1" title="1"><span class="kw">function</span> <span class="at">selectionSort</span>(arr) <span class="op">{</span></a>
<a class="sourceLine" id="cb35-2" title="2">  <span class="cf">for</span> (<span class="kw">let</span> i <span class="op">=</span> <span class="dv">0</span><span class="op">;</span> i <span class="op">&lt;</span> <span class="va">arr</span>.<span class="at">length</span><span class="op">;</span> i<span class="op">++</span>) <span class="op">{</span></a>
<a class="sourceLine" id="cb35-3" title="3">    <span class="kw">let</span> minIndex <span class="op">=</span> i<span class="op">;</span></a>
<a class="sourceLine" id="cb35-4" title="4"></a>
<a class="sourceLine" id="cb35-5" title="5">    <span class="cf">for</span> (<span class="kw">let</span> j <span class="op">=</span> i <span class="op">+</span> <span class="dv">1</span><span class="op">;</span> j <span class="op">&lt;</span> <span class="va">arr</span>.<span class="at">length</span><span class="op">;</span> j<span class="op">++</span>) <span class="op">{</span></a>
<a class="sourceLine" id="cb35-6" title="6">      <span class="cf">if</span> (arr[minIndex] <span class="op">&gt;</span> arr[j]) <span class="op">{</span></a>
<a class="sourceLine" id="cb35-7" title="7">        minIndex <span class="op">=</span> j<span class="op">;</span></a>
<a class="sourceLine" id="cb35-8" title="8">      <span class="op">}</span></a>
<a class="sourceLine" id="cb35-9" title="9">    <span class="op">}</span></a>
<a class="sourceLine" id="cb35-10" title="10"></a>
<a class="sourceLine" id="cb35-11" title="11">    <span class="at">swap</span>(arr<span class="op">,</span> i<span class="op">,</span> minIndex)<span class="op">;</span></a>
<a class="sourceLine" id="cb35-12" title="12">  <span class="op">}</span></a>
<a class="sourceLine" id="cb35-13" title="13">  <span class="cf">return</span> arr<span class="op">;</span></a>
<a class="sourceLine" id="cb35-14" title="14"><span class="op">}</span></a></code></pre>
                </div>
                <div class="sourceCode" id="cb36">
                    <pre data-filter-output="(out)" class="sourceCode javascript" class="sourceCode javascript"><code  class="language-javascript  highlight" id="button" class="sourceCode javascript"><a class="sourceLine" id="cb36-1" title="1"><span class="co">// commented</span></a>
<a class="sourceLine" id="cb36-2" title="2"><span class="kw">function</span> <span class="at">selectionSort</span>(arr) <span class="op">{</span></a>
<a class="sourceLine" id="cb36-3" title="3">    <span class="co">// the `i` loop will track the index that points to the first element of the unsorted region:</span></a>
<a class="sourceLine" id="cb36-4" title="4">    <span class="co">//    this means that the sorted region is everything left of index i</span></a>
<a class="sourceLine" id="cb36-5" title="5">    <span class="co">//    and the unsorted region is everything to the right of index i</span></a>
<a class="sourceLine" id="cb36-6" title="6">    <span class="cf">for</span> (<span class="kw">let</span> i <span class="op">=</span> <span class="dv">0</span><span class="op">;</span> i <span class="op">&lt;</span> <span class="va">arr</span>.<span class="at">length</span><span class="op">;</span> i<span class="op">++</span>) <span class="op">{</span></a>
<a class="sourceLine" id="cb36-7" title="7">        <span class="kw">let</span> minIndex <span class="op">=</span> i<span class="op">;</span></a>
<a class="sourceLine" id="cb36-8" title="8"></a>
<a class="sourceLine" id="cb36-9" title="9">        <span class="co">// the `j` loop will iterate through the unsorted region and find the index of the smallest element</span></a>
<a class="sourceLine" id="cb36-10" title="10">        <span class="cf">for</span> (<span class="kw">let</span> j <span class="op">=</span> i <span class="op">+</span> <span class="dv">1</span><span class="op">;</span> j <span class="op">&lt;</span> <span class="va">arr</span>.<span class="at">length</span><span class="op">;</span> j<span class="op">++</span>) <span class="op">{</span></a>
<a class="sourceLine" id="cb36-11" title="11">            <span class="cf">if</span> (arr[minIndex] <span class="op">&gt;</span> arr[j]) <span class="op">{</span></a>
<a class="sourceLine" id="cb36-12" title="12">                minIndex <span class="op">=</span> j<span class="op">;</span></a>
<a class="sourceLine" id="cb36-13" title="13">            <span class="op">}</span></a>
<a class="sourceLine" id="cb36-14" title="14">        <span class="op">}</span></a>
<a class="sourceLine" id="cb36-15" title="15"></a>
<a class="sourceLine" id="cb36-16" title="16">        <span class="co">// after we find the minIndex in the unsorted region,</span></a>
<a class="sourceLine" id="cb36-17" title="17">        <span class="co">// swap that minIndex with the first index of the unsorted region</span></a>
<a class="sourceLine" id="cb36-18" title="18">        <span class="at">swap</span>(arr<span class="op">,</span> i<span class="op">,</span> minIndex)<span class="op">;</span></a>
<a class="sourceLine" id="cb36-19" title="19">    <span class="op">}</span></a>
<a class="sourceLine" id="cb36-20" title="20">    <span class="cf">return</span> arr<span class="op">;</span></a>
<a class="sourceLine" id="cb36-21" title="21"><span class="op">}</span></a></code></pre>
                </div>
                <h2 id="time-complexity-analysis">Time Complexity Analysis</h2>
                <p>Selection Sort runtime is O(n<sup>2</sup>) because:</p>
                <ul>
                    <li><code class="language-javascript  highlight" id="button">n</code> is the length of the input
                        array</li>
                    <li>The outer loop i contributes O(n) in isolation, this is plain to see</li>
                    <li>The inner loop j is more complicated, it will make one less iteration for every iteration of i.
                        <ul>
                            <li>for example, let's say we have an array of 10 elements, <code
                                    class="language-javascript  highlight" id="button">n = 10</code>.</li>
                            <li>the first full cycle of <code class="language-javascript  highlight"
                                    id="button">j</code> will have 9 iterations</li>
                            <li>the second full cycle of <code class="language-javascript  highlight"
                                    id="button">j</code> will have 8 iterations</li>
                            <li>the third full cycle of <code class="language-javascript  highlight"
                                    id="button">j</code> will have 7 iterations</li>
                            <li>…</li>
                            <li>the last full cycle of <code class="language-javascript  highlight" id="button">j</code>
                                will have 1 iteration</li>
                            <li>This means that the inner loop j will contribute roughly O(n / 2) on average</li>
                        </ul>
                    </li>
                    <li>The two loops are nested so our total time complexity is O(n * n / 2) = O(n<sup>2</sup>)</li>
                </ul>
                <p>You'll notice that during this analysis we said something silly like O(n / 2). In some analyses such
                    as this
                    one,
                    we'll prefer to drop the constants only at the end of the sketch so you understand the logical steps
                    we took
                    to
                    derive a complicated time complexity.</p>
                <h2 id="space-complexity-analysis-o1">Space Complexity Analysis: O(1)</h2>
                <p>The amount of memory consumed by the algorithm does not increase relative to the size of the input
                    array. We
                    use
                    the same amount of memory and create the same amount of variables regardless of the size of our
                    input. A
                    quick
                    indicator of this is the fact that we don't create any arrays.</p>
                <h2 id="when-should-we-use-selection-sort">When should we use Selection Sort?</h2>
                <p>There is really only one use case where Selection Sort becomes superior to Bubble Sort. Both
                    algorithms are
                    quadratic in time and constant in space, but the point at which they differ is in the <em>number of
                        swaps</em>
                    they make.</p>
                <p>Bubble Sort, in the worst case, invokes a swap on every single comparison. Selection Sort only swaps
                    once our
                    inner loop has completely finished traversing the array. Therefore, Selection Sort is optimized to
                    make the
                    least possible number of swaps.</p>
                <p>Selection Sort becomes advantageous when making a swap is the most expensive operation in your
                    system. You
                    will
                    likely rarely encounter this scenario, but in a situation where you've built (or have inherited) a
                    system
                    with
                    suboptimal write speed ability, for instance, maybe you're sorting data in a specialized database
                    tuned
                    strictly
                    for fast read speeds at the expense of slow write speeds, using Selection Sort would save you a ton
                    of
                    expensive
                    operations that could potential crash your system under peak load.</p>
                <p>Though in industry this situation is very rare, the insights above make for a fantastic
                    conversational piece
                    when
                    weighing technical tradeoffs while strategizing solutions in an interview setting. This commentary
                    may help
                    deliver the impression that you are well-versed in system design and technical analysis, a key
                    indicator
                    that
                    someone is prepared for a senior level position.</p>
                <hr />
                <h1 id="insertion-sort-analysis">Insertion Sort Analysis</h1>
                <p>Take a look at the snippet below and try to understand how it corresponds to our conceptual
                    understanding of
                    the
                    Insertion Sort algorithm. Scroll down to the commented version when you get stuck:</p>
                <div class="sourceCode" id="cb37">
                    <pre data-filter-output="(out)" class="sourceCode javascript" class="sourceCode javascript"><code  class="language-javascript  highlight" id="button" class="sourceCode javascript"><a class="sourceLine" id="cb37-1" title="1"><span class="kw">function</span> <span class="at">insertionSort</span>(arr) <span class="op">{</span></a>
<a class="sourceLine" id="cb37-2" title="2">  <span class="cf">for</span> (<span class="kw">let</span> i <span class="op">=</span> <span class="dv">1</span><span class="op">;</span> i <span class="op">&lt;</span> <span class="va">arr</span>.<span class="at">length</span><span class="op">;</span> i<span class="op">++</span>) <span class="op">{</span></a>
<a class="sourceLine" id="cb37-3" title="3">    <span class="kw">let</span> currElement <span class="op">=</span> arr[i]<span class="op">;</span></a>
<a class="sourceLine" id="cb37-4" title="4">    <span class="cf">for</span> (<span class="kw">var</span> j <span class="op">=</span> i <span class="op">-</span> <span class="dv">1</span><span class="op">;</span> j <span class="op">&gt;=</span> <span class="dv">0</span> <span class="op">&amp;&amp;</span> currElement <span class="op">&lt;</span> arr[j]<span class="op">;</span> j<span class="op">--</span>) <span class="op">{</span></a>
<a class="sourceLine" id="cb37-5" title="5">      arr[j <span class="op">+</span> <span class="dv">1</span>] <span class="op">=</span> arr[j]<span class="op">;</span></a>
<a class="sourceLine" id="cb37-6" title="6">    <span class="op">}</span></a>
<a class="sourceLine" id="cb37-7" title="7">    arr[j <span class="op">+</span> <span class="dv">1</span>] <span class="op">=</span> currElement<span class="op">;</span></a>
<a class="sourceLine" id="cb37-8" title="8">  <span class="op">}</span></a>
<a class="sourceLine" id="cb37-9" title="9">  <span class="cf">return</span> arr<span class="op">;</span></a>
<a class="sourceLine" id="cb37-10" title="10"><span class="op">}</span></a></code></pre>
                </div>
                <div class="sourceCode" id="cb38">
                    <pre data-filter-output="(out)" class="sourceCode javascript" class="sourceCode javascript"><code  class="language-javascript  highlight" id="button" class="sourceCode javascript"><a class="sourceLine" id="cb38-1" title="1"><span class="kw">function</span> <span class="at">insertionSort</span>(arr) <span class="op">{</span></a>
<a class="sourceLine" id="cb38-2" title="2">    <span class="co">// the `i` loop will iterate through every element of the array</span></a>
<a class="sourceLine" id="cb38-3" title="3">    <span class="co">// we begin at i = 1, because we can consider the first element of the array as a</span></a>
<a class="sourceLine" id="cb38-4" title="4">    <span class="co">// trivially sorted region of only one element</span></a>
<a class="sourceLine" id="cb38-5" title="5">    <span class="co">// insertion sort allows us to insert new elements anywhere within the sorted region</span></a>
<a class="sourceLine" id="cb38-6" title="6">    <span class="cf">for</span> (<span class="kw">let</span> i <span class="op">=</span> <span class="dv">1</span><span class="op">;</span> i <span class="op">&lt;</span> <span class="va">arr</span>.<span class="at">length</span><span class="op">;</span> i<span class="op">++</span>) <span class="op">{</span></a>
<a class="sourceLine" id="cb38-7" title="7">        <span class="co">// grab the first element of the unsorted region</span></a>
<a class="sourceLine" id="cb38-8" title="8">        <span class="kw">let</span> currElement <span class="op">=</span> arr[i]<span class="op">;</span></a>
<a class="sourceLine" id="cb38-9" title="9"></a>
<a class="sourceLine" id="cb38-10" title="10">        <span class="co">// the `j` loop will iterate left through the sorted region,</span></a>
<a class="sourceLine" id="cb38-11" title="11">        <span class="co">// looking for a legal spot to insert currElement</span></a>
<a class="sourceLine" id="cb38-12" title="12">        <span class="cf">for</span> (<span class="kw">var</span> j <span class="op">=</span> i <span class="op">-</span> <span class="dv">1</span><span class="op">;</span> j <span class="op">&gt;=</span> <span class="dv">0</span> <span class="op">&amp;&amp;</span> currElement <span class="op">&lt;</span> arr[j]<span class="op">;</span> j<span class="op">--</span>) <span class="op">{</span></a>
<a class="sourceLine" id="cb38-13" title="13">            <span class="co">// keep moving left while currElement is less than the j-th element</span></a>
<a class="sourceLine" id="cb38-14" title="14"></a>
<a class="sourceLine" id="cb38-15" title="15">            arr[j <span class="op">+</span> <span class="dv">1</span>] <span class="op">=</span> arr[j]<span class="op">;</span></a>
<a class="sourceLine" id="cb38-16" title="16">            <span class="co">// the line above will move the j-th element to the right,</span></a>
<a class="sourceLine" id="cb38-17" title="17">            <span class="co">// leaving a gap to potentially insert currElement</span></a>
<a class="sourceLine" id="cb38-18" title="18">        <span class="op">}</span></a>
<a class="sourceLine" id="cb38-19" title="19">        <span class="co">// insert currElement into that gap</span></a>
<a class="sourceLine" id="cb38-20" title="20">        arr[j <span class="op">+</span> <span class="dv">1</span>] <span class="op">=</span> currElement<span class="op">;</span></a>
<a class="sourceLine" id="cb38-21" title="21">    <span class="op">}</span></a>
<a class="sourceLine" id="cb38-22" title="22">    <span class="cf">return</span> arr<span class="op">;</span></a>
<a class="sourceLine" id="cb38-23" title="23"><span class="op">}</span></a></code></pre>
                </div>
                <p>There are a few key pieces to point out in the above solution before moving forward:</p>
                <ol type="1">
                    <li>
                        <p>The outer <code class="language-javascript  highlight" id="button">for</code> loop starts at
                            the 1st index, not the 0th index, and moves to the
                            right.
                        </p>
                    </li>
                    <li>
                        <p>The inner <code class="language-javascript  highlight" id="button">for</code> loop starts
                            immediately to the left of the current element, and
                            moves to
                            the
                            left.</p>
                    </li>
                    <li>The condition for the inner <code class="language-javascript  highlight" id="button">for</code>
                        loop is complicated, and behaves similarly to a
                        while loop!
                        <ul>
                            <li>It continues iterating to the left toward <code class="language-javascript  highlight"
                                    id="button">j = 0</code>, <em>only while</em> the
                                <code class="language-javascript  highlight" id="button">currElement</code> is less than
                                <code class="language-javascript  highlight" id="button">arr[j]</code>.
                            </li>
                            <li>It does this over and over until it finds the proper place to insert
                                <code class="language-javascript  highlight" id="button">currElement</code>,
                                and
                                then we exit the inner loop!
                            </li>
                        </ul>
                    </li>
                    <li>
                        <p>When shifting elements in the sorted region to the right, it <em>does not</em> replace the
                            value at
                            their
                            old index! If the input array is <code class="language-javascript  highlight"
                                id="button">[1, 2, 4, 3]</code>, and <code class="language-javascript  highlight"
                                id="button">currElement</code> is
                            <code class="language-javascript  highlight" id="button">3</code>, after comparing <code
                                class="language-javascript  highlight" id="button">4</code> and <code
                                class="language-javascript  highlight" id="button">3</code>, but before inserting
                            <code class="language-javascript  highlight" id="button">3</code>
                            between <code class="language-javascript  highlight" id="button">2</code> and <code
                                class="language-javascript  highlight" id="button">4</code>, the array will look like
                            this: <code class="language-javascript  highlight" id="button">[1, 2, 4,
                                4]</code>.
                        </p>
                    </li>
                </ol>
                <p>If you are currently scratching your head, that is perfectly okay because when this one clicks, it
                    clicks for
                    good.</p>
                <p>If you're struggling, you should try taking out a pen and paper and step through the solution
                    provided above
                    one
                    step at a time. Keep track of <code class="language-javascript  highlight" id="button">i</code>,
                    <code class="language-javascript  highlight" id="button">j</code>, <code
                        class="language-javascript  highlight" id="button">currElement</code>,
                    <code class="language-javascript  highlight" id="button">arr[j]</code>,
                    and
                    the input <code class="language-javascript  highlight" id="button">arr</code> itself <em>at every
                        step</em>. After going through this a few times,
                    you'll have
                    your
                    "ah HA!" moment.
                </p>
                <h2 id="time-and-space-complexity-analysis">Time and Space Complexity Analysis</h2>
                <p>Insertion Sort runtime is O(n<sup>2</sup>) because:</p>
                <p>In the <strong>worst case scenario</strong> where our input array is entirely unsorted, since this
                    algorithm
                    contains a nested loop, its run time behaves similarly to <code
                        class="language-javascript  highlight" id="button">bubbleSort</code> and
                    <code class="language-javascript  highlight" id="button">selectionSort</code>. In this case, we are
                    forced to make a comparison at each iteration of
                    the inner
                    loop. Not convinced? Let's derive the complexity. We'll use much of the same argument as we did in
                    <code class="language-javascript  highlight" id="button">selectionSort</code>. Say we had the worst
                    case scenario where are input array is sorted in
                    full
                    decreasing order, but we wanted to sort it in increasing order:
                </p>
                <ul>
                    <li><code class="language-javascript  highlight" id="button">n</code> is the length of the input
                        array</li>
                    <li>The outer loop i contributes O(n) in isolation, this is plain to see</li>
                    <li>The inner loop j is more complicated. We know j will iterate until it finds an appropriate place
                        to
                        insert
                        the <code class="language-javascript  highlight" id="button">currElement</code> into the sorted
                        region. However, since we are discussing the case
                        where the
                        data is already in decreasing order, the element must travel the maximum distance to find it's
                        insertion
                        point! We know this insertion point to be index 0, since every <code
                            class="language-javascript  highlight" id="button">currElement</code> will be
                        the next
                        smallest of the array. So:
                        <ul>
                            <li>the 1st element travels 1 distance to be inserted</li>
                            <li>the 2nd element travels 2 distance to be inserted</li>
                            <li>the 3rd element travels 3 distance to be inserted</li>
                            <li>…</li>
                            <li>the n-1th element travels n-1 distance to be inserted</li>
                            <li>This means that our inner loop j will contribute roughly O(n / 2) on average</li>
                        </ul>
                    </li>
                    <li>The two loops are nested so our total time complexity is O(n * n / 2) = O(n<sup>2</sup>)</li>
                </ul>
                <h3 id="space-complexity-o1-1">Space Complexity: O(1)</h3>
                <p>The amount of memory consumed by the algorithm does not increase relative to the size of the input
                    array. We
                    use
                    the same amount of memory and create the same amount of variables regardless of the size of our
                    input. A
                    quick
                    indicator of this is the fact that we don't create any arrays.</p>
                <h2 id="when-should-you-use-insertion-sort">When should you use Insertion Sort?</h2>
                <p>Insertion Sort has one advantage that makes it absolutely supreme in one special case. Insertion Sort
                    is
                    what's
                    known as an "online" algorithm. Online algorithms are great when you're dealing with <em>streaming
                        data</em>,
                    because they can sort the data live <em>as it is received</em>.</p>
                <p>If you must sort a set of data that is ever-incoming, for example, maybe you are sorting the most
                    relevant
                    posts
                    in a social media feed so that those posts that are most likely to impact the site's audience always
                    appear
                    at
                    the top of the feed, an online algorithm like Insertion Sort is a great option.</p>
                <p>Insertion Sort works well in this situation because the left side of the array is always sorted, and
                    in the
                    case
                    of nearly sorted arrays, it can run in linear time. The absolute best case scenario for Insertion
                    Sort is
                    when
                    there is only one unsorted element, and it is located all the way to the right of the array.</p>
                <p>Well, if you have data constantly being pushed to the array, it will always be added to the right
                    side. If
                    you
                    keep your algorithm constantly running, the left side will always be sorted. Now you have linear
                    time sort.
                </p>
                <p>Otherwise, Insertion Sort is, in general, useful in all the same situations as Bubble Sort. It's a
                    good
                    option
                    when:</p>
                <ul>
                    <li>You are sorting really small arrays where run time will be negligible no matter what algorithm
                        we
                        choose.
                    </li>
                    <li>You are sorting an array that you expect to already be nearly sorted.</li>
                </ul>
                <hr />
                <h1 id="merge-sort-analysis">Merge Sort Analysis</h1>
                <p>You needed to come up with two pieces of code to make merge sort work.</p>
                <h2 id="full-code">Full code</h2>
                <div class="sourceCode" id="cb39">
                    <pre data-filter-output="(out)" class="sourceCode javascript" class="sourceCode javascript"><code  class="language-javascript  highlight" id="button" class="sourceCode javascript"><a class="sourceLine" id="cb39-1" title="1"><span class="kw">function</span> <span class="at">merge</span>(array1<span class="op">,</span> array2) <span class="op">{</span></a>
<a class="sourceLine" id="cb39-2" title="2">  <span class="kw">let</span> merged <span class="op">=</span> []<span class="op">;</span></a>
<a class="sourceLine" id="cb39-3" title="3"></a>
<a class="sourceLine" id="cb39-4" title="4">  <span class="cf">while</span> (<span class="va">array1</span>.<span class="at">length</span> <span class="op">||</span> <span class="va">array2</span>.<span class="at">length</span>) <span class="op">{</span></a>
<a class="sourceLine" id="cb39-5" title="5">    <span class="kw">let</span> ele1 <span class="op">=</span> <span class="va">array1</span>.<span class="at">length</span> <span class="op">?</span> array1[<span class="dv">0</span>] : <span class="kw">Infinity</span><span class="op">;</span></a>
<a class="sourceLine" id="cb39-6" title="6">    <span class="kw">let</span> ele2 <span class="op">=</span> <span class="va">array2</span>.<span class="at">length</span> <span class="op">?</span> array2[<span class="dv">0</span>] : <span class="kw">Infinity</span><span class="op">;</span></a>
<a class="sourceLine" id="cb39-7" title="7"></a>
<a class="sourceLine" id="cb39-8" title="8">    <span class="kw">let</span> next<span class="op">;</span></a>
<a class="sourceLine" id="cb39-9" title="9">    <span class="cf">if</span> (ele1 <span class="op">&lt;</span> ele2) <span class="op">{</span></a>
<a class="sourceLine" id="cb39-10" title="10">      next <span class="op">=</span> <span class="va">array1</span>.<span class="at">shift</span>()<span class="op">;</span></a>
<a class="sourceLine" id="cb39-11" title="11">    <span class="op">}</span> <span class="cf">else</span> <span class="op">{</span></a>
<a class="sourceLine" id="cb39-12" title="12">      next <span class="op">=</span> <span class="va">array2</span>.<span class="at">shift</span>()<span class="op">;</span></a>
<a class="sourceLine" id="cb39-13" title="13">    <span class="op">}</span></a>
<a class="sourceLine" id="cb39-14" title="14"></a>
<a class="sourceLine" id="cb39-15" title="15">    <span class="va">merged</span>.<span class="at">push</span>(next)<span class="op">;</span></a>
<a class="sourceLine" id="cb39-16" title="16">  <span class="op">}</span></a>
<a class="sourceLine" id="cb39-17" title="17"></a>
<a class="sourceLine" id="cb39-18" title="18">  <span class="cf">return</span> merged<span class="op">;</span></a>
<a class="sourceLine" id="cb39-19" title="19"><span class="op">}</span></a>
<a class="sourceLine" id="cb39-20" title="20"></a>
<a class="sourceLine" id="cb39-21" title="21"><span class="kw">function</span> <span class="at">mergeSort</span>(array) <span class="op">{</span></a>
<a class="sourceLine" id="cb39-22" title="22">  <span class="cf">if</span> (<span class="va">array</span>.<span class="at">length</span> <span class="op">&lt;=</span> <span class="dv">1</span>) <span class="op">{</span></a>
<a class="sourceLine" id="cb39-23" title="23">    <span class="cf">return</span> array<span class="op">;</span></a>
<a class="sourceLine" id="cb39-24" title="24">  <span class="op">}</span></a>
<a class="sourceLine" id="cb39-25" title="25"></a>
<a class="sourceLine" id="cb39-26" title="26">  <span class="kw">let</span> midIdx <span class="op">=</span> <span class="va">Math</span>.<span class="at">floor</span>(<span class="va">array</span>.<span class="at">length</span> / <span class="dv">2</span>)<span class="op">;</span></a>
<a class="sourceLine" id="cb39-27" title="27">  <span class="kw">let</span> leftHalf <span class="op">=</span> <span class="va">array</span>.<span class="at">slice</span>(<span class="dv">0</span><span class="op">,</span> midIdx)<span class="op">;</span></a>
<a class="sourceLine" id="cb39-28" title="28">  <span class="kw">let</span> rightHalf <span class="op">=</span> <span class="va">array</span>.<span class="at">slice</span>(midIdx)<span class="op">;</span></a>
<a class="sourceLine" id="cb39-29" title="29"></a>
<a class="sourceLine" id="cb39-30" title="30">  <span class="kw">let</span> sortedLeft <span class="op">=</span> <span class="at">mergeSort</span>(leftHalf)<span class="op">;</span></a>
<a class="sourceLine" id="cb39-31" title="31">  <span class="kw">let</span> sortedRight <span class="op">=</span> <span class="at">mergeSort</span>(rightHalf)<span class="op">;</span></a>
<a class="sourceLine" id="cb39-32" title="32"></a>
<a class="sourceLine" id="cb39-33" title="33">  <span class="cf">return</span> <span class="at">merge</span>(sortedLeft<span class="op">,</span> sortedRight)<span class="op">;</span></a>
<a class="sourceLine" id="cb39-34" title="34"><span class="op">}</span></a></code></pre>
                </div>
                <h2 id="merging-two-sorted-arrays">Merging two sorted arrays</h2>
                <p>Merging two sorted arrays is simple. Since both arrays are sorted, we know the smallest numbers to
                    always be
                    at
                    the front of the arrays. We can construct the new array by comparing the first elements of both
                    input
                    arrays. We
                    remove the smaller element from it's respective array and add it to our new array. Do this until
                    both input
                    arrays are empty:</p>
                <div class="sourceCode" id="cb40">
                    <pre data-filter-output="(out)" class="sourceCode javascript" class="sourceCode javascript"><code  class="language-javascript  highlight" id="button" class="sourceCode javascript"><a class="sourceLine" id="cb40-1" title="1"><span class="kw">function</span> <span class="at">merge</span>(array1<span class="op">,</span> array2) <span class="op">{</span></a>
<a class="sourceLine" id="cb40-2" title="2">  <span class="kw">let</span> merged <span class="op">=</span> []<span class="op">;</span></a>
<a class="sourceLine" id="cb40-3" title="3"></a>
<a class="sourceLine" id="cb40-4" title="4">  <span class="cf">while</span> (<span class="va">array1</span>.<span class="at">length</span> <span class="op">||</span> <span class="va">array2</span>.<span class="at">length</span>) <span class="op">{</span></a>
<a class="sourceLine" id="cb40-5" title="5">    <span class="kw">let</span> ele1 <span class="op">=</span> <span class="va">array1</span>.<span class="at">length</span> <span class="op">?</span> array1[<span class="dv">0</span>] : <span class="kw">Infinity</span><span class="op">;</span></a>
<a class="sourceLine" id="cb40-6" title="6">    <span class="kw">let</span> ele2 <span class="op">=</span> <span class="va">array2</span>.<span class="at">length</span> <span class="op">?</span> array2[<span class="dv">0</span>] : <span class="kw">Infinity</span><span class="op">;</span></a>
<a class="sourceLine" id="cb40-7" title="7"></a>
<a class="sourceLine" id="cb40-8" title="8">    <span class="kw">let</span> next<span class="op">;</span></a>
<a class="sourceLine" id="cb40-9" title="9">    <span class="cf">if</span> (ele1 <span class="op">&lt;</span> ele2) <span class="op">{</span></a>
<a class="sourceLine" id="cb40-10" title="10">      next <span class="op">=</span> <span class="va">array1</span>.<span class="at">shift</span>()<span class="op">;</span></a>
<a class="sourceLine" id="cb40-11" title="11">    <span class="op">}</span> <span class="cf">else</span> <span class="op">{</span></a>
<a class="sourceLine" id="cb40-12" title="12">      next <span class="op">=</span> <span class="va">array2</span>.<span class="at">shift</span>()<span class="op">;</span></a>
<a class="sourceLine" id="cb40-13" title="13">    <span class="op">}</span></a>
<a class="sourceLine" id="cb40-14" title="14"></a>
<a class="sourceLine" id="cb40-15" title="15">    <span class="va">merged</span>.<span class="at">push</span>(next)<span class="op">;</span></a>
<a class="sourceLine" id="cb40-16" title="16">  <span class="op">}</span></a>
<a class="sourceLine" id="cb40-17" title="17"></a>
<a class="sourceLine" id="cb40-18" title="18">  <span class="cf">return</span> merged<span class="op">;</span></a>
<a class="sourceLine" id="cb40-19" title="19"><span class="op">}</span></a></code></pre>
                </div>
                <p>Remember the following about JavaScript to understand the above code.</p>
                <ul>
                    <li><code class="language-javascript  highlight" id="button">0</code> is considered a falsey value,
                        meaning it acts like <code class="language-javascript  highlight" id="button">false</code> when
                        used
                        in
                        Boolean
                        expressions. All other numbers are truthy.</li>
                    <li><code class="language-javascript  highlight" id="button">Infinity</code> is a value that is
                        guaranteed to be greater than any other quantity</li>
                    <li><code class="language-javascript  highlight" id="button">shift</code> is an array method that
                        removes and returns the first element</li>
                </ul>
                <p>Here's the annotated version.</p>
                <div class="sourceCode" id="cb41">
                    <pre data-filter-output="(out)" class="sourceCode javascript" class="sourceCode javascript"><code  class="language-javascript  highlight" id="button" class="sourceCode javascript"><a class="sourceLine" id="cb41-1" title="1"><span class="co">// commented</span></a>
<a class="sourceLine" id="cb41-2" title="2"><span class="kw">function</span> <span class="at">merge</span>(array1<span class="op">,</span> array2) <span class="op">{</span></a>
<a class="sourceLine" id="cb41-3" title="3">  <span class="kw">let</span> merged <span class="op">=</span> []<span class="op">;</span></a>
<a class="sourceLine" id="cb41-4" title="4"></a>
<a class="sourceLine" id="cb41-5" title="5">  <span class="co">// keep running while either array still contains elements</span></a>
<a class="sourceLine" id="cb41-6" title="6">  <span class="cf">while</span> (<span class="va">array1</span>.<span class="at">length</span> <span class="op">||</span> <span class="va">array2</span>.<span class="at">length</span>) <span class="op">{</span></a>
<a class="sourceLine" id="cb41-7" title="7">    <span class="co">// if array1 is nonempty, take its the first element as ele1</span></a>
<a class="sourceLine" id="cb41-8" title="8">    <span class="co">// otherwise array1 is empty, so take Infinity as ele1</span></a>
<a class="sourceLine" id="cb41-9" title="9">    <span class="kw">let</span> ele1 <span class="op">=</span> <span class="va">array1</span>.<span class="at">length</span> <span class="op">?</span> array1[<span class="dv">0</span>] : <span class="kw">Infinity</span><span class="op">;</span></a>
<a class="sourceLine" id="cb41-10" title="10"></a>
<a class="sourceLine" id="cb41-11" title="11">    <span class="co">// do the same for array2, ele2</span></a>
<a class="sourceLine" id="cb41-12" title="12">    <span class="kw">let</span> ele2 <span class="op">=</span> <span class="va">array2</span>.<span class="at">length</span> <span class="op">?</span> array2[<span class="dv">0</span>] : <span class="kw">Infinity</span><span class="op">;</span></a>
<a class="sourceLine" id="cb41-13" title="13"></a>
<a class="sourceLine" id="cb41-14" title="14">    <span class="kw">let</span> next<span class="op">;</span></a>
<a class="sourceLine" id="cb41-15" title="15">    <span class="co">// remove the smaller of the eles from it&#39;s array</span></a>
<a class="sourceLine" id="cb41-16" title="16">    <span class="cf">if</span> (ele1 <span class="op">&lt;</span> ele2) <span class="op">{</span></a>
<a class="sourceLine" id="cb41-17" title="17">      next <span class="op">=</span> <span class="va">array1</span>.<span class="at">shift</span>()<span class="op">;</span></a>
<a class="sourceLine" id="cb41-18" title="18">    <span class="op">}</span> <span class="cf">else</span> <span class="op">{</span></a>
<a class="sourceLine" id="cb41-19" title="19">      next <span class="op">=</span> <span class="va">array2</span>.<span class="at">shift</span>()<span class="op">;</span></a>
<a class="sourceLine" id="cb41-20" title="20">    <span class="op">}</span></a>
<a class="sourceLine" id="cb41-21" title="21"></a>
<a class="sourceLine" id="cb41-22" title="22">    <span class="co">// and add that ele to the new array</span></a>
<a class="sourceLine" id="cb41-23" title="23">    <span class="va">merged</span>.<span class="at">push</span>(next)<span class="op">;</span></a>
<a class="sourceLine" id="cb41-24" title="24">  <span class="op">}</span></a>
<a class="sourceLine" id="cb41-25" title="25"></a>
<a class="sourceLine" id="cb41-26" title="26">  <span class="cf">return</span> merged<span class="op">;</span></a>
<a class="sourceLine" id="cb41-27" title="27"><span class="op">}</span></a></code></pre>
                </div>
                <p>By using <code class="language-javascript  highlight" id="button">Infinity</code> as the default
                    element when an array is empty, we are able to
                    elegantly handle
                    the
                    scenario where one array empties before the other. We know that any actual element will be less than
                    <code class="language-javascript  highlight" id="button">Infinity</code> so we will continually take
                    the other element into our merged array.
                </p>
                <p>In other words, we can safely handle this edge case:</p>
                <div class="sourceCode" id="cb42">
                    <pre data-filter-output="(out)" class="sourceCode javascript"
                        class="sourceCode javascript"><code  class="language-javascript  highlight" id="button" class="sourceCode javascript"><a class="sourceLine" id="cb42-1" title="1"><span class="at">merge</span>([<span class="dv">10</span><span class="op">,</span> <span class="dv">13</span><span class="op">,</span> <span class="dv">15</span><span class="op">,</span> <span class="dv">25</span>]<span class="op">,</span> [])<span class="op">;</span>  <span class="co">// =&gt; [10, 13, 15, 25]</span></a></code></pre>
                </div>
                <p>Nice! We now have a way to merge two sorted arrays into a single sorted array. It's worth mentioning
                    that
                    <code class="language-javascript  highlight" id="button">merge</code> will have a <code
                        class="language-javascript  highlight" id="button">O(n)</code> runtime where <code
                        class="language-javascript  highlight" id="button">n</code> is the combined length
                    of the
                    two
                    input arrays. This is what we meant when we said it was "easy" to merge two sorted arrays; linear
                    time is
                    fast!
                    We'll find fact this useful later.
                </p>
                <h2 id="divide-and-conquer-step-by-step">Divide and conquer, step-by-step</h2>
                <p>Now that we satisfied the merge idea, let's handle the second point. That is, we say an array of 1 or
                    0
                    elements
                    is already sorted. This will be the base case of our recursion. Let's begin adding this code:</p>
                <div class="sourceCode" id="cb43">
                    <pre data-filter-output="(out)" class="sourceCode javascript" class="sourceCode javascript"><code  class="language-javascript  highlight" id="button" class="sourceCode javascript"><a class="sourceLine" id="cb43-1" title="1"><span class="kw">function</span> <span class="at">mergeSort</span>(array) <span class="op">{</span></a>
<a class="sourceLine" id="cb43-2" title="2">    <span class="cf">if</span> (<span class="va">array</span>.<span class="at">length</span> <span class="op">&lt;=</span> <span class="dv">1</span>) <span class="op">{</span></a>
<a class="sourceLine" id="cb43-3" title="3">        <span class="cf">return</span> array<span class="op">;</span></a>
<a class="sourceLine" id="cb43-4" title="4">    <span class="op">}</span></a>
<a class="sourceLine" id="cb43-5" title="5">    <span class="co">// ....</span></a>
<a class="sourceLine" id="cb43-6" title="6"><span class="op">}</span></a></code></pre>
                </div>
                <p>If our base case pertains to an array of a very small size, then the design of our recursive case
                    should make
                    progress toward hitting this base scenario. In other words, we should recursively call
                    <code class="language-javascript  highlight" id="button">mergeSort</code> on
                    smaller and smaller arrays. A logical way to do this is to take the input array and split it into
                    left and
                    right
                    halves.
                </p>
                <div class="sourceCode" id="cb44">
                    <pre data-filter-output="(out)" class="sourceCode javascript" class="sourceCode javascript"><code  class="language-javascript  highlight" id="button" class="sourceCode javascript"><a class="sourceLine" id="cb44-1" title="1"><span class="kw">function</span> <span class="at">mergeSort</span>(array) <span class="op">{</span></a>
<a class="sourceLine" id="cb44-2" title="2">    <span class="cf">if</span> (<span class="va">array</span>.<span class="at">length</span> <span class="op">&lt;=</span> <span class="dv">1</span>) <span class="op">{</span></a>
<a class="sourceLine" id="cb44-3" title="3">        <span class="cf">return</span> array<span class="op">;</span></a>
<a class="sourceLine" id="cb44-4" title="4">    <span class="op">}</span></a>
<a class="sourceLine" id="cb44-5" title="5"></a>
<a class="sourceLine" id="cb44-6" title="6">    <span class="kw">let</span> midIdx <span class="op">=</span> <span class="va">Math</span>.<span class="at">floor</span>(<span class="va">array</span>.<span class="at">length</span> / <span class="dv">2</span>)<span class="op">;</span></a>
<a class="sourceLine" id="cb44-7" title="7">    <span class="kw">let</span> leftHalf <span class="op">=</span> <span class="va">array</span>.<span class="at">slice</span>(<span class="dv">0</span><span class="op">,</span> midIdx)<span class="op">;</span></a>
<a class="sourceLine" id="cb44-8" title="8">    <span class="kw">let</span> rightHalf <span class="op">=</span> <span class="va">array</span>.<span class="at">slice</span>(midIdx)<span class="op">;</span></a>
<a class="sourceLine" id="cb44-9" title="9"></a>
<a class="sourceLine" id="cb44-10" title="10">    <span class="kw">let</span> sortedLeft <span class="op">=</span> <span class="at">mergeSort</span>(leftHalf)<span class="op">;</span></a>
<a class="sourceLine" id="cb44-11" title="11">    <span class="kw">let</span> sortedRight <span class="op">=</span> <span class="at">mergeSort</span>(rightHalf)<span class="op">;</span></a>
<a class="sourceLine" id="cb44-12" title="12">    <span class="co">// ...</span></a>
<a class="sourceLine" id="cb44-13" title="13"><span class="op">}</span></a></code></pre>
                </div>
                <p>Here is the part of the recursion where we do a lot of hand waving and we take things on faith. We
                    know that
                    <code class="language-javascript  highlight" id="button">mergeSort</code> will take in an array and
                    return the sorted version; we assume that it works.
                    That
                    means
                    the two recursive calls will return the <code class="language-javascript  highlight"
                        id="button">sortedLeft</code> and <code class="language-javascript  highlight"
                        id="button">sortedRight</code> halves.
                </p>
                <p>Okay, so we have two sorted arrays. We want to return one sorted array. So <code
                        class="language-javascript  highlight" id="button">merge</code> them!
                    Using the
                    <code class="language-javascript  highlight" id="button">merge</code> function we designed earlier:
                </p>
                <div class="sourceCode" id="cb45">
                    <pre data-filter-output="(out)" class="sourceCode javascript" class="sourceCode javascript"><code  class="language-javascript  highlight" id="button" class="sourceCode javascript"><a class="sourceLine" id="cb45-1" title="1"><span class="kw">function</span> <span class="at">mergeSort</span>(array) <span class="op">{</span></a>
<a class="sourceLine" id="cb45-2" title="2">    <span class="cf">if</span> (<span class="va">array</span>.<span class="at">length</span> <span class="op">&lt;=</span> <span class="dv">1</span>) <span class="op">{</span></a>
<a class="sourceLine" id="cb45-3" title="3">        <span class="cf">return</span> array<span class="op">;</span></a>
<a class="sourceLine" id="cb45-4" title="4">    <span class="op">}</span></a>
<a class="sourceLine" id="cb45-5" title="5"></a>
<a class="sourceLine" id="cb45-6" title="6">    <span class="kw">let</span> midIdx <span class="op">=</span> <span class="va">Math</span>.<span class="at">floor</span>(<span class="va">array</span>.<span class="at">length</span> / <span class="dv">2</span>)<span class="op">;</span></a>
<a class="sourceLine" id="cb45-7" title="7">    <span class="kw">let</span> leftHalf <span class="op">=</span> <span class="va">array</span>.<span class="at">slice</span>(<span class="dv">0</span><span class="op">,</span> midIdx)<span class="op">;</span></a>
<a class="sourceLine" id="cb45-8" title="8">    <span class="kw">let</span> rightHalf <span class="op">=</span> <span class="va">array</span>.<span class="at">slice</span>(midIdx)<span class="op">;</span></a>
<a class="sourceLine" id="cb45-9" title="9"></a>
<a class="sourceLine" id="cb45-10" title="10">    <span class="kw">let</span> sortedLeft <span class="op">=</span> <span class="at">mergeSort</span>(leftHalf)<span class="op">;</span></a>
<a class="sourceLine" id="cb45-11" title="11">    <span class="kw">let</span> sortedRight <span class="op">=</span> <span class="at">mergeSort</span>(rightHalf)<span class="op">;</span></a>
<a class="sourceLine" id="cb45-12" title="12"></a>
<a class="sourceLine" id="cb45-13" title="13">    <span class="cf">return</span> <span class="at">merge</span>(sortedLeft<span class="op">,</span> sortedRight)<span class="op">;</span></a>
<a class="sourceLine" id="cb45-14" title="14"><span class="op">}</span></a></code></pre>
                </div>
                <p>Wow. that's it. Notice how light the implementation of <code class="language-javascript  highlight"
                        id="button">mergeSort</code> is. Much of the heavy
                    lifting
                    (the
                    actually comparisons) is done by the <code class="language-javascript  highlight"
                        id="button">merge</code> helper.</p>
                <p><code class="language-javascript  highlight" id="button">mergeSort</code> is a classic example of a
                    "Divide and Conquer" algorithm. In other words, we
                    keep
                    breaking
                    the array into smaller and smaller sub arrays. This is the same as saying we take the problem and
                    break it
                    down
                    into smaller and smaller subproblems. We do this until the subproblems are so small that we
                    trivially know
                    the
                    answer to them (an array length 0 or 1 is already sorted). Once we have those subanswers we can
                    combine to
                    reconstruct the larger problems that we previously divided (merge the left and right subarrays).</p>
                <h2 id="time-and-space-complexity-analysis-1">Time and Space Complexity Analysis</h2>
                <h3 id="time-complexity-on-logn">Time Complexity: O(n log(n))</h3>
                <ul>
                    <li><code class="language-javascript  highlight" id="button">n</code> is the length of the input
                        array</li>
                    <li>We must calculate how many recursive calls we make. The number of recursive calls is the number
                        of times
                        we
                        must split the array to reach the base case. Since we split in half each time, the number of
                        recursive
                        calls
                        is <code class="language-javascript  highlight" id="button">O(log(n))</code>.
                        <ul>
                            <li>for example, say we had an array of length <code class="language-javascript  highlight"
                                    id="button">32</code></li>
                            <li>then the length would change as <code class="language-javascript  highlight"
                                    id="button">32 -&gt; 16 -&gt; 8 -&gt; 4 -&gt; 2 -&gt;
                                    1</code>, we
                                have to
                                split 5 times before reaching the base case, <code
                                    class="language-javascript  highlight" id="button">log(32) = 5</code></li>
                            <li>in our algorithm, <strong>log(n)</strong> describes how many times we must halve
                                <strong>n</strong>
                                until the quantity reaches 1.
                            </li>
                        </ul>
                    </li>
                    <li>Besides the recursive calls, we must consider the while loop within the <code
                            class="language-javascript  highlight" id="button">merge</code>
                        function,
                        which
                        contributes <code class="language-javascript  highlight" id="button">O(n)</code> in isolation
                    </li>
                    <li>We call <code class="language-javascript  highlight" id="button">merge</code> in every recursive
                        <code class="language-javascript  highlight" id="button">mergeSort</code> call, so the total
                        complexity is
                        <strong>O(n * log(n))</strong>
                    </li>
                </ul>
                <h3 id="space-complexity-on">Space Complexity: O(n)</h3>
                <p>Merge Sort is the first non-O(1) space sorting algorithm we've seen thus far.</p>
                <p>The larger the size of our input array, the greater the number of subarrays we must create in memory.
                    These
                    are
                    not free! They each take up finite space, and we will need a new subarray for each element in the
                    original
                    input. Therefore, Merge Sort has a linear space complexity, O(n).</p>
                <h3 id="when-should-you-use-merge-sort">When should you use Merge Sort?</h3>
                <p>Unless we, the engineers, have access in advance to some unique, exploitable insight about our
                    dataset, it
                    turns
                    out that O(n log n) time is <em>the best</em> we can do when sorting unknown datasets.</p>
                <p>That means that Merge Sort is fast! It's way faster than Bubble Sort, Selection Sort, and Insertion
                    Sort.
                    However, due to its linear space complexity, we must always weigh the trade off between speed and
                    memory
                    consumption when making the choice to use Merge Sort. Consider the following:</p>
                <ul>
                    <li>If you have unlimited memory available, use it, it's fast!</li>
                    <li>If you have a decent amount of memory available and a medium sized dataset, run some tests
                        first, but
                        use
                        it!</li>
                    <li>In other cases, maybe you should consider other options.</li>
                </ul>
                <hr />
                <h1 id="quick-sort-analysis">Quick Sort Analysis</h1>
                <p>Let's begin structuring the recursion. The base case of any recursive problem is where the input is
                    so
                    trivial,
                    we immediately know the answer without calculation. If our problem is to sort an array, what is the
                    trivial
                    array? An array of 1 or 0 elements! Let's establish the code:</p>
                <div class="sourceCode" id="cb46">
                    <pre data-filter-output="(out)" class="sourceCode javascript" class="sourceCode javascript"><code  class="language-javascript  highlight" id="button" class="sourceCode javascript"><a class="sourceLine" id="cb46-1" title="1"><span class="kw">function</span> <span class="at">quickSort</span>(array) <span class="op">{</span></a>
<a class="sourceLine" id="cb46-2" title="2">    <span class="cf">if</span> (<span class="va">array</span>.<span class="at">length</span> <span class="op">&lt;=</span> <span class="dv">1</span>) <span class="op">{</span></a>
<a class="sourceLine" id="cb46-3" title="3">        <span class="cf">return</span> array<span class="op">;</span></a>
<a class="sourceLine" id="cb46-4" title="4">    <span class="op">}</span></a>
<a class="sourceLine" id="cb46-5" title="5">    <span class="co">// ...</span></a>
<a class="sourceLine" id="cb46-6" title="6"><span class="op">}</span></a></code></pre>
                </div>
                <p>If our base case pertains to an array of a very small size, then the design of our recursive case
                    should make
                    progress toward hitting this base scenario. In other words, we should recursively call
                    <code class="language-javascript  highlight" id="button">quickSort</code> on
                    smaller and smaller arrays. This is very similar to our previous <code
                        class="language-javascript  highlight" id="button">mergeSort</code>, except we
                    don't
                    just
                    split the array down the middle. Instead we should arbitrarily choose an element of the array as a
                    pivot and
                    partition the remaining elements relative to this pivot:
                </p>
                <div class="sourceCode" id="cb47">
                    <pre data-filter-output="(out)" class="sourceCode javascript" class="sourceCode javascript"><code  class="language-javascript  highlight" id="button" class="sourceCode javascript"><a class="sourceLine" id="cb47-1" title="1"><span class="kw">function</span> <span class="at">quickSort</span>(array) <span class="op">{</span></a>
<a class="sourceLine" id="cb47-2" title="2">    <span class="cf">if</span> (<span class="va">array</span>.<span class="at">length</span> <span class="op">&lt;=</span> <span class="dv">1</span>) <span class="op">{</span></a>
<a class="sourceLine" id="cb47-3" title="3">        <span class="cf">return</span> array<span class="op">;</span></a>
<a class="sourceLine" id="cb47-4" title="4">    <span class="op">}</span></a>
<a class="sourceLine" id="cb47-5" title="5"></a>
<a class="sourceLine" id="cb47-6" title="6">    <span class="kw">let</span> pivot <span class="op">=</span> <span class="va">array</span>.<span class="at">shift</span>()<span class="op">;</span></a>
<a class="sourceLine" id="cb47-7" title="7">    <span class="kw">let</span> left <span class="op">=</span> <span class="va">array</span>.<span class="at">filter</span>(el <span class="kw">=&gt;</span> el <span class="op">&lt;</span> pivot)<span class="op">;</span></a>
<a class="sourceLine" id="cb47-8" title="8">    <span class="kw">let</span> right <span class="op">=</span> <span class="va">array</span>.<span class="at">filter</span>(el <span class="kw">=&gt;</span> el <span class="op">&gt;=</span> pivot)<span class="op">;</span></a>
<a class="sourceLine" id="cb47-9" title="9">    <span class="co">// ...</span></a></code></pre>
                </div>
                <p>Here is what to notice about the partition step above: 1. the pivot is an element of the array; we
                    arbitrarily
                    chose the first element 2. we removed the pivot from the master array before we filter into the left
                    and
                    right
                    partitions</p>
                <p>Now that we have the two subarrays of <code class="language-javascript  highlight"
                        id="button">left</code> and <code class="language-javascript  highlight"
                        id="button">right</code> we have our
                    subproblems! To
                    solve
                    these subproblems we must sort the subarrays. I wish we had a function that sorts an array…oh wait
                    we do,
                    <code class="language-javascript  highlight" id="button">quickSort</code>! Recursively:
                </p>
                <div class="sourceCode" id="cb48">
                    <pre data-filter-output="(out)" class="sourceCode javascript" class="sourceCode javascript"><code  class="language-javascript  highlight" id="button" class="sourceCode javascript"><a class="sourceLine" id="cb48-1" title="1"><span class="kw">function</span> <span class="at">quickSort</span>(array) <span class="op">{</span></a>
<a class="sourceLine" id="cb48-2" title="2">    <span class="cf">if</span> (<span class="va">array</span>.<span class="at">length</span> <span class="op">&lt;=</span> <span class="dv">1</span>) <span class="op">{</span></a>
<a class="sourceLine" id="cb48-3" title="3">        <span class="cf">return</span> array<span class="op">;</span></a>
<a class="sourceLine" id="cb48-4" title="4">    <span class="op">}</span></a>
<a class="sourceLine" id="cb48-5" title="5"></a>
<a class="sourceLine" id="cb48-6" title="6">    <span class="kw">let</span> pivot <span class="op">=</span> <span class="va">array</span>.<span class="at">shift</span>()<span class="op">;</span></a>
<a class="sourceLine" id="cb48-7" title="7">    <span class="kw">let</span> left <span class="op">=</span> <span class="va">array</span>.<span class="at">filter</span>(el <span class="kw">=&gt;</span> el <span class="op">&lt;</span> pivot)<span class="op">;</span></a>
<a class="sourceLine" id="cb48-8" title="8">    <span class="kw">let</span> right <span class="op">=</span> <span class="va">array</span>.<span class="at">filter</span>(el <span class="kw">=&gt;</span> el <span class="op">&gt;=</span> pivot)<span class="op">;</span></a>
<a class="sourceLine" id="cb48-9" title="9"></a>
<a class="sourceLine" id="cb48-10" title="10">    <span class="kw">let</span> leftSorted <span class="op">=</span> <span class="at">quickSort</span>(left)<span class="op">;</span></a>
<a class="sourceLine" id="cb48-11" title="11">    <span class="kw">let</span> rightSorted <span class="op">=</span> <span class="at">quickSort</span>(right)<span class="op">;</span></a>
<a class="sourceLine" id="cb48-12" title="12">    <span class="co">// ...</span></a></code></pre>
                </div>
                <p>Okay, so we have the two sorted partitions. This means we have the two subsolutions. But how do we
                    put them
                    together? Think about how we partitioned them in the first place. Everything in
                    <code class="language-javascript  highlight" id="button">leftSorted</code> is
                    <strong>guaranteed</strong> to be less than everything in <code
                        class="language-javascript  highlight" id="button">rightSorted</code>. On top of that,
                    <code class="language-javascript  highlight" id="button">pivot</code> should be placed after the
                    last element in <code class="language-javascript  highlight" id="button">leftSorted</code>, but
                    before
                    the first
                    element in <code class="language-javascript  highlight" id="button">rightSorted</code>. So all we
                    need to do is to combine the elements in the order
                    "left,
                    pivot,
                    right"!
                </p>
                <div class="sourceCode" id="cb49">
                    <pre data-filter-output="(out)" class="sourceCode javascript" class="sourceCode javascript"><code  class="language-javascript  highlight" id="button" class="sourceCode javascript"><a class="sourceLine" id="cb49-1" title="1"><span class="kw">function</span> <span class="at">quickSort</span>(array) <span class="op">{</span></a>
<a class="sourceLine" id="cb49-2" title="2">    <span class="cf">if</span> (<span class="va">array</span>.<span class="at">length</span> <span class="op">&lt;=</span> <span class="dv">1</span>) <span class="op">{</span></a>
<a class="sourceLine" id="cb49-3" title="3">        <span class="cf">return</span> array<span class="op">;</span></a>
<a class="sourceLine" id="cb49-4" title="4">    <span class="op">}</span></a>
<a class="sourceLine" id="cb49-5" title="5"></a>
<a class="sourceLine" id="cb49-6" title="6">    <span class="kw">let</span> pivot <span class="op">=</span> <span class="va">array</span>.<span class="at">shift</span>()<span class="op">;</span></a>
<a class="sourceLine" id="cb49-7" title="7">    <span class="kw">let</span> left <span class="op">=</span> <span class="va">array</span>.<span class="at">filter</span>(el <span class="kw">=&gt;</span> el <span class="op">&lt;</span> pivot)<span class="op">;</span></a>
<a class="sourceLine" id="cb49-8" title="8">    <span class="kw">let</span> right <span class="op">=</span> <span class="va">array</span>.<span class="at">filter</span>(el <span class="kw">=&gt;</span> el <span class="op">&gt;=</span> pivot)<span class="op">;</span></a>
<a class="sourceLine" id="cb49-9" title="9"></a>
<a class="sourceLine" id="cb49-10" title="10">    <span class="kw">let</span> leftSorted <span class="op">=</span> <span class="at">quickSort</span>(left)<span class="op">;</span></a>
<a class="sourceLine" id="cb49-11" title="11">    <span class="kw">let</span> rightSorted <span class="op">=</span> <span class="at">quickSort</span>(right)<span class="op">;</span></a>
<a class="sourceLine" id="cb49-12" title="12"></a>
<a class="sourceLine" id="cb49-13" title="13">    <span class="cf">return</span> <span class="va">leftSorted</span>.<span class="at">concat</span>([pivot]).<span class="at">concat</span>(rightSorted)<span class="op">;</span></a>
<a class="sourceLine" id="cb49-14" title="14"><span class="op">}</span></a></code></pre>
                </div>
                <p>That last <code class="language-javascript  highlight" id="button">concat</code> line is a bit
                    clunky. Bonus JS Lesson: we can use the spread
                    <code class="language-javascript  highlight" id="button">...</code>
                    operator to elegantly concatenate arrays. In general:
                </p>
                <div class="sourceCode" id="cb50">
                    <pre data-filter-output="(out)" class="sourceCode javascript"
                        class="sourceCode javascript"><code  class="language-javascript  highlight" id="button" class="sourceCode javascript"><a class="sourceLine" id="cb50-1" title="1"><span class="kw">let</span> one <span class="op">=</span> [<span class="st">&#39;a&#39;</span><span class="op">,</span> <span class="st">&#39;b&#39;</span>]</a>
<a class="sourceLine" id="cb50-2" title="2"><span class="kw">let</span> two <span class="op">=</span> [<span class="st">&#39;d&#39;</span><span class="op">,</span> <span class="st">&#39;e&#39;</span><span class="op">,</span> <span class="st">&#39;f&#39;</span>]</a>
<a class="sourceLine" id="cb50-3" title="3"><span class="kw">let</span> newArr <span class="op">=</span> [ ...<span class="at">one</span><span class="op">,</span> <span class="st">&#39;c&#39;</span><span class="op">,</span> ...<span class="at">two</span>  ]<span class="op">;</span></a>
<a class="sourceLine" id="cb50-4" title="4">newArr<span class="op">;</span> <span class="co">// =&gt;  [ &#39;a&#39;, &#39;b&#39;, &#39;c&#39;, &#39;d&#39;, &#39;e&#39;, &#39;f&#39; ]</span></a></code></pre>
                </div>
                <p>Utilizing that spread pattern gives us this final implementation:</p>
                <div class="sourceCode" id="cb51">
                    <pre data-filter-output="(out)" class="sourceCode javascript" class="sourceCode javascript"><code  class="language-javascript  highlight" id="button" class="sourceCode javascript"><a class="sourceLine" id="cb51-1" title="1"><span class="kw">function</span> <span class="at">quickSort</span>(array) <span class="op">{</span></a>
<a class="sourceLine" id="cb51-2" title="2">    <span class="cf">if</span> (<span class="va">array</span>.<span class="at">length</span> <span class="op">&lt;=</span> <span class="dv">1</span>) <span class="op">{</span></a>
<a class="sourceLine" id="cb51-3" title="3">        <span class="cf">return</span> array<span class="op">;</span></a>
<a class="sourceLine" id="cb51-4" title="4">    <span class="op">}</span></a>
<a class="sourceLine" id="cb51-5" title="5"></a>
<a class="sourceLine" id="cb51-6" title="6">    <span class="kw">let</span> pivot <span class="op">=</span> <span class="va">array</span>.<span class="at">shift</span>()<span class="op">;</span></a>
<a class="sourceLine" id="cb51-7" title="7">    <span class="kw">let</span> left <span class="op">=</span> <span class="va">array</span>.<span class="at">filter</span>(el <span class="kw">=&gt;</span> el <span class="op">&lt;</span> pivot)<span class="op">;</span></a>
<a class="sourceLine" id="cb51-8" title="8">    <span class="kw">let</span> right <span class="op">=</span> <span class="va">array</span>.<span class="at">filter</span>(el <span class="kw">=&gt;</span> el <span class="op">&gt;=</span> pivot)<span class="op">;</span></a>
<a class="sourceLine" id="cb51-9" title="9"></a>
<a class="sourceLine" id="cb51-10" title="10">    <span class="kw">let</span> leftSorted <span class="op">=</span> <span class="at">quickSort</span>(left)<span class="op">;</span></a>
<a class="sourceLine" id="cb51-11" title="11">    <span class="kw">let</span> rightSorted <span class="op">=</span> <span class="at">quickSort</span>(right)<span class="op">;</span></a>
<a class="sourceLine" id="cb51-12" title="12"></a>
<a class="sourceLine" id="cb51-13" title="13">    <span class="cf">return</span> [ ...<span class="at">leftSorted</span><span class="op">,</span> pivot<span class="op">,</span> ...<span class="at">rightSorted</span> ]<span class="op">;</span></a>
<a class="sourceLine" id="cb51-14" title="14"><span class="op">}</span></a></code></pre>
                </div>
                <h3 id="quicksort-sort-js-implementation">Quicksort Sort JS Implementation</h3>
                <p>That code was so clean we should show it again. Here's the complete code for your reference, for when
                    you
                    <code class="language-javascript  highlight" id="button">ctrl+F "quicksort"</code> the night before
                    an interview:
                </p>
                <div class="sourceCode" id="cb52">
                    <pre data-filter-output="(out)" class="sourceCode javascript" class="sourceCode javascript"><code  class="language-javascript  highlight" id="button" class="sourceCode javascript"><a class="sourceLine" id="cb52-1" title="1"><span class="kw">function</span> <span class="at">quickSort</span>(array) <span class="op">{</span></a>
<a class="sourceLine" id="cb52-2" title="2">    <span class="cf">if</span> (<span class="va">array</span>.<span class="at">length</span> <span class="op">&lt;=</span> <span class="dv">1</span>) <span class="op">{</span></a>
<a class="sourceLine" id="cb52-3" title="3">        <span class="cf">return</span> array<span class="op">;</span></a>
<a class="sourceLine" id="cb52-4" title="4">    <span class="op">}</span></a>
<a class="sourceLine" id="cb52-5" title="5"></a>
<a class="sourceLine" id="cb52-6" title="6">    <span class="kw">let</span> pivot <span class="op">=</span> <span class="va">array</span>.<span class="at">shift</span>()<span class="op">;</span></a>
<a class="sourceLine" id="cb52-7" title="7">    <span class="kw">let</span> left <span class="op">=</span> <span class="va">array</span>.<span class="at">filter</span>(el <span class="kw">=&gt;</span> el <span class="op">&lt;</span> pivot)<span class="op">;</span></a>
<a class="sourceLine" id="cb52-8" title="8">    <span class="kw">let</span> right <span class="op">=</span> <span class="va">array</span>.<span class="at">filter</span>(el <span class="kw">=&gt;</span> el <span class="op">&gt;=</span> pivot)<span class="op">;</span></a>
<a class="sourceLine" id="cb52-9" title="9"></a>
<a class="sourceLine" id="cb52-10" title="10">    <span class="kw">let</span> leftSorted <span class="op">=</span> <span class="at">quickSort</span>(left)<span class="op">;</span></a>
<a class="sourceLine" id="cb52-11" title="11">    <span class="kw">let</span> rightSorted <span class="op">=</span> <span class="at">quickSort</span>(right)<span class="op">;</span></a>
<a class="sourceLine" id="cb52-12" title="12"></a>
<a class="sourceLine" id="cb52-13" title="13">    <span class="cf">return</span> [ ...<span class="at">leftSorted</span><span class="op">,</span> pivot<span class="op">,</span> ...<span class="at">rightSorted</span> ]<span class="op">;</span></a>
<a class="sourceLine" id="cb52-14" title="14"><span class="op">}</span></a></code></pre>
                </div>
                <h2 id="time-and-space-complexity-analysis-2">Time and Space Complexity Analysis</h2>
                <p>Here is a summary of the complexity.</p>
                <h3 id="time-complexity">Time Complexity</h3>
                <ul>
                    <li>Avg Case: O(n log(n))</li>
                    <li>Worst Case: O(n<sup>2</sup>)</li>
                </ul>
                <p>The runtime analysis of <code class="language-javascript  highlight" id="button">quickSort</code> is
                    more complex than <code class="language-javascript  highlight" id="button">mergeSort</code></p>
                <ul>
                    <li><code class="language-javascript  highlight" id="button">n</code> is the length of the input
                        array</li>
                    <li>The partition step alone is <code class="language-javascript  highlight" id="button">O(n)</code>
                    </li>
                    <li>We must calculate how many recursive calls we make. The number of recursive calls is the number
                        of times
                        we
                        must split the array to reach the base case. This is dependent on how we choose the pivot. Let's
                        analyze
                        the
                        best and worst case:
                        <ul>
                            <li><strong>Best Case:</strong> We are lucky and always choose the median as the pivot. This
                                means
                                the
                                left and right partitions will have equal length. This will halve the array length at
                                every step
                                of
                                the recursion. We benefit from this halving with <code
                                    class="language-javascript  highlight" id="button">O(log(n))</code> recursive calls
                                to reach
                                the
                                base case.</li>
                            <li><strong>Worst Case:</strong> We are unlucky and always choose the min or max as the
                                pivot. This
                                means one partition will contain everything, and the other partition is empty. This will
                                decrease
                                the array length by 1 at every step of the recursion. We suffer from <code
                                    class="language-javascript  highlight" id="button">O(n)</code>
                                recursive
                                calls to reach the base case.</li>
                        </ul>
                    </li>
                    <li>The partition step occurs in every recursive call, so our total complexities are:
                        <ul>
                            <li><strong>Best Case:</strong> O(n * log(n))</li>
                            <li><strong>Worst Case:</strong> O(n<sup>2</sup>)</li>
                        </ul>
                    </li>
                </ul>
                <p>Although we typically take the worst case when describing Big-O for an algorithm, much research on
                    <code class="language-javascript  highlight" id="button">quickSort</code> has shown the worst case
                    to be an exceedingly rare occurrence even if we
                    choose the
                    pivot
                    at random. Because of this we still consider <code class="language-javascript  highlight"
                        id="button">quickSort</code> an efficient algorithm. This is
                    a common
                    interview talking point, so you should be familiar with the relationship between the choice of pivot
                    and
                    efficiency of the algorithm.
                </p>
                <p>Just in case: A somewhat common question a student may ask when studying <code
                        class="language-javascript  highlight" id="button">quickSort</code> is,
                    "If the
                    median is the best pivot, why don't we always just choose the median when we partition?" Don't
                    overthink
                    this.
                    To know the median of an array, it must be sorted in the first place.</p>
                <h3 id="space-complexity">Space Complexity</h3>
                <p>Our implementation of <code class="language-javascript  highlight" id="button">quickSort</code> uses
                    <code class="language-javascript  highlight" id="button">O(n)</code> space because of the partition
                    arrays we
                    create. There is an in-place version of <code class="language-javascript  highlight"
                        id="button">quickSort</code> that uses <code class="language-javascript  highlight"
                        id="button">O(log(n))</code>
                    space.
                    <code class="language-javascript  highlight" id="button">O(log(n))</code> space is not huge benefit
                    over <code class="language-javascript  highlight" id="button">O(n)</code>. You'll also find our
                    version of
                    <code class="language-javascript  highlight" id="button">quickSort</code> as easier to remember,
                    easier to implement. Just know that a
                    <code class="language-javascript  highlight" id="button">O(logn)</code>
                    space
                    <code class="language-javascript  highlight" id="button">quickSort</code> exists.
                </p>
                <h3 id="when-should-you-use-quick-sort">When should you use Quick Sort?</h3>
                <ul>
                    <li>When you are in a pinch and need to throw down an efficient sort (on average). The recursive
                        code is
                        light
                        and simple to implement; much smaller than <code class="language-javascript  highlight"
                            id="button">mergeSort</code>.</li>
                    <li>When constant space is important to you, use the in-place version. This will of course trade off
                        some
                        simplicity of implementation.</li>
                </ul>
                <p>If you know some constraints about dataset you can make some modifications to optimize pivot choice.
                    Here's
                    some
                    food for thought. Our implementation of <code class="language-javascript  highlight"
                        id="button">quickSort</code> will always take the first element as
                    the
                    pivot.
                    This means we will suffer from the worst case time complexity in the event that we are given an
                    already
                    sorted
                    array (ironic isn't it?). If you know your input data to be mostly already sorted, randomize the
                    choice of
                    pivot
                    - this is a very easy change. Bam. Solved like a true engineer.</p>
                <hr />
                <h1 id="binary-search-analysis">Binary Search Analysis</h1>
                <p>We'll implement binary search recursively. As always, we start with a base case that captures the
                    scenario of
                    the
                    input array being so trivial, that we know the answer without further calculation. If we are given
                    an empty
                    array and a target, we can be certain that the target is not inside of the array:</p>
                <div class="sourceCode" id="cb53">
                    <pre data-filter-output="(out)" class="sourceCode javascript" class="sourceCode javascript"><code  class="language-javascript  highlight" id="button" class="sourceCode javascript"><a class="sourceLine" id="cb53-1" title="1"><span class="kw">function</span> <span class="at">binarySearch</span>(array<span class="op">,</span> target) <span class="op">{</span></a>
<a class="sourceLine" id="cb53-2" title="2">    <span class="cf">if</span> (<span class="va">array</span>.<span class="at">length</span> <span class="op">===</span> <span class="dv">0</span>) <span class="op">{</span></a>
<a class="sourceLine" id="cb53-3" title="3">        <span class="cf">return</span> <span class="kw">false</span><span class="op">;</span></a>
<a class="sourceLine" id="cb53-4" title="4">    <span class="op">}</span></a>
<a class="sourceLine" id="cb53-5" title="5">    <span class="co">// ...</span></a>
<a class="sourceLine" id="cb53-6" title="6"><span class="op">}</span></a></code></pre>
                </div>
                <p>Now for our recursive case. If we want to get a time complexity less than <code
                        class="language-javascript  highlight" id="button">O(n)</code>, we must
                    avoid
                    touching all <code class="language-javascript  highlight" id="button">n</code> elements. Adopting
                    our dictionary strategy, let's find the middle
                    element and
                    grab
                    references to the left and right halves of the sorted array:</p>
                <div class="sourceCode" id="cb54">
                    <pre data-filter-output="(out)" class="sourceCode javascript" class="sourceCode javascript"><code  class="language-javascript  highlight" id="button" class="sourceCode javascript"><a class="sourceLine" id="cb54-1" title="1"><span class="kw">function</span> <span class="at">binarySearch</span>(array<span class="op">,</span> target) <span class="op">{</span></a>
<a class="sourceLine" id="cb54-2" title="2">    <span class="cf">if</span> (<span class="va">array</span>.<span class="at">length</span> <span class="op">===</span> <span class="dv">0</span>) <span class="op">{</span></a>
<a class="sourceLine" id="cb54-3" title="3">        <span class="cf">return</span> <span class="kw">false</span><span class="op">;</span></a>
<a class="sourceLine" id="cb54-4" title="4">    <span class="op">}</span></a>
<a class="sourceLine" id="cb54-5" title="5"></a>
<a class="sourceLine" id="cb54-6" title="6">    <span class="kw">let</span> midIdx <span class="op">=</span> <span class="va">Math</span>.<span class="at">floor</span>(<span class="va">array</span>.<span class="at">length</span> / <span class="dv">2</span>)<span class="op">;</span></a>
<a class="sourceLine" id="cb54-7" title="7">    <span class="kw">let</span> leftHalf <span class="op">=</span> <span class="va">array</span>.<span class="at">slice</span>(<span class="dv">0</span><span class="op">,</span> midIdx)<span class="op">;</span></a>
<a class="sourceLine" id="cb54-8" title="8">    <span class="kw">let</span> rightHalf <span class="op">=</span> <span class="va">array</span>.<span class="at">slice</span>(midIdx <span class="op">+</span> <span class="dv">1</span>)<span class="op">;</span></a>
<a class="sourceLine" id="cb54-9" title="9">    <span class="co">// ...</span></a>
<a class="sourceLine" id="cb54-10" title="10"><span class="op">}</span></a></code></pre>
                </div>
                <p>It's worth pointing out that the left and right halves do not contain the middle element we chose.
                </p>
                <p>Here is where we leverage the sorted property of the array. If the target is less than the middle,
                    then the
                    target must be in the left half of the array. If the target is greater than the middle, then the
                    target must
                    be
                    in the right half of the array. So we can narrow our search to one of these halves, and ignore the
                    other.
                    Luckily we have a function that can search the half, its <code
                        class="language-javascript  highlight" id="button">binarySearch</code>:</p>
                <div class="sourceCode" id="cb55">
                    <pre data-filter-output="(out)" class="sourceCode javascript" class="sourceCode javascript"><code  class="language-javascript  highlight" id="button" class="sourceCode javascript"><a class="sourceLine" id="cb55-1" title="1"><span class="kw">function</span> <span class="at">binarySearch</span>(array<span class="op">,</span> target) <span class="op">{</span></a>
<a class="sourceLine" id="cb55-2" title="2">    <span class="cf">if</span> (<span class="va">array</span>.<span class="at">length</span> <span class="op">===</span> <span class="dv">0</span>) <span class="op">{</span></a>
<a class="sourceLine" id="cb55-3" title="3">        <span class="cf">return</span> <span class="kw">false</span><span class="op">;</span></a>
<a class="sourceLine" id="cb55-4" title="4">    <span class="op">}</span></a>
<a class="sourceLine" id="cb55-5" title="5"></a>
<a class="sourceLine" id="cb55-6" title="6">    <span class="kw">let</span> midIdx <span class="op">=</span> <span class="va">Math</span>.<span class="at">floor</span>(<span class="va">array</span>.<span class="at">length</span> / <span class="dv">2</span>)<span class="op">;</span></a>
<a class="sourceLine" id="cb55-7" title="7">    <span class="kw">let</span> leftHalf <span class="op">=</span> <span class="va">array</span>.<span class="at">slice</span>(<span class="dv">0</span><span class="op">,</span> midIdx)<span class="op">;</span></a>
<a class="sourceLine" id="cb55-8" title="8">    <span class="kw">let</span> rightHalf <span class="op">=</span> <span class="va">array</span>.<span class="at">slice</span>(midIdx <span class="op">+</span> <span class="dv">1</span>)<span class="op">;</span></a>
<a class="sourceLine" id="cb55-9" title="9"></a>
<a class="sourceLine" id="cb55-10" title="10">    <span class="cf">if</span> (target <span class="op">&lt;</span> array[midIdx]) <span class="op">{</span></a>
<a class="sourceLine" id="cb55-11" title="11">        <span class="cf">return</span> <span class="at">binarySearch</span>(leftHalf<span class="op">,</span> target)<span class="op">;</span></a>
<a class="sourceLine" id="cb55-12" title="12">    <span class="op">}</span> <span class="cf">else</span> <span class="cf">if</span> (target <span class="op">&gt;</span> array[midIdx]) <span class="op">{</span></a>
<a class="sourceLine" id="cb55-13" title="13">        <span class="cf">return</span> <span class="at">binarySearch</span>(rightHalf<span class="op">,</span> target)<span class="op">;</span></a>
<a class="sourceLine" id="cb55-14" title="14">    <span class="op">}</span></a>
<a class="sourceLine" id="cb55-15" title="15">    <span class="co">// ...</span></a>
<a class="sourceLine" id="cb55-16" title="16"><span class="op">}</span></a></code></pre>
                </div>
                <p>We know <code class="language-javascript  highlight" id="button">binarySeach</code> will return the
                    correct Boolean, so we just pass that result up by
                    returning
                    it
                    ourselves. However, something is lacking in our code. It is only possible to get a false from the
                    literal
                    <code class="language-javascript  highlight" id="button">return false</code> line, but there is no
                    <code class="language-javascript  highlight" id="button">return true</code>. Looking at our
                    conditionals, we
                    handle
                    the cases where the target is less than middle or the target is greater than the middle, but what if
                    the
                    product
                    is <strong>equal</strong> to the middle? If the target is equal to the middle, then we found the
                    target and
                    should <code class="language-javascript  highlight" id="button">return true</code>! This is easy to
                    add with an <code class="language-javascript  highlight" id="button">else</code>:
                </p>
                <div class="sourceCode" id="cb56">
                    <pre data-filter-output="(out)" class="sourceCode javascript" class="sourceCode javascript"><code  class="language-javascript  highlight" id="button" class="sourceCode javascript"><a class="sourceLine" id="cb56-1" title="1"><span class="kw">function</span> <span class="at">binarySearch</span>(array<span class="op">,</span> target) <span class="op">{</span></a>
<a class="sourceLine" id="cb56-2" title="2">    <span class="cf">if</span> (<span class="va">array</span>.<span class="at">length</span> <span class="op">===</span> <span class="dv">0</span>) <span class="op">{</span></a>
<a class="sourceLine" id="cb56-3" title="3">        <span class="cf">return</span> <span class="kw">false</span><span class="op">;</span></a>
<a class="sourceLine" id="cb56-4" title="4">    <span class="op">}</span></a>
<a class="sourceLine" id="cb56-5" title="5"></a>
<a class="sourceLine" id="cb56-6" title="6">    <span class="kw">let</span> midIdx <span class="op">=</span> <span class="va">Math</span>.<span class="at">floor</span>(<span class="va">array</span>.<span class="at">length</span> / <span class="dv">2</span>)<span class="op">;</span></a>
<a class="sourceLine" id="cb56-7" title="7">    <span class="kw">let</span> leftHalf <span class="op">=</span> <span class="va">array</span>.<span class="at">slice</span>(<span class="dv">0</span><span class="op">,</span> midIdx)<span class="op">;</span></a>
<a class="sourceLine" id="cb56-8" title="8">    <span class="kw">let</span> rightHalf <span class="op">=</span> <span class="va">array</span>.<span class="at">slice</span>(midIdx <span class="op">+</span> <span class="dv">1</span>)<span class="op">;</span></a>
<a class="sourceLine" id="cb56-9" title="9"></a>
<a class="sourceLine" id="cb56-10" title="10">    <span class="cf">if</span> (target <span class="op">&lt;</span> array[midIdx]) <span class="op">{</span></a>
<a class="sourceLine" id="cb56-11" title="11">        <span class="cf">return</span> <span class="at">binarySearch</span>(leftHalf<span class="op">,</span> target)<span class="op">;</span></a>
<a class="sourceLine" id="cb56-12" title="12">    <span class="op">}</span> <span class="cf">else</span> <span class="cf">if</span> (target <span class="op">&gt;</span> array[midIdx]) <span class="op">{</span></a>
<a class="sourceLine" id="cb56-13" title="13">        <span class="cf">return</span> <span class="at">binarySearch</span>(rightHalf<span class="op">,</span> target)<span class="op">;</span></a>
<a class="sourceLine" id="cb56-14" title="14">    <span class="op">}</span> <span class="cf">else</span> <span class="op">{</span></a>
<a class="sourceLine" id="cb56-15" title="15">        <span class="cf">return</span> <span class="kw">true</span><span class="op">;</span></a>
<a class="sourceLine" id="cb56-16" title="16">    <span class="op">}</span></a>
<a class="sourceLine" id="cb56-17" title="17"><span class="op">}</span></a></code></pre>
                </div>
                <p>To wrap up, we have confidence of our base case will eventually be hit because we are continually
                    halving the
                    array. We halve the array until it's length is 0 or we actually find the target.</p>
                <h3 id="binary-search-js-implementation">Binary Search JS Implementation</h3>
                <p>Here is the code again for your quick reference:</p>
                <div class="sourceCode" id="cb57">
                    <pre data-filter-output="(out)" class="sourceCode javascript" class="sourceCode javascript"><code  class="language-javascript  highlight" id="button" class="sourceCode javascript"><a class="sourceLine" id="cb57-1" title="1"><span class="kw">function</span> <span class="at">binarySearch</span>(array<span class="op">,</span> target) <span class="op">{</span></a>
<a class="sourceLine" id="cb57-2" title="2">    <span class="cf">if</span> (<span class="va">array</span>.<span class="at">length</span> <span class="op">===</span> <span class="dv">0</span>) <span class="op">{</span></a>
<a class="sourceLine" id="cb57-3" title="3">        <span class="cf">return</span> <span class="kw">false</span><span class="op">;</span></a>
<a class="sourceLine" id="cb57-4" title="4">    <span class="op">}</span></a>
<a class="sourceLine" id="cb57-5" title="5"></a>
<a class="sourceLine" id="cb57-6" title="6">    <span class="kw">let</span> midIdx <span class="op">=</span> <span class="va">Math</span>.<span class="at">floor</span>(<span class="va">array</span>.<span class="at">length</span> / <span class="dv">2</span>)<span class="op">;</span></a>
<a class="sourceLine" id="cb57-7" title="7">    <span class="kw">let</span> leftHalf <span class="op">=</span> <span class="va">array</span>.<span class="at">slice</span>(<span class="dv">0</span><span class="op">,</span> midIdx)<span class="op">;</span></a>
<a class="sourceLine" id="cb57-8" title="8">    <span class="kw">let</span> rightHalf <span class="op">=</span> <span class="va">array</span>.<span class="at">slice</span>(midIdx <span class="op">+</span> <span class="dv">1</span>)<span class="op">;</span></a>
<a class="sourceLine" id="cb57-9" title="9"></a>
<a class="sourceLine" id="cb57-10" title="10">    <span class="cf">if</span> (target <span class="op">&lt;</span> array[midIdx]) <span class="op">{</span></a>
<a class="sourceLine" id="cb57-11" title="11">        <span class="cf">return</span> <span class="at">binarySearch</span>(leftHalf<span class="op">,</span> target)<span class="op">;</span></a>
<a class="sourceLine" id="cb57-12" title="12">    <span class="op">}</span> <span class="cf">else</span> <span class="cf">if</span> (target <span class="op">&gt;</span> array[midIdx]) <span class="op">{</span></a>
<a class="sourceLine" id="cb57-13" title="13">        <span class="cf">return</span> <span class="at">binarySearch</span>(rightHalf<span class="op">,</span> target)<span class="op">;</span></a>
<a class="sourceLine" id="cb57-14" title="14">    <span class="op">}</span> <span class="cf">else</span> <span class="op">{</span></a>
<a class="sourceLine" id="cb57-15" title="15">        <span class="cf">return</span> <span class="kw">true</span><span class="op">;</span></a>
<a class="sourceLine" id="cb57-16" title="16">    <span class="op">}</span></a>
<a class="sourceLine" id="cb57-17" title="17"><span class="op">}</span></a></code></pre>
                </div>
                <h2 id="time-and-space-complexity-analysis-3">Time and Space Complexity Analysis</h2>
                <p>The complexity analysis of this algorithm is easier to explain through visuals, so we <strong>highly
                        encourage</strong> you to watch the lecture that accompanies this reading. In any case, here is
                    a
                    summary of
                    the complexity:</p>
                <h3 id="time-complexity-ologn">Time Complexity: O(log(n))</h3>
                <ul>
                    <li><code class="language-javascript  highlight" id="button">n</code> is the length of the input
                        array</li>
                    <li>We have no loops, so we must only consider the number of recursive calls it takes to hit the
                        base case
                    </li>
                    <li>The number of recursive calls is the number of times we must halve the array until it's length
                        becomes
                        0.
                        This number can be described by <code class="language-javascript  highlight"
                            id="button">log(n)</code>
                        <ul>
                            <li>for example, say we had an array of 8 elements, <code
                                    class="language-javascript  highlight" id="button">n = 8</code></li>
                            <li>the length would halve as <code class="language-javascript  highlight" id="button">8
                                    -&gt; 4 -&gt; 2 -&gt; 1</code></li>
                            <li>it takes 3 calls, <code class="language-javascript  highlight" id="button">log(8) =
                                    3</code></li>
                        </ul>
                    </li>
                </ul>
                <h3 id="space-complexity-on-1">Space Complexity: O(n)</h3>
                <p>Our implementation uses <code class="language-javascript  highlight" id="button">n</code> space due
                    to half arrays we create using slice. Note that
                    JavaScript
                    <code class="language-javascript  highlight" id="button">slice</code> creates a new array, so it
                    requires additional memory to be allocated.
                </p>
                <h3 id="when-should-we-use-binary-search">When should we use Binary Search?</h3>
                <p>Use this algorithm when the input data is sorted!!! This is a heavy requirement, but if you have it,
                    you'll
                    have
                    an insanely fast algorithm. Of course, you can use one of your high-functioning sorting algorithms
                    to sort
                    the
                    input and <em>then</em> perform the binary search!</p>
                <hr />
                <h1 id="practice-bubble-sort">Practice: Bubble Sort</h1>
                <p>This project contains a skeleton for you to implement Bubble Sort. In the file
                    <strong>lib/bubble_sort.js</strong>, you should implement the Bubble Sort. This is a description of
                    how the
                    Bubble Sort works (and is also in the code file).
                </p>
                <pre data-filter-output="(out)" class="sourceCode javascript"><code  class="language-javascript  highlight" id="button">Bubble Sort: (array)
  n := length(array)
  repeat
    swapped = false
    for i := 1 to n - 1 inclusive do

      /* if this pair is out of order */
      if array[i - 1] &gt; array[i] then

        /* swap them and remember something changed */
        swap(array, i - 1, i)
        swapped := true

      end if
    end for
  until not swapped</code></pre>
                <h2 id="instructions">Instructions</h2>
                <ul>
                    <li>Clone the project from https://github.com/appacademy-starters/algorithms-bubble-sort-starter.
                    </li>
                    <li><code class="language-javascript  highlight" id="button">cd</code> into the project folder</li>
                    <li><code class="language-javascript  highlight" id="button">npm install</code> to install
                        dependencies in the project root directory</li>
                    <li><code class="language-javascript  highlight" id="button">npm test</code> to run the specs</li>
                    <li>You can view the test cases in <code class="language-javascript  highlight"
                            id="button">/test/test.js</code>. Your job is to write code in the
                        <code class="language-javascript  highlight" id="button">/lib/bubble_sort.js</code> that
                        implements the Bubble Sort.
                    </li>
                </ul>
                <hr />
                <h1 id="practice-selection-sort">Practice: Selection Sort</h1>
                <p>This project contains a skeleton for you to implement Selection Sort. In the file
                    <strong>lib/selection_sort.js</strong>, you should implement the Selection Sort. You can use the
                    same
                    <code class="language-javascript  highlight" id="button">swap</code> function from Bubble Sort;
                    however, try to implement it on your own, first.
                </p>
                <p>The algorithm can be summarized as the following:</p>
                <ol type="1">
                    <li>Set MIN to location 0</li>
                    <li>Search the minimum element in the list</li>
                    <li>Swap with value at location MIN</li>
                    <li>Increment MIN to point to next element</li>
                    <li>Repeat until list is sorted</li>
                </ol>
                <p>This is a description of how the Selection Sort works (and is also in the code file).</p>
                <pre data-filter-output="(out)" class="sourceCode javascript"><code  class="language-javascript  highlight" id="button">procedure selection sort(list)
   list  : array of items
   n     : size of list

   for i = 1 to n - 1
   /* set current element as minimum*/
      min = i

      /* check the element to be minimum */

      for j = i+1 to n
         if list[j] &lt; list[min] then
            min = j;
         end if
      end for

      /* swap the minimum element with the current element*/
      if indexMin != i  then
         swap list[min] and list[i]
      end if
   end for
end procedure</code></pre>
                <h2 id="instructions-1">Instructions</h2>
                <ul>
                    <li>Clone the project from https://github.com/appacademy-starters/algorithms-selection-sort-starter.
                    </li>
                    <li><code class="language-javascript  highlight" id="button">cd</code> into the project folder</li>
                    <li><code class="language-javascript  highlight" id="button">npm install</code> to install
                        dependencies in the project root directory</li>
                    <li><code class="language-javascript  highlight" id="button">npm test</code> to run the specs</li>
                    <li>You can view the test cases in <code class="language-javascript  highlight"
                            id="button">/test/test.js</code>. Your job is to write code in the
                        <code class="language-javascript  highlight" id="button">/lib/selection_sort.js</code> that
                        implements the Selection Sort.
                    </li>
                </ul>
                <hr />
                <h1 id="practice-insertion-sort">Practice: Insertion Sort</h1>
                <p>This project contains a skeleton for you to implement Insertion Sort. In the file
                    <strong>lib/insertion_sort.js</strong>, you should implement the Insertion Sort.
                </p>
                <p>The algorithm can be summarized as the following:</p>
                <ol type="1">
                    <li>If it is the first element, it is already sorted. return 1;</li>
                    <li>Pick next element</li>
                    <li>Compare with all elements in the sorted sub-list</li>
                    <li>Shift all the elements in the sorted sub-list that is greater than the value to be sorted</li>
                    <li>Insert the value</li>
                    <li>Repeat until list is sorted</li>
                </ol>
                <p>This is a description of how the Insertion Sort works (and is also in the code file).</p>
                <pre data-filter-output="(out)" class="sourceCode javascript"><code  class="language-javascript  highlight" id="button">procedure insertionSort( A : array of items )
   int holePosition
   int valueToInsert

   for i = 1 to length(A) inclusive do:

      /* select value to be inserted */
      valueToInsert = A[i]
      holePosition = i

      /*locate hole position for the element to be inserted */

      while holePosition &gt; 0 and A[holePosition-1] &gt; valueToInsert do:
         A[holePosition] = A[holePosition-1]
         holePosition = holePosition -1
      end while

      /* insert the number at hole position */
      A[holePosition] = valueToInsert

   end for

end procedure</code></pre>
                <h2 id="instructions-2">Instructions</h2>
                <ul>
                    <li>Clone the project from https://github.com/appacademy-starters/algorithms-insertion-sort-starter.
                    </li>
                    <li><code class="language-javascript  highlight" id="button">cd</code> into the project folder</li>
                    <li><code class="language-javascript  highlight" id="button">npm install</code> to install
                        dependencies in the project root directory</li>
                    <li><code class="language-javascript  highlight" id="button">npm test</code> to run the specs</li>
                    <li>You can view the test cases in <code class="language-javascript  highlight"
                            id="button">/test/test.js</code>. Your job is to write code in the
                        <code class="language-javascript  highlight" id="button">/lib/insertion_sort.js</code> that
                        implements the Insertion Sort.
                    </li>
                </ul>
                <hr />
                <h1 id="practice-merge-sort">Practice: Merge Sort</h1>
                <p>This project contains a skeleton for you to implement Merge Sort. In the file
                    <strong>lib/merge_sort.js</strong>,
                    you should implement the Merge Sort.
                </p>
                <p>The algorithm can be summarized as the following:</p>
                <ol type="1">
                    <li>if there is only one element in the list, it is already sorted. return that array.</li>
                    <li>otherwise, divide the list recursively into two halves until it can no more be divided.</li>
                    <li>merge the smaller lists into new list in sorted order.</li>
                </ol>
                <p>This is a description of how the Merge Sort works (and is also in the code file).</p>
                <pre data-filter-output="(out)" class="sourceCode javascript"><code  class="language-javascript  highlight" id="button">procedure mergesort( a as array )
   if ( n == 1 ) return a

   /* Split the array into two */
   var l1 as array = a[0] ... a[n/2]
   var l2 as array = a[n/2+1] ... a[n]

   l1 = mergesort( l1 )
   l2 = mergesort( l2 )

   return merge( l1, l2 )
end procedure

procedure merge( a as array, b as array )
   var result as array
   while ( a and b have elements )
      if ( a[0] &gt; b[0] )
         add b[0] to the end of result
         remove b[0] from b
      else
         add a[0] to the end of result
         remove a[0] from a
      end if
   end while

   while ( a has elements )
      add a[0] to the end of result
      remove a[0] from a
   end while

   while ( b has elements )
      add b[0] to the end of result
      remove b[0] from b
   end while

   return result
end procedure</code></pre>
                <h2 id="instructions-3">Instructions</h2>
                <ul>
                    <li>Clone the project from https://github.com/appacademy-starters/algorithms-merge-sort-starter.
                    </li>
                    <li><code class="language-javascript  highlight" id="button">cd</code> into the project folder</li>
                    <li><code class="language-javascript  highlight" id="button">npm install</code> to install
                        dependencies in the project root directory</li>
                    <li><code class="language-javascript  highlight" id="button">npm test</code> to run the specs</li>
                    <li>You can view the test cases in <code class="language-javascript  highlight"
                            id="button">/test/test.js</code>. Your job is to write code in the
                        <code class="language-javascript  highlight" id="button">/lib/merge_sort.js</code> that
                        implements the Merge Sort.
                    </li>
                </ul>
                <hr />
                <h1 id="practice-quick-sort">Practice: Quick Sort</h1>
                <p>This project contains a skeleton for you to implement Quick Sort. In the file
                    <strong>lib/quick_sort.js</strong>,
                    you should implement the Quick Sort. This is a description of how the Quick Sort works (and is also
                    in the
                    code
                    file).
                </p>
                <pre data-filter-output="(out)" class="sourceCode javascript"><code  class="language-javascript  highlight" id="button">procedure quick sort (array)
  if the length of the array is 0 or 1, return the array

  set the pivot to the first element of the array
  remove the first element of the array

  put all values less than the pivot value into an array called left
  put all values greater than the pivot value into an array called right

  call quick sort on left and assign the return value to leftSorted
  call quick sort on right and assign the return value to rightSorted

  return the concatenation of leftSorted, the pivot value, and rightSorted
end procedure quick sort</code></pre>
                <h2 id="instructions-4">Instructions</h2>
                <ul>
                    <li>Clone the project from https://github.com/appacademy-starters/algorithms-quick-sort-starter.
                    </li>
                    <li><code class="language-javascript  highlight" id="button">cd</code> into the project folder</li>
                    <li><code class="language-javascript  highlight" id="button">npm install</code> to install
                        dependencies in the project root directory</li>
                    <li><code class="language-javascript  highlight" id="button">npm test</code> to run the specs</li>
                    <li>You can view the test cases in <code class="language-javascript  highlight"
                            id="button">/test/test.js</code>. Your job is to write code in the
                        <code class="language-javascript  highlight" id="button">/lib/quick_sort.js</code> that
                        implements the Quick Sort.
                    </li>
                </ul>
                <hr />
                <h1 id="practice-binary-search">Practice: Binary Search</h1>
                <p>This project contains a skeleton for you to implement Binary Search. In the file
                    <strong>lib/binary_search.js</strong>, you should implement the Binary Search and its cousin Binary
                    Search
                    Index.
                </p>
                <p>The Binary Search algorithm can be summarized as the following:</p>
                <ol type="1">
                    <li>If the array is empty, then return false</li>
                    <li>Check the value in the middle of the array against the target value</li>
                    <li>If the value is equal to the target value, then return true</li>
                    <li>If the value is less than the target value, then return the binary search on the left half of
                        the array
                        for
                        the target</li>
                    <li>If the value is greater than the target value, then return the binary search on the right half
                        of the
                        array
                        for the target</li>
                </ol>
                <p>This is a description of how the Binary Search works (and is also in the code file).</p>
                <pre data-filter-output="(out)" class="sourceCode javascript"><code  class="language-javascript  highlight" id="button">procedure binary search (list, target)
  parameter list: a list of sorted value
  parameter target: the value to search for

  if the list has zero length, then return false

  determine the slice point:
    if the list has an even number of elements,
      the slice point is the number of elements
      divided by two
    if the list has an odd number of elements,
      the slice point is the number of elements
      minus one divided by two

  create an list of the elements from 0 to the
    slice point, not including the slice point,
    which is known as the &quot;left half&quot;
  create an list of the elements from the
    slice point to the end of the list which is
    known as the &quot;right half&quot;

  if the target is less than the value in the
    original array at the slice point, then
    return the binary search of the &quot;left half&quot;
    and the target
  if the target is greater than the value in the
    original array at the slice point, then
    return the binary search of the &quot;right half&quot;
    and the target
  if neither of those is true, return true
end procedure binary search</code></pre>
                <p>Then you need to adapt that to return <em>the index</em> of the found item rather than a Boolean
                    value. The
                    pseudocode is also in the code file.</p>
                <pre data-filter-output="(out)" class="sourceCode javascript"><code  class="language-javascript  highlight" id="button">procedure binary search index(list, target, low, high)
  parameter list: a list of sorted value
  parameter target: the value to search for
  parameter low: the lower index for the search
  parameter high: the upper index for the search

  if low is equal to high, then return -1 to indicate
    that the value was not found

  determine the slice point:
    if the list between the high index and the low index
    has an even number of elements,
      the slice point is the number of elements
      between high and low divided by two
    if the list between the high index and the low index
    has an odd number of elements,
      the slice point is the number of elements
      between high and low minus one, divided by two

  if the target is less than the value in the
    original array at the slice point, then
    return the binary search of the array,
    the target, low, and the slice point
  if the target is greater than the value in the
    original array at the slice point, then return
    the binary search of the array, the target,
    the slice point plus one, and high
  if neither of those is true, return the slice point
end procedure binary search index</code></pre>
                <h2 id="instructions-5">Instructions</h2>
                <ul>
                    <li>Clone the project from https://github.com/appacademy-starters/algorithms-binary-search-starter.
                    </li>
                    <li><code class="language-javascript  highlight" id="button">cd</code> into the project folder</li>
                    <li><code class="language-javascript  highlight" id="button">npm install</code> to install
                        dependencies in the project root directory</li>
                    <li><code class="language-javascript  highlight" id="button">npm test</code> to run the specs</li>
                    <li>You can view the test cases in <code class="language-javascript  highlight"
                            id="button">/test/test.js</code>. Your job is to write code in the
                        <code class="language-javascript  highlight" id="button">/lib/binary_search.js</code> that
                        implements the Binary Search and Binary Search Index.
                    </li>
                </ul>
                <hr />
                <h1 id="week-07-day-4-lists-stacks-queues" data-ignore="true">WEEK-07 DAY-4<br><em>Lists, Stacks,
                        Queues</em>
                </h1>
                <hr />
                <h1 id="lists-stacks-and-queues-">Lists, Stacks, and Queues </h1>
                <p><strong>The objective of this lesson</strong> is for you to become comfortable with implementing
                    common data
                    structures. This is important because questions about data structures are incredibly likely to be
                    interview
                    questions for software engineers from junior to senior levels. Moreover, understanding how different
                    data
                    structures work will influence the libraries and frameworks that you choose when writing software.
                </p>
                <p>When you are done, you will be able to:</p>
                <ol type="1">
                    <li>Explain and implement a List.</li>
                    <li>Explain and implement a Stack.</li>
                    <li>Explain and implement a Queue.me comfortable with implementing common data structures. This is
                        important
                        because questions about data structures are incredibly likely to be interview questions for
                        software
                        engineers from junior to senior levels. Moreover, understanding how different data structures
                        work will
                        influence the libraries and frameworks that you choose when writing software.</li>
                </ol>
                <p>When you are done, you will be able to:</p>
                <ol type="1">
                    <li>Explain and implement a List.</li>
                    <li>Explain and implement a Stack.</li>
                    <li>Explain and implement a Queue.</li>
                </ol>
                <hr />
                <h1 id="linked-lists">Linked Lists</h1>
                <p>In the university setting, it's common for Linked Lists to appear early on in an undergraduate's
                    Computer
                    Science
                    coursework. While they don't always have the most practical real-world applications in industry,
                    Linked
                    Lists
                    make for an important and effective educational tool in helping develop a student's mental model on
                    what
                    data
                    structures actually are to begin with.</p>
                <p>Linked lists are simple. They have many compelling, reoccurring edge cases to consider that emphasize
                    to the
                    student the need for care and intent while implementing data structures. They can be applied as the
                    underlying
                    data structure while implementing a variety of other prevalent abstract data types, such as Lists,
                    Stacks,
                    and
                    Queues, and they have a level of versatility high enough to clearly illustrate the value of the
                    Object
                    Oriented
                    Programming paradigm.</p>
                <p>They also come up in software engineering interviews quite often.</p>
                <h2 id="what-is-a-linked-list">What is a Linked List?</h2>
                <p>A Linked List data structure represents a linear sequence of "vertices" (or "nodes"), and tracks
                    three
                    important
                    properties.</p>
                <p align="center">
                    <b>Linked List Properties:</b>
                </p>
                <table>
                    <thead>
                        <tr class="header">
                            <th style="text-align: center;">Property</th>
                            <th style="text-align: center;">Description</th>
                        </tr>
                    </thead>
                    <tbody>
                        <tr class="odd">
                            <td style="text-align: center;"><code class="language-javascript  highlight"
                                    id="button">head</code></td>
                            <td style="text-align: center;">The first node in the list.</td>
                        </tr>
                        <tr class="even">
                            <td style="text-align: center;"><code class="language-javascript  highlight"
                                    id="button">tail</code></td>
                            <td style="text-align: center;">The last node in the list.</td>
                        </tr>
                        <tr class="odd">
                            <td style="text-align: center;"><code class="language-javascript  highlight"
                                    id="button">length</code></td>
                            <td style="text-align: center;">The number of nodes in the list; the list's length.</td>
                        </tr>
                    </tbody>
                </table>
                <p>The data being tracked by a particular Linked List does not live inside the Linked List instance
                    itself.
                    Instead,
                    each vertex is actually an instance of an even simpler, smaller data structure, often referred to as
                    a
                    "Node".
                </p>
                <p>Depending on the type of Linked List (there are many), Node instances track some very important
                    properties as
                    well.</p>
                <p align="center">
                    <b>Linked List Node Properties:</b>
                </p>
                <table>
                    <thead>
                        <tr class="header">
                            <th style="text-align: center;">Property</th>
                            <th style="text-align: center;">Description</th>
                        </tr>
                    </thead>
                    <tbody>
                        <tr class="odd">
                            <td style="text-align: center;"><code class="language-javascript  highlight"
                                    id="button">value</code></td>
                            <td style="text-align: center;">The actual value this node represents.</td>
                        </tr>
                        <tr class="even">
                            <td style="text-align: center;"><code class="language-javascript  highlight"
                                    id="button">next</code></td>
                            <td style="text-align: center;">The next node in the list (relative to this node).</td>
                        </tr>
                        <tr class="odd">
                            <td style="text-align: center;"><code class="language-javascript  highlight"
                                    id="button">previous</code></td>
                            <td style="text-align: center;">The previous node in the list (relative to this node).</td>
                        </tr>
                    </tbody>
                </table>
                <p align="center">
                    <b>NOTE:</b> The <code class="language-javascript  highlight" id="button">previous</code> property
                    is for Doubly Linked Lists only!
                </p>
                <p>Linked Lists contain <em>ordered</em> data, just like arrays. The first node in the list is, indeed,
                    first.
                    From
                    the perspective of the very first node in the list, the <em>next</em> node is the second node. From
                    the
                    perspective of the second node in the list, the <em>previous</em> node is the first node, and the
                    <em>next</em>
                    node is the third node. And so it goes.
                </p>
                <h4 id="sothis-sounds-a-lot-like-an-array"><em>"So…this sounds a lot like an Array…"</em></h4>
                <p>Admittedly, this does <em>sound</em> a lot like an Array so far, and that's because Arrays and Linked
                    Lists
                    are
                    both implementations of the List ADT. However, there is an incredibly important distinction to be
                    made
                    between
                    Arrays and Linked Lists, and that is how they <em>physically store</em> their data. (As opposed to
                    how they
                    <em>represent</em> the order of their data.)
                </p>
                <p>Recall that Arrays contain <em>contiguous</em> data. Each element of an array is actually stored
                    <em>next
                        to</em>
                    it's neighboring element <em>in the actual hardware of your machine</em>, in a single continuous
                    block in
                    memory.
                </p>
                <img src="images/array-in-memory.png" alt="Array in Memory" />
                <p align="center">
                    <i>An Array's contiguous data being stored in a continuous block of addresses in memory.</i>
                </p>
                <p><br></p>
                <p>Unlike Arrays, Linked Lists contain <em>non-contiguous</em> data. Though Linked Lists
                    <em>represent</em> data
                    that is ordered linearly, that mental model is just that - an interpretation of the
                    <em>representation</em>
                    of
                    information, not reality.
                </p>
                <p>In reality, in the actual hardware of your machine, whether it be in disk or in memory, a Linked
                    List's Nodes
                    are
                    not stored in a single continuous block of addresses. Rather, Linked List Nodes live at randomly
                    distributed
                    addresses throughout your machine! The only reason we know which node comes next in the list is
                    because
                    we've
                    assigned its reference to the current node's <code class="language-javascript  highlight"
                        id="button">next</code> pointer.</p>
                <img src="images/SLL-diagram.png" alt="Array in Memory" />
                <p align="center">
                    <i>A Singly Linked List's non-contiguous data (Nodes) being stored at randomly distributed addresses
                        in
                        memory.</i>
                </p>
                <p><br></p>
                <p>For this reason, Linked List Nodes have <em>no indices</em>, and no <em>random access</em>. Without
                    random
                    access, we do not have the ability to look up an individual Linked List Node in constant time.
                    Instead, to
                    find
                    a particular Node, we have to start at the very first Node and iterate through the Linked List one
                    node at a
                    time, checking each Node's <em>next</em> Node until we find the one we're interested in.</p>
                <p>So when implementing a Linked List, we actually must implement both the Linked List class
                    <em>and</em> the
                    Node
                    class. Since the actual data lives in the Nodes, it's simpler to implement the Node class first.
                </p>
                <h2 id="types-of-linked-lists">Types of Linked Lists</h2>
                <p>There are four flavors of Linked List you should be familiar with when walking into your job
                    interviews.</p>
                <p align="center">
                    <b>Linked List Types:</b>
                </p>
                <table>
                    <colgroup>
                        <col style="width: 16%" />
                        <col style="width: 62%" />
                        <col style="width: 21%" />
                    </colgroup>
                    <thead>
                        <tr class="header">
                            <th style="text-align: center;">List Type</th>
                            <th style="text-align: center;">Description</th>
                            <th style="text-align: center;">Directionality</th>
                        </tr>
                    </thead>
                    <tbody>
                        <tr class="odd">
                            <td style="text-align: center;">Singly Linked</td>
                            <td style="text-align: center;">Nodes have a single pointer connecting them in a single
                                direction.
                            </td>
                            <td style="text-align: center;">Head→Tail</td>
                        </tr>
                        <tr class="even">
                            <td style="text-align: center;">Doubly Linked</td>
                            <td style="text-align: center;">Nodes have two pointers connecting them bi-directionally.
                            </td>
                            <td style="text-align: center;">Head⇄Tail</td>
                        </tr>
                        <tr class="odd">
                            <td style="text-align: center;">Multiply Linked</td>
                            <td style="text-align: center;">Nodes have two or more pointers, providing a variety of
                                potential
                                node
                                orderings.</td>
                            <td style="text-align: center;">Head⇄Tail, A→Z, Jan→Dec, etc.</td>
                        </tr>
                        <tr class="even">
                            <td style="text-align: center;">Circularly Linked</td>
                            <td style="text-align: center;">Final node's <code class="language-javascript  highlight"
                                    id="button">next</code> pointer points to the first
                                node,
                                creating a non-linear, circular version of a Linked List.</td>
                            <td style="text-align: center;">Head→Tail→Head→Tail</td>
                        </tr>
                    </tbody>
                </table>
                <p align="center">
                    <b>NOTE:</b> These Linked List types are not always mutually exclusive.
                </p>
                <p>For instance:</p>
                <ul>
                    <li>Any type of Linked List can be implemented Circularly (e.g. A Circular Doubly Linked List).</li>
                    <li>A Doubly Linked List is actually just a special case of a Multiply Linked List.</li>
                </ul>
                <p>You are most likely to encounter Singly and Doubly Linked Lists in your upcoming job search, so we
                    are going
                    to
                    focus exclusively on those two moving forward. However, in more senior level interviews, it is very
                    valuable
                    to
                    have some familiarity with the other types of Linked Lists. Though you may not actually code them
                    out,
                    <em>you
                        will win extra points by illustrating your ability to weigh the tradeoffs of your technical
                        decisions</em>
                    by discussing how your choice of Linked List type may affect the efficiency of the solutions you
                    propose.
                </p>
                <h2 id="linked-list-methods">Linked List Methods</h2>
                <p>Linked Lists are great foundation builders when learning about data structures because they share a
                    number of
                    similar methods (and edge cases) with many other common data structures. You will find that many of
                    the
                    concepts
                    discussed here will repeat themselves as we dive into some of the more complex non-linear data
                    structures
                    later
                    on, like Trees and Graphs.</p>
                <p>In the project that follows, we will implement the following Linked List methods:</p>
                <table style="width:100%;">
                    <colgroup>
                        <col style="width: 7%" />
                        <col style="width: 10%" />
                        <col style="width: 66%" />
                        <col style="width: 15%" />
                    </colgroup>
                    <thead>
                        <tr class="header">
                            <th style="text-align: center;">Type</th>
                            <th style="text-align: center;">Name</th>
                            <th style="text-align: center;">Description</th>
                            <th style="text-align: center;">Returns</th>
                        </tr>
                    </thead>
                    <tbody>
                        <tr class="odd">
                            <td style="text-align: center;">Insertion</td>
                            <td style="text-align: center;"><code class="language-javascript  highlight"
                                    id="button">addToTail</code></td>
                            <td style="text-align: center;">Adds a new node to the tail of the Linked List.</td>
                            <td style="text-align: center;">Updated Linked List</td>
                        </tr>
                        <tr class="even">
                            <td style="text-align: center;">Insertion</td>
                            <td style="text-align: center;"><code class="language-javascript  highlight"
                                    id="button">addToHead</code></td>
                            <td style="text-align: center;">Adds a new node to the head of the Linked List.</td>
                            <td style="text-align: center;">Updated Linked List</td>
                        </tr>
                        <tr class="odd">
                            <td style="text-align: center;">Insertion</td>
                            <td style="text-align: center;"><code class="language-javascript  highlight"
                                    id="button">insertAt</code></td>
                            <td style="text-align: center;">Inserts a new node at the "index", or position, specified.
                            </td>
                            <td style="text-align: center;">Boolean</td>
                        </tr>
                        <tr class="even">
                            <td style="text-align: center;">Deletion</td>
                            <td style="text-align: center;"><code class="language-javascript  highlight"
                                    id="button">removeTail</code></td>
                            <td style="text-align: center;">Removes the node at the tail of the Linked List.</td>
                            <td style="text-align: center;">Removed node</td>
                        </tr>
                        <tr class="odd">
                            <td style="text-align: center;">Deletion</td>
                            <td style="text-align: center;"><code class="language-javascript  highlight"
                                    id="button">removeHead</code></td>
                            <td style="text-align: center;">Removes the node at the head of the Linked List.</td>
                            <td style="text-align: center;">Removed node</td>
                        </tr>
                        <tr class="even">
                            <td style="text-align: center;">Deletion</td>
                            <td style="text-align: center;"><code class="language-javascript  highlight"
                                    id="button">removeFrom</code></td>
                            <td style="text-align: center;">Removes the node at the "index", or position, specified.
                            </td>
                            <td style="text-align: center;">Removed node</td>
                        </tr>
                        <tr class="odd">
                            <td style="text-align: center;">Search</td>
                            <td style="text-align: center;"><code class="language-javascript  highlight"
                                    id="button">contains</code></td>
                            <td style="text-align: center;">Searches the Linked List for a node with the value
                                specified.</td>
                            <td style="text-align: center;">Boolean</td>
                        </tr>
                        <tr class="even">
                            <td style="text-align: center;">Access</td>
                            <td style="text-align: center;"><code class="language-javascript  highlight"
                                    id="button">get</code></td>
                            <td style="text-align: center;">Gets the node at the "index", or position, specified.</td>
                            <td style="text-align: center;">Node at index</td>
                        </tr>
                        <tr class="odd">
                            <td style="text-align: center;">Access</td>
                            <td style="text-align: center;"><code class="language-javascript  highlight"
                                    id="button">set</code></td>
                            <td style="text-align: center;">Updates the value of a node at the "index", or position,
                                specified.
                            </td>
                            <td style="text-align: center;">Boolean</td>
                        </tr>
                        <tr class="even">
                            <td style="text-align: center;">Meta</td>
                            <td style="text-align: center;"><code class="language-javascript  highlight"
                                    id="button">size</code></td>
                            <td style="text-align: center;">Returns the current size of the Linked List.</td>
                            <td style="text-align: center;">Integer</td>
                        </tr>
                    </tbody>
                </table>
                <h2 id="time-and-space-complexity-analysis-4">Time and Space Complexity Analysis</h2>
                <p>Before we begin our analysis, here is a quick summary of the Time and Space constraints of each
                    Linked List
                    Operation. The complexities below apply to both Singly and Doubly Linked Lists:</p>
                <table>
                    <colgroup>
                        <col style="width: 26%" />
                        <col style="width: 22%" />
                        <col style="width: 25%" />
                        <col style="width: 26%" />
                    </colgroup>
                    <thead>
                        <tr class="header">
                            <th style="text-align: center;">Data Structure Operation</th>
                            <th style="text-align: center;">Time Complexity (Avg)</th>
                            <th style="text-align: center;">Time Complexity (Worst)</th>
                            <th style="text-align: center;">Space Complexity (Worst)</th>
                        </tr>
                    </thead>
                    <tbody>
                        <tr class="odd">
                            <td style="text-align: center;">Access</td>
                            <td style="text-align: center;"><code class="language-javascript  highlight"
                                    id="button">Θ(n)</code></td>
                            <td style="text-align: center;"><code class="language-javascript  highlight"
                                    id="button">O(n)</code></td>
                            <td style="text-align: center;"><code class="language-javascript  highlight"
                                    id="button">O(n)</code></td>
                        </tr>
                        <tr class="even">
                            <td style="text-align: center;">Search</td>
                            <td style="text-align: center;"><code class="language-javascript  highlight"
                                    id="button">Θ(n)</code></td>
                            <td style="text-align: center;"><code class="language-javascript  highlight"
                                    id="button">O(n)</code></td>
                            <td style="text-align: center;"><code class="language-javascript  highlight"
                                    id="button">O(n)</code></td>
                        </tr>
                        <tr class="odd">
                            <td style="text-align: center;">Insertion</td>
                            <td style="text-align: center;"><code class="language-javascript  highlight"
                                    id="button">Θ(1)</code></td>
                            <td style="text-align: center;"><code class="language-javascript  highlight"
                                    id="button">O(1)</code></td>
                            <td style="text-align: center;"><code class="language-javascript  highlight"
                                    id="button">O(n)</code></td>
                        </tr>
                        <tr class="even">
                            <td style="text-align: center;">Deletion</td>
                            <td style="text-align: center;"><code class="language-javascript  highlight"
                                    id="button">Θ(1)</code></td>
                            <td style="text-align: center;"><code class="language-javascript  highlight"
                                    id="button">O(1)</code></td>
                            <td style="text-align: center;"><code class="language-javascript  highlight"
                                    id="button">O(n)</code></td>
                        </tr>
                    </tbody>
                </table>
                <p>Before moving forward, see if you can reason to yourself why each operation has the time and space
                    complexity
                    listed above!</p>
                <h2 id="time-complexity---access-and-search">Time Complexity - Access and Search:</h2>
                <h3 id="scenarios">Scenarios:</h3>
                <ol type="1">
                    <li>We have a Linked List, and we'd like to find the 8th item in the list.</li>
                    <li>We have a Linked List of sorted alphabet letters, and we'd like to see if the letter "Q" is
                        inside that
                        list.</li>
                </ol>
                <h3 id="discussion">Discussion:</h3>
                <p>Unlike Arrays, Linked Lists Nodes are not stored contiguously in memory, and thereby do not have an
                    indexed
                    set
                    of memory addresses at which we can quickly lookup individual nodes in constant time. Instead, we
                    must begin
                    at
                    the head of the list (or possibly at the tail, if we have a Doubly Linked List), and iterate through
                    the
                    list
                    until we arrive at the node of interest.</p>
                <p>In Scenario 1, we'll know we're there because we've iterated 8 times. In Scenario 2, we'll know we're
                    there
                    because, while iterating, we've checked each node's value and found one that matches our target
                    value, "Q".
                </p>
                <p>In the worst case scenario, we may have to traverse the entire Linked List until we arrive at the
                    final node.
                    This makes both Access &amp; Search <strong>Linear Time</strong> operations.</p>
                <h2 id="time-complexity---insertion-and-deletion">Time Complexity - Insertion and Deletion:</h2>
                <h3 id="scenarios-1">Scenarios:</h3>
                <ol type="1">
                    <li>We have an empty Linked List, and we'd like to insert our first node.</li>
                    <li>We have a Linked List, and we'd like to insert or delete a node at the Head or Tail.</li>
                    <li>We have a Linked List, and we'd like to insert or delete a node from somewhere in the middle of
                        the
                        list.
                    </li>
                </ol>
                <h3 id="discussion-1">Discussion:</h3>
                <p>Since we have our Linked List Nodes stored in a non-contiguous manner that relies on pointers to keep
                    track
                    of
                    where the next and previous nodes live, Linked Lists liberate us from the linear time nature of
                    Array
                    insertions
                    and deletions. We no longer have to adjust the position at which each node/element is stored after
                    making an
                    insertion at a particular position in the list. Instead, if we want to insert a new node at position
                    <code class="language-javascript  highlight" id="button">i</code>, we can simply:
                </p>
                <ol type="1">
                    <li>Create a new node.</li>
                    <li>Set the new node's <code class="language-javascript  highlight" id="button">next</code> and
                        <code class="language-javascript  highlight" id="button">previous</code> pointers to the nodes
                        that live
                        at
                        positions
                        <code class="language-javascript  highlight" id="button">i</code> and <code
                            class="language-javascript  highlight" id="button">i - 1</code>, respectively.
                    </li>
                    <li>Adjust the <code class="language-javascript  highlight" id="button">next</code> pointer of the
                        node that lives at position <code class="language-javascript  highlight" id="button">i -
                            1</code> to
                        point to
                        the
                        new node.</li>
                    <li>Adjust the <code class="language-javascript  highlight" id="button">previous</code> pointer of
                        the node that lives at position <code class="language-javascript  highlight"
                            id="button">i</code> to
                        point to
                        the
                        new node.</li>
                </ol>
                <p>And we're done, in Constant Time. No iterating across the entire list necessary.</p>
                <p>"But hold on one second," you may be thinking. "In order to insert a new node in the middle of the
                    list,
                    don't we
                    have to lookup its position? Doesn't that take linear time?!"</p>
                <p>Yes, it is tempting to call insertion or deletion in the middle of a Linked List a linear time
                    operation
                    since
                    there is lookup involved. However, it's usually the case that you'll already have a reference to the
                    node
                    where
                    your desired insertion or deletion will occur.</p>
                <p>For this reason, we separate the Access time complexity from the Insertion/Deletion time complexity,
                    and
                    formally
                    state that Insertion and Deletion in a Linked List are <strong>Constant Time</strong> across the
                    board.</p>
                <h3 id="note">NOTE:</h3>
                <p>Without a reference to the node at which an insertion or deletion will occur, due to linear time
                    lookup, an
                    insertion or deletion <em>in the middle</em> of a Linked List will still take Linear Time, sum
                    total.</p>
                <h2 id="space-complexity-1">Space Complexity:</h2>
                <h3 id="scenarios-2">Scenarios:</h3>
                <ol type="1">
                    <li>We're given a Linked List, and need to operate on it.</li>
                    <li>We've decided to create a new Linked List as part of strategy to solve some problem.</li>
                </ol>
                <h3 id="discussion-2">Discussion:</h3>
                <p>It's obvious that Linked Lists have one node for every one item in the list, and for that reason we
                    know that
                    Linked Lists take up Linear Space in memory. However, when asked in an interview setting what the
                    Space
                    Complexity <em>of your solution</em> to a problem is, it's important to recognize the difference
                    between the
                    two
                    scenarios above.</p>
                <p>In Scenario 1, we <em>are not</em> creating a new Linked List. We simply need to operate on the one
                    given.
                    Since
                    we are not storing a <em>new</em> node for every node represented in the Linked List we are
                    provided, our
                    solution is <em>not necessarily</em> linear in space.</p>
                <p>In Scenario 2, we <em>are</em> creating a new Linked List. If the number of nodes we create is
                    linearly
                    correlated to the size of our input data, we are now operating in Linear Space.</p>
                <h3 id="note-1">NOTE:</h3>
                <p>Linked Lists can be traversed both iteratively and recursively. <em>If you choose to traverse a
                        Linked List
                        recursively</em>, there will be a recursive function call added to the call stack for every node
                    in the
                    Linked List. Even if you're provided the Linked List, as in Scenario 1, you will still use Linear
                    Space in
                    the
                    call stack, and that counts.</p>
                <hr />
                <h1 id="stacks-and-queues">Stacks and Queues</h1>
                <p>Stacks and Queues aren't really "data structures" by the strict definition of the term. The more
                    appropriate
                    terminology would be to call them abstract data types (ADTs), meaning that their definitions are
                    more
                    conceptual
                    and related to the rules governing their user-facing behaviors rather than their core
                    implementations.</p>
                <p>For the sake of simplicity, we'll refer to them as data structures and ADTs interchangeably
                    throughout the
                    course, but the distinction is an important one to be familiar with as you level up as an engineer.
                </p>
                <p>Now that that's out of the way, Stacks and Queues represent a linear collection of nodes or values.
                    In this
                    way,
                    they are quite similar to the Linked List data structure we discussed in the previous section. In
                    fact, you
                    can
                    even use a modified version of a Linked List to implement each of them. (Hint, hint.)</p>
                <p>These two ADTs are similar to each other as well, but each obey their own special rule regarding the
                    order
                    with
                    which Nodes can be added and removed from the structure.</p>
                <p>Since we've covered Linked Lists in great length, these two data structures will be quick and easy.
                    Let's
                    break
                    them down individually in the next couple of sections.</p>
                <h2 id="what-is-a-stack">What is a Stack?</h2>
                <p>Stacks are a Last In First Out (LIFO) data structure. The last Node added to a stack is always the
                    first Node
                    to
                    be removed, and as a result, the first Node added is always the last Node removed.</p>
                <p>The name Stack actually comes from this characteristic, as it is helpful to visualize the data
                    structure as a
                    vertical stack of items. Personally, I like to think of a Stack as a stack of plates, or a stack of
                    sheets
                    of
                    paper. This seems to make them more approachable, because the analogy relates to something in our
                    everyday
                    lives.</p>
                <p>If you can imagine adding items to, or removing items from, a Stack of…literally anything…you'll
                    realize that
                    every (sane) person naturally obeys the LIFO rule.</p>
                <p>We add things to the <em>top</em> of a stack. We remove things from the <em>top</em> of a stack. We
                    never add
                    things to, or remove things from, the <em>bottom</em> of the stack. That's just crazy.</p>
                <p>Note: We can use JavaScript Arrays to implement a basic stack. <code
                        class="language-javascript  highlight" id="button">Array#push</code> adds to the
                    top of the
                    stack and <code class="language-javascript  highlight" id="button">Array#pop</code> will remove from
                    the top of the stack. In the exercise that
                    follows, we'll
                    build our own Stack class from scratch (without using any arrays). In an interview setting, your
                    evaluator
                    may
                    be okay with you using an array as a stack.</p>
                <h2 id="what-is-a-queue">What is a Queue?</h2>
                <p>Queues are a First In First Out (FIFO) data structure. The first Node added to the queue is always
                    the first
                    Node
                    to be removed.</p>
                <p>The name Queue comes from this characteristic, as it is helpful to visualize this data structure as a
                    horizontal
                    line of items with a beginning and an end. Personally, I like to think of a Queue as the line one
                    waits on
                    for
                    an amusement park, at a grocery store checkout, or to see the teller at a bank.</p>
                <p>If you can imagine a queue of humans waiting…again, for literally anything…you'll realize that
                    <em>most</em>
                    people (the civil ones) naturally obey the FIFO rule.
                </p>
                <p>People add themselves to the <em>back</em> of a queue, wait their turn in line, and make their way
                    toward the
                    <em>front</em>. People exit from the <em>front</em> of a queue, but only when they have made their
                    way to
                    being
                    first in line.
                </p>
                <p>We never add ourselves to the front of a queue (unless there is no one else in line), otherwise we
                    would be
                    "cutting" the line, and other humans don't seem to appreciate that.</p>
                <p>Note: We can use JavaScript Arrays to implement a basic queue. <code
                        class="language-javascript  highlight" id="button">Array#push</code> adds to the
                    back
                    (enqueue)
                    and <code class="language-javascript  highlight" id="button">Array#shift</code> will remove from the
                    front (dequeue). In the exercise that follows,
                    we'll build
                    our
                    own Queue class from scratch (without using any arrays). In an interview setting, your evaluator may
                    be okay
                    with you using an array as a queue.</p>



                <h1 id="reverse-part-of-a-linked-list-via-recusion">Reverse Part of a Linked List via Recusion</h1>
                <p><strong>Translator: <a href="https://github.com/CarrieOn">CarrieOn</a></strong></p>
                <p><strong>Author: <a href="https://github.com/labuladong">labuladong</a></strong></p>
                <p>It's easy to reverse a single linked list using iteration, however it's kind of difficult to come up
                    with a
                    recursive solution. Furthermore, if only part of a linked list needs reversed, can you nail it with
                    <strong>recursion</strong>?
                </p>
                <p>If you haven't known how to <strong>recursively reverse a single linked list</strong>, no worry, we
                    will
                    start
                    right here and guide you step by step to a deeper level.</p>
                <div class="sourceCode" id="cb1">
                    <pre data-filter-output="(out)" class="sourceCode javascript" data-filter-output="(out)"
                        class="sourceCode java"><code  class="language-javascript  highlight" id="button" class="sourceCode java"><a class="sourceLine" id="cb1-1" title="1"><span class="lang-js co">// node structure for a single linked list </span></a>
<a class="sourceLine" id="cb1-2" title="2"><span class="lang-js kw">public</span> <span class="lang-js kw">class</span> ListNode {</a>
<a class="sourceLine" id="cb1-3" title="3">    <span class="lang-js dt">int</span> val;</a>
<a class="sourceLine" id="cb1-4" title="4">    ListNode next;</a>
<a class="sourceLine" id="cb1-5" title="5">    <span class="lang-js fu">ListNode</span>(<span class="lang-js dt">int</span> x) { val = x; }</a>
<a class="sourceLine" id="cb1-6" title="6">}</a></code></pre>
                </div>
                <p><br></p>
                <p>To reverse part of a linked list means we only reverse elements in a specific interval and leave
                    others
                    untouched.</p>
                <p><img src="../pictures/reverse_linked_list/title.png" /></p>
                <p>Note: <strong>Index starts from 1</strong>. Two loops needed if solve via iteration: use one for-loop
                    to find
                    the
                    mth element, and then use another for-loop to reverse elements between m and n. While in recursive
                    solution,
                    no
                    loop at all.</p>
                <p>Though iterative solution looks simple, you have to be careful with the details. On the contrary,
                    recursive
                    solution is quite elegant. Let's start reversing a whole single linked list in the recursive way.
                </p>
                <h3 id="recursively-reverse-a-whole-single-linked-list">1. Recursively reverse a whole single Linked
                    List</h3>
                <p>You may have already known the solution below.</p>
                <div class="sourceCode" id="cb2">
                    <pre data-filter-output="(out)" class="sourceCode javascript" data-filter-output="(out)"
                        class="sourceCode java"><code  class="language-javascript  highlight" id="button" class="sourceCode java"><a class="sourceLine" id="cb2-1" title="1">ListNode <span class="lang-js fu">reverse</span>(ListNode head) {</a>
<a class="sourceLine" id="cb2-2" title="2">    <span class="lang-js kw">if</span> (head.<span class="lang-js fu">next</span> == <span class="lang-js kw">null</span>) <span class="lang-js kw">return</span> head;</a>
<a class="sourceLine" id="cb2-3" title="3">    ListNode last = <span class="lang-js fu">reverse</span>(head.<span class="lang-js fu">next</span>);</a>
<a class="sourceLine" id="cb2-4" title="4">    head.<span class="lang-js fu">next</span>.<span class="lang-js fu">next</span> = head;</a>
<a class="sourceLine" id="cb2-5" title="5">    head.<span class="lang-js fu">next</span> = <span class="lang-js kw">null</span>;</a>
<a class="sourceLine" id="cb2-6" title="6">    <span class="lang-js kw">return</span> last;</a>
<a class="sourceLine" id="cb2-7" title="7">}</a></code></pre>
                </div>
                <p>Do you feel lost in trying to understand code above? Well, you are not the only one. This algorithm
                    is often
                    used
                    to show how clever and elegant recursion can be. Let's dig into the code together.</p>
                <p>For recursion, <strong>the most important thing is to clarify the definition of the recursive
                        function</strong>.
                    Specifically, we define <code class="language-javascript  highlight" id="button"
                        class="language-javascript">reverse</code> as follows:</p>
                <p><strong>Input a node <code class="language-javascript  highlight" id="button"
                            class="language-javascript">head</code> , we will reverse the list
                        starting from
                        <code class="language-javascript  highlight" id="button" class="language-javascript">head</code>
                        , and return
                        the new head node.</strong></p>
                <p>After clarifying the definition, we look back at the problem. For example, we want to reverse the
                    list below:
                </p>
                <p><img src="../pictures/reverse_linked_list/1.jpg" /></p>
                <p>So after calling <code class="language-javascript  highlight" id="button"
                        class="language-javascript">reverse(head)</code> , recursion happens:</p>
                <div class="sourceCode" id="cb3">
                    <pre data-filter-output="(out)" class="sourceCode javascript" data-filter-output="(out)"
                        class="sourceCode java"><code  class="language-javascript  highlight" id="button" class="sourceCode java"><a class="sourceLine" id="cb3-1" title="1">ListNode last = <span class="lang-js fu">reverse</span>(head.<span class="lang-js fu">next</span>);</a></code></pre>
                </div>
                <p>Did you just step into the messy details in recursion? Oops, it's a wrong way, step back now! Focus
                    on the
                    recursion definition (which tells you what it does) to understand how recursive code works the
                    wonder.</p>
                <p><img src="../pictures/reverse_linked_list/2.jpg" /></p>
                <p>After executing <code class="language-javascript  highlight" id="button"
                        class="language-javascript">reverse(head.next)</code> , the whole linked list
                    becomes
                    this:
                </p>
                <p><img src="../pictures/reverse_linked_list/3.jpg" /></p>
                <p>According to the definition of the recursive function, <code class="language-javascript  highlight"
                        id="button" class="language-javascript">reverse</code> needs
                    to
                    return the new head node, so
                    we use variable <code class="language-javascript  highlight" id="button"
                        class="language-javascript">last</code> to mark it.</p>
                <p>Let's continue cracking the next piece of code:</p>
                <div class="sourceCode" id="cb4">
                    <pre data-filter-output="(out)" class="sourceCode javascript" data-filter-output="(out)"
                        class="sourceCode java"><code  class="language-javascript  highlight" id="button" class="sourceCode java"><a class="sourceLine" id="cb4-1" title="1">head.<span class="lang-js fu">next</span>.<span class="lang-js fu">next</span> = head;</a></code></pre>
                </div>
                <p><img src="../pictures/reverse_linked_list/4.jpg" /></p>
                <p>Last work to do:</p>
                <div class="sourceCode" id="cb5">
                    <pre data-filter-output="(out)" class="sourceCode javascript" data-filter-output="(out)"
                        class="sourceCode java"><code  class="language-javascript  highlight" id="button" class="sourceCode java"><a class="sourceLine" id="cb5-1" title="1">head.<span class="lang-js fu">next</span> = <span class="lang-js kw">null</span>;</a>
<a class="sourceLine" id="cb5-2" title="2"><span class="lang-js kw">return</span> last;</a></code></pre>
                </div>
                <p><img src="../pictures/reverse_linked_list/5.jpg" /></p>
                <p>The whole linked list is successfully reversed now. Amazing, isn't it?</p>
                <p>Last but not the least, there are two things in recursion you need to pay attention to:</p>
                <ol type="1">
                    <li>Recursion needs a base case.</li>
                </ol>
                <p><code class="language-javascript  highlight" id="button" class="language-javascript">java
                        if(head.next == null) return head;</code></p>
                <pre data-filter-output="(out)" class="sourceCode javascript" data-filter-output="(out)"
                    data-role="codeBlock" data-info="js"
                    class="language-javascript data-line line-numbers data-user data-host data-prompt data-output"
                    data-prismjs-copy="Copy !" data-download-link />
                <code class="language-javascript  highlight" id="button" class="language-javascript">which means when
                    there is only one node, after reversion, the head is
                    still
                    itself.</code></pre>
                <ol start="2" type="1">
                    <li>After reversion, the new head is <code class="language-javascript  highlight" id="button"
                            class="language-javascript">last</code>, and the former
                        <code class="language-javascript  highlight" id="button" class="language-javascript">head</code>
                        becomes the last node,
                        don't forget to point its tail to null.
                    </li>
                </ol>
                <p><code class="language-javascript  highlight" id="button" class="language-javascript">java head.next =
                        null;</code></p>
                <p>After understanding above, now we can proceed further, the problem below is actually an extend to the
                    above
                    solution.</p>
                <h3 id="reverse-first-n-nodes">2. Reverse first N nodes</h3>
                <p>This time we will implement a funtion below:</p>
                <div class="sourceCode" id="cb7">
                    <pre data-filter-output="(out)" class="sourceCode javascript" data-filter-output="(out)"
                        class="sourceCode java"><code  class="language-javascript  highlight" id="button" class="sourceCode java"><a class="sourceLine" id="cb7-1" title="1"><span class="lang-js co">// reverse first n nodes in a linked list (n &lt;= length of the list)</span></a>
<a class="sourceLine" id="cb7-2" title="2">ListNode <span class="lang-js fu">reverseN</span>(ListNode head, <span class="lang-js dt">int</span> n)</a></code></pre>
                </div>
                <p>Take below as an example, call <code class="language-javascript  highlight" id="button"
                        class="language-javascript">reverseN(head, 3)</code> :</p>
                <p><img src="../pictures/reverse_linked_list/6.jpg" /></p>
                <p>The idea is similar to reversing the whole linked list, only a few modifications needed:</p>
                <div class="sourceCode" id="cb8">
                    <pre data-filter-output="(out)" class="sourceCode javascript" data-filter-output="(out)"
                        class="sourceCode java"><code  class="language-javascript  highlight" id="button" class="sourceCode java"><a class="sourceLine" id="cb8-1" title="1">ListNode successor = <span class="lang-js kw">null</span>; <span class="lang-js co">// successor node</span></a>
<a class="sourceLine" id="cb8-2" title="2"></a>
<a class="sourceLine" id="cb8-3" title="3"><span class="lang-js co">// reverse n nodes starting from head, and return new head</span></a>
<a class="sourceLine" id="cb8-4" title="4">ListNode <span class="lang-js fu">reverseN</span>(ListNode head, <span class="lang-js dt">int</span> n) {</a>
<a class="sourceLine" id="cb8-5" title="5">    <span class="lang-js kw">if</span> (n == <span class="lang-js dv">1</span>) { </a>
<a class="sourceLine" id="cb8-6" title="6">        <span class="lang-js co">// mark the (n + 1)th node</span></a>
<a class="sourceLine" id="cb8-7" title="7">        successor = head.<span class="lang-js fu">next</span>;</a>
<a class="sourceLine" id="cb8-8" title="8">        <span class="lang-js kw">return</span> head;</a>
<a class="sourceLine" id="cb8-9" title="9">    }</a>
<a class="sourceLine" id="cb8-10" title="10">    <span class="lang-js co">// starts from head.next, revers the first n - 1 nodes</span></a>
<a class="sourceLine" id="cb8-11" title="11">    ListNode last = <span class="lang-js fu">reverseN</span>(head.<span class="lang-js fu">next</span>, n - <span class="lang-js dv">1</span>);</a>
<a class="sourceLine" id="cb8-12" title="12"></a>
<a class="sourceLine" id="cb8-13" title="13">    head.<span class="lang-js fu">next</span>.<span class="lang-js fu">next</span> = head;</a>
<a class="sourceLine" id="cb8-14" title="14">    <span class="lang-js co">// link the new head to successor</span></a>
<a class="sourceLine" id="cb8-15" title="15">    head.<span class="lang-js fu">next</span> = successor;</a>
<a class="sourceLine" id="cb8-16" title="16">    <span class="lang-js kw">return</span> last;</a>
<a class="sourceLine" id="cb8-17" title="17">}    </a></code></pre>
                </div>
                <p>Main differences:</p>
                <ol type="1">
                    <li>Base case <code class="language-javascript  highlight" id="button" class="language-javascript">n
                            == 1</code>, if reverse only one element, then new
                        head is
                        itself, meanwhile
                        <strong>remember to mark the successor node</strong>.
                    </li>
                    <li>In previouse solution, we set <code class="language-javascript  highlight" id="button"
                            class="language-javascript">head.next</code> directly to
                        null,
                        because
                        after reversing the whole
                        list, head becoms the last node. But now <code class="language-javascript  highlight"
                            id="button" class="language-javascript">head</code> may not
                        be the
                        last
                        node after reversion, so we
                        need mark <code class="language-javascript  highlight" id="button"
                            class="language-javascript">successor</code> (the (n+1)th node), and link it to
                        <code class="language-javascript  highlight" id="button" class="language-javascript">head</code>
                        after reversion.
                    </li>
                </ol>
                <p><img src="../pictures/reverse_linked_list/7.jpg" /></p>
                <p>OK, now we are pretty close to reversing part of the linked list.</p>
                <h3 id="reverse-part-of-a-linked-list">3. Reverse part of a linked list</h3>
                <p>Given an interval <code class="language-javascript  highlight" id="button"
                        class="language-javascript">[m,n]</code> (index starts from 1), only reverse
                    elements
                    in
                    this section.</p>
                <div class="sourceCode" id="cb9">
                    <pre data-filter-output="(out)" class="sourceCode javascript" data-filter-output="(out)"
                        class="sourceCode java"><code  class="language-javascript  highlight" id="button" class="sourceCode java"><a class="sourceLine" id="cb9-1" title="1">ListNode <span class="lang-js fu">reverseBetween</span>(ListNode head, <span class="lang-js dt">int</span> m, <span class="lang-js dt">int</span> n)</a></code></pre>
                </div>
                <p>First, if <code class="language-javascript  highlight" id="button" class="language-javascript">m ==
                        1</code> , it is equal to reversing the first <code class="language-javascript  highlight"
                        id="button" class="language-javascript">n</code> elements as we discussed just
                    now.</p>
                <div class="sourceCode" id="cb10">
                    <pre data-filter-output="(out)" class="sourceCode javascript" data-filter-output="(out)"
                        class="sourceCode java"><code  class="language-javascript  highlight" id="button" class="sourceCode java"><a class="sourceLine" id="cb10-1" title="1">ListNode <span class="lang-js fu">reverseBetween</span>(ListNode head, <span class="lang-js dt">int</span> m, <span class="lang-js dt">int</span> n) {</a>
<a class="sourceLine" id="cb10-2" title="2">    <span class="lang-js co">// base case</span></a>
<a class="sourceLine" id="cb10-3" title="3">    <span class="lang-js kw">if</span> (m == <span class="lang-js dv">1</span>) {</a>
<a class="sourceLine" id="cb10-4" title="4">        <span class="lang-js co">// equals to reversing the first n nodes</span></a>
<a class="sourceLine" id="cb10-5" title="5">        <span class="lang-js kw">return</span> <span class="lang-js fu">reverseN</span>(head, n);</a>
<a class="sourceLine" id="cb10-6" title="6">    }</a>
<a class="sourceLine" id="cb10-7" title="7">    <span class="lang-js co">// ...</span></a>
<a class="sourceLine" id="cb10-8" title="8">}</a></code></pre>
                </div>
                <p>What if <code class="language-javascript  highlight" id="button" class="language-javascript">m !=
                        1</code> ? If we take the index of the <code class="language-javascript  highlight" id="button"
                        class="language-javascript">head</code> as 1, then we need to reverse from
                    the <code class="language-javascript  highlight" id="button" class="language-javascript">mth</code>
                    element. And what if we take the index of the <code class="language-javascript  highlight"
                        id="button" class="language-javascript">head.next</code> as 1? Then compared to
                    <code class="language-javascript  highlight" id="button"
                        class="language-javascript">head.next</code> , the reverse section should start from <code
                        class="language-javascript  highlight" id="button" class="language-javascript">(m-1)th</code>
                    element. And what about
                    <code class="language-javascript  highlight" id="button"
                        class="language-javascript">head.next.next</code> …
                </p>
                <p>Different from iteration, this is how we think in the recursive way, so our code should be:</p>
                <div class="sourceCode" id="cb11">
                    <pre data-filter-output="(out)" class="sourceCode javascript" data-filter-output="(out)"
                        class="sourceCode java"><code  class="language-javascript  highlight" id="button" class="sourceCode java"><a class="sourceLine" id="cb11-1" title="1">ListNode <span class="lang-js fu">reverseBetween</span>(ListNode head, <span class="lang-js dt">int</span> m, <span class="lang-js dt">int</span> n) {</a>
<a class="sourceLine" id="cb11-2" title="2">    <span class="lang-js co">// base case</span></a>
<a class="sourceLine" id="cb11-3" title="3">    <span class="lang-js kw">if</span> (m == <span class="lang-js dv">1</span>) {</a>
<a class="sourceLine" id="cb11-4" title="4">        <span class="lang-js kw">return</span> <span class="lang-js fu">reverseN</span>(head, n);</a>
<a class="sourceLine" id="cb11-5" title="5">    }</a>
<a class="sourceLine" id="cb11-6" title="6">    head.<span class="lang-js fu">next</span> = <span class="lang-js fu">reverseBetween</span>(head.<span class="lang-js fu">next</span>, m - <span class="lang-js dv">1</span>, n - <span class="lang-js dv">1</span>);</a>
<a class="sourceLine" id="cb11-7" title="7">    <span class="lang-js kw">return</span> head;</a>
<a class="sourceLine" id="cb11-8" title="8">}</a></code></pre>


                    <h2 id="stack-and-queue-properties">Stack and Queue Properties</h2>
                    Stacks and Queues are so similar in composition that we can discuss their properties together. They
                    track
                    the
                    following three properties:
                    <p align="center">
                        <b>Stack Properties | Queue Properties:</b>
                    </p>
                    <table>
                        <colgroup>
                            <col style="width: 10%" />
                            <col style="width: 39%" />
                            <col style="width: 10%" />
                            <col style="width: 39%" />
                        </colgroup>
                        <thead>
                            <tr class="header">
                                <th style="text-align: center;">Stack Property</th>
                                <th style="text-align: center;">Description</th>
                                <th style="text-align: center;">Queue Property</th>
                                <th style="text-align: center;">Description</th>
                            </tr>
                        </thead>
                        <tbody>
                            <tr class="odd">
                                <td style="text-align: center;"><code class="language-javascript  highlight"
                                        id="button">top</code></td>
                                <td style="text-align: center;">The first node in the Stack</td>
                                <td style="text-align: center;"><code class="language-javascript  highlight"
                                        id="button">front</code></td>
                                <td style="text-align: center;">The first node in the Queue.</td>
                            </tr>
                            <tr class="even">
                                <td style="text-align: center;">—-</td>
                                <td style="text-align: center;">Stacks do not have an equivalent</td>
                                <td style="text-align: center;"><code class="language-javascript  highlight"
                                        id="button">back</code></td>
                                <td style="text-align: center;">The last node in the Queue.</td>
                            </tr>
                            <tr class="odd">
                                <td style="text-align: center;"><code class="language-javascript  highlight"
                                        id="button">length</code></td>
                                <td style="text-align: center;">The number of nodes in the Stack; the Stack's length.
                                </td>
                                <td style="text-align: center;"><code class="language-javascript  highlight"
                                        id="button">length</code></td>
                                <td style="text-align: center;">The number of nodes in the Queue; the Queue's length.
                                </td>
                            </tr>
                        </tbody>
                    </table>
                    <p>Notice that rather than having a <code class="language-javascript  highlight"
                            id="button">head</code> and a <code class="language-javascript  highlight"
                            id="button">tail</code> like Linked Lists,
                        Stacks have
                        a
                        <code class="language-javascript  highlight" id="button">top</code>, and Queues have a <code
                            class="language-javascript  highlight" id="button">front</code> and a <code
                            class="language-javascript  highlight" id="button">back</code> instead. Stacks
                        don't
                        have
                        the
                        equivalent of a <code class="language-javascript  highlight" id="button">tail</code> because you
                        only ever push or pop things off the top of
                        Stacks. These
                        properties are essentially the same; pointers to the end points of the respective List ADT where
                        important
                        actions way take place. The differences in naming conventions are strictly for human
                        comprehension.
                    </p>
                    <hr />
                    <p>Similarly to Linked Lists, the values stored inside a Stack or a Queue are actually contained
                        within
                        Stack
                        Node
                        and Queue Node instances. Stack, Queue, and Singly Linked List Nodes are all identical, but just
                        as a
                        reminder
                        and for the sake of completion, these List Nodes track the following two properties:</p>
                    <p align="center">
                        <b>Stack &amp; Queue Node Properties:</b>
                    </p>
                    <table>
                        <thead>
                            <tr class="header">
                                <th style="text-align: center;">Property</th>
                                <th style="text-align: center;">Description</th>
                            </tr>
                        </thead>
                        <tbody>
                            <tr class="odd">
                                <td style="text-align: center;"><code class="language-javascript  highlight"
                                        id="button">value</code></td>
                                <td style="text-align: center;">The actual value this node represents.</td>
                            </tr>
                            <tr class="even">
                                <td style="text-align: center;"><code class="language-javascript  highlight"
                                        id="button">next</code></td>
                                <td style="text-align: center;">The next node in the Stack (relative to this node).</td>
                            </tr>
                        </tbody>
                    </table>
                    <h2 id="stack-methods">Stack Methods</h2>
                    <p>In the exercise that follows, we will implement a Stack data structure along with the following
                        Stack
                        methods:
                    </p>
                    <table>
                        <colgroup>
                            <col style="width: 9%" />
                            <col style="width: 12%" />
                            <col style="width: 45%" />
                            <col style="width: 32%" />
                        </colgroup>
                        <thead>
                            <tr class="header">
                                <th style="text-align: center;">Type</th>
                                <th style="text-align: center;">Name</th>
                                <th style="text-align: center;">Description</th>
                                <th style="text-align: center;">Returns</th>
                            </tr>
                        </thead>
                        <tbody>
                            <tr class="odd">
                                <td style="text-align: center;">Insertion</td>
                                <td style="text-align: center;"><code class="language-javascript  highlight"
                                        id="button">push</code></td>
                                <td style="text-align: center;">Adds a Node to the top of the Stack.</td>
                                <td style="text-align: center;">Integer - New size of stack</td>
                            </tr>
                            <tr class="even">
                                <td style="text-align: center;">Deletion</td>
                                <td style="text-align: center;"><code class="language-javascript  highlight"
                                        id="button">pop</code></td>
                                <td style="text-align: center;">Removes a Node from the top of the Stack.</td>
                                <td style="text-align: center;">Node removed from top of Stack</td>
                            </tr>
                            <tr class="odd">
                                <td style="text-align: center;">Meta</td>
                                <td style="text-align: center;"><code class="language-javascript  highlight"
                                        id="button">size</code></td>
                                <td style="text-align: center;">Returns the current size of the Stack.</td>
                                <td style="text-align: center;">Integer</td>
                            </tr>
                        </tbody>
                    </table>
                    <h2 id="queue-methods">Queue Methods</h2>
                    <p>In the exercise that follows, we will implement a Queue data structure along with the following
                        Queue
                        methods:
                    </p>
                    <table>
                        <colgroup>
                            <col style="width: 9%" />
                            <col style="width: 12%" />
                            <col style="width: 45%" />
                            <col style="width: 32%" />
                        </colgroup>
                        <thead>
                            <tr class="header">
                                <th style="text-align: center;">Type</th>
                                <th style="text-align: center;">Name</th>
                                <th style="text-align: center;">Description</th>
                                <th style="text-align: center;">Returns</th>
                            </tr>
                        </thead>
                        <tbody>
                            <tr class="odd">
                                <td style="text-align: center;">Insertion</td>
                                <td style="text-align: center;"><code class="language-javascript  highlight"
                                        id="button">enqueue</code></td>
                                <td style="text-align: center;">Adds a Node to the front of the Queue.</td>
                                <td style="text-align: center;">Integer - New size of Queue</td>
                            </tr>
                            <tr class="even">
                                <td style="text-align: center;">Deletion</td>
                                <td style="text-align: center;"><code class="language-javascript  highlight"
                                        id="button">dequeue</code></td>
                                <td style="text-align: center;">Removes a Node from the front of the Queue.</td>
                                <td style="text-align: center;">Node removed from front of Queue</td>
                            </tr>
                            <tr class="odd">
                                <td style="text-align: center;">Meta</td>
                                <td style="text-align: center;"><code class="language-javascript  highlight"
                                        id="button">size</code></td>
                                <td style="text-align: center;">Returns the current size of the Queue.</td>
                                <td style="text-align: center;">Integer</td>
                            </tr>
                        </tbody>
                    </table>
                    <h2 id="time-and-space-complexity-analysis-5">Time and Space Complexity Analysis</h2>
                    <p>Before we begin our analysis, here is a quick summary of the Time and Space constraints of each
                        Stack
                        Operation.
                    </p>
                    <table>
                        <colgroup>
                            <col style="width: 26%" />
                            <col style="width: 22%" />
                            <col style="width: 25%" />
                            <col style="width: 26%" />
                        </colgroup>
                        <thead>
                            <tr class="header">
                                <th style="text-align: center;">Data Structure Operation</th>
                                <th style="text-align: center;">Time Complexity (Avg)</th>
                                <th style="text-align: center;">Time Complexity (Worst)</th>
                                <th style="text-align: center;">Space Complexity (Worst)</th>
                            </tr>
                        </thead>
                        <tbody>
                            <tr class="odd">
                                <td style="text-align: center;">Access</td>
                                <td style="text-align: center;"><code class="language-javascript  highlight"
                                        id="button">Θ(n)</code></td>
                                <td style="text-align: center;"><code class="language-javascript  highlight"
                                        id="button">O(n)</code></td>
                                <td style="text-align: center;"><code class="language-javascript  highlight"
                                        id="button">O(n)</code></td>
                            </tr>
                            <tr class="even">
                                <td style="text-align: center;">Search</td>
                                <td style="text-align: center;"><code class="language-javascript  highlight"
                                        id="button">Θ(n)</code></td>
                                <td style="text-align: center;"><code class="language-javascript  highlight"
                                        id="button">O(n)</code></td>
                                <td style="text-align: center;"><code class="language-javascript  highlight"
                                        id="button">O(n)</code></td>
                            </tr>
                            <tr class="odd">
                                <td style="text-align: center;">Insertion</td>
                                <td style="text-align: center;"><code class="language-javascript  highlight"
                                        id="button">Θ(1)</code></td>
                                <td style="text-align: center;"><code class="language-javascript  highlight"
                                        id="button">O(1)</code></td>
                                <td style="text-align: center;"><code class="language-javascript  highlight"
                                        id="button">O(n)</code></td>
                            </tr>
                            <tr class="even">
                                <td style="text-align: center;">Deletion</td>
                                <td style="text-align: center;"><code class="language-javascript  highlight"
                                        id="button">Θ(1)</code></td>
                                <td style="text-align: center;"><code class="language-javascript  highlight"
                                        id="button">O(1)</code></td>
                                <td style="text-align: center;"><code class="language-javascript  highlight"
                                        id="button">O(n)</code></td>
                            </tr>
                        </tbody>
                    </table>
                    <p>Before moving forward, see if you can reason to yourself why each operation has the time and
                        space
                        complexity
                        listed above!</p>
                    <h4 id="time-complexity---access-and-search-1">Time Complexity - Access and Search:</h4>
                    <p>When the Stack ADT was first conceived, its inventor definitely did not prioritize searching and
                        accessing
                        individual Nodes or values in the list. The same idea applies for the Queue ADT. There are
                        certainly
                        better
                        data
                        structures for speedy search and lookup, and if these operations are a priority for your use
                        case, it
                        would
                        be
                        best to choose something else!</p>
                    <p>Search and Access are both linear time operations for Stacks and Queues, and that shouldn't be
                        too
                        unclear.
                        Both
                        ADTs are nearly identical to Linked Lists in this way. The only way to find a Node somewhere in
                        the
                        middle
                        of a
                        Stack or a Queue, is to start at the <code class="language-javascript  highlight"
                            id="button">top</code> (or the <code class="language-javascript  highlight"
                            id="button">back</code>) and traverse
                        downward
                        (or
                        forward) toward the <code class="language-javascript  highlight" id="button">bottom</code> (or
                        <code class="language-javascript  highlight" id="button">front</code>) one node at a time via
                        each
                        Node's
                        <code class="language-javascript  highlight" id="button">next</code> property.
                    </p>
                    <p>This is a linear time operation, O(n).</p>
                    <h4 id="time-complexity---insertion-and-deletion-1">Time Complexity - Insertion and Deletion:</h4>
                    <p>For Stacks and Queues, insertion and deletion is what it's all about. If there is one feature a
                        Stack
                        absolutely
                        must have, it's constant time insertion and removal to and from the <code
                            class="language-javascript  highlight" id="button">top</code> of the
                        Stack
                        (FIFO).
                        The
                        same applies for Queues, but with insertion occurring at the <code
                            class="language-javascript  highlight" id="button">back</code> and removal
                        occurring at
                        the
                        <code class="language-javascript  highlight" id="button">front</code> (LIFO).
                    </p>
                    <p>Think about it. When you add a plate to the top of a stack of plates, do you have to iterate
                        through all
                        of
                        the
                        other plates first to do so? Of course not. You simply add your plate to the top of the stack,
                        and
                        that's
                        that.
                        The concept is the same for removal.</p>
                    <p>Therefore, Stacks and Queues have constant time Insertion and Deletion via their
                        <code class="language-javascript  highlight" id="button">push</code> and
                        <code class="language-javascript  highlight" id="button">pop</code> or <code
                            class="language-javascript  highlight" id="button">enqueue</code> and <code
                            class="language-javascript  highlight" id="button">dequeue</code> methods, O(1).
                    </p>
                    <h4 id="space-complexity-2">Space Complexity:</h4>
                    <p>The space complexity of Stacks and Queues is very simple. Whether we are instantiating a new
                        instance of
                        a
                        Stack
                        or Queue to store a set of data, or we are using a Stack or Queue as part of a strategy to solve
                        some
                        problem,
                        Stacks and Queues always store one Node for each value they receive as input.</p>
                    <p>For this reason, we always consider Stacks and Queues to have a linear space complexity, O(n).
                    </p>
                    <h2 id="when-should-we-use-stacks-and-queues">When should we use Stacks and Queues?</h2>
                    <p>At this point, we've done a lot of work understanding the ins and outs of Stacks and Queues, but
                        we still
                        haven't
                        really discussed what we can use them for. The answer is actually…a lot!</p>
                    <p>For one, Stacks and Queues can be used as intermediate data structures while implementing some of
                        the
                        more
                        complicated data structures and methods we'll see in some of our upcoming sections.</p>
                    <p>For example, the implementation of the breadth-first Tree traversal algorithm takes advantage of
                        a Queue
                        instance, and the depth-first Graph traversal algorithm exploits the benefits of a Stack
                        instance.</p>
                    <p>Additionally, Stacks and Queues serve as the essential underlying data structures to a wide
                        variety of
                        applications you use all the time. Just to name a few:</p>
                    <h4 id="stacks">Stacks:</h4>
                    <ul>
                        <li>The Call Stack is a Stack data structure, and is used to manage the order of function
                            invocations in
                            your
                            code.</li>
                        <li>Browser History is often implemented using a Stack, with one great example being the browser
                            history
                            object
                            in the very popular React Router module.</li>
                        <li>Undo/Redo functionality in just about any application. For example:
                            <ul>
                                <li>When you're coding in your text editor, each of the actions you take on your
                                    keyboard are
                                    recorded
                                    by <code class="language-javascript  highlight" id="button">push</code>ing that
                                    event to a Stack.</li>
                                <li>When you hit [cmd + z] to undo your most recent action, that event is
                                    <code class="language-javascript  highlight" id="button">pop</code>ed off
                                    the
                                    Stack, because the last event that occured should be the first one to be undone
                                    (LIFO).
                                </li>
                                <li>When you hit [cmd + y] to redo your most recent action, that event is
                                    <code class="language-javascript  highlight" id="button">push</code>ed
                                    back
                                    onto
                                    the Stack.
                                </li>
                            </ul>
                        </li>
                    </ul>
                    <h4 id="queues">Queues:</h4>
                    <ul>
                        <li>Printers use a Queue to manage incoming jobs to ensure that documents are printed in the
                            order they
                            are
                            received.</li>
                        <li>Chat rooms, online video games, and customer service phone lines use a Queue to ensure that
                            patrons
                            are
                            served in the order they arrive.
                            <ul>
                                <li>In the case of a Chat Room, to be admitted to a size-limited room.</li>
                                <li>In the case of an Online Multi-Player Game, players wait in a lobby until there is
                                    enough
                                    space
                                    and
                                    it is their turn to be admitted to a game.</li>
                                <li>In the case of a Customer Service Phone Line…you get the point.</li>
                            </ul>
                        </li>
                        <li>As a more advanced use case, Queues are often used as components or services in the system
                            design of
                            a
                            service-oriented architecture. A very popular and easy to use example of this is Amazon's
                            Simple
                            Queue
                            Service (SQS), which is a part of their Amazon Web Services (AWS) offering.
                            <ul>
                                <li>You would add this service to your system between two other services, one that is
                                    sending
                                    information for processing, and one that is receiving information to be processed,
                                    when the
                                    volume
                                    of incoming requests is high and the integrity of the order with which those
                                    requests are
                                    processed
                                    must be maintained.</li>
                            </ul>
                        </li>
                    </ul>
                    <hr />


                    <hr />
                    <h1 id="graphs-and-heaps-">Graphs and Heaps </h1>
                    <p><strong>The objective of this lesson</strong> is for you to become comfortable with implementing
                        common
                        data
                        structures. This is important because questions about data structures are incredibly likely to
                        be
                        interview
                        questions for software engineers from junior to senior levels. Moreover, understanding how
                        different
                        data
                        structures work will influence the libraries and frameworks that you choose when writing
                        software.</p>
                    <p>When you are done, you will be able to:</p>
                    <ol type="1">
                        <li>Explain and implement a Heap.</li>
                        <li>Explain and implement a Graph.table with implementing common data structures. This is
                            important
                            because
                            questions about data structures are incredibly likely to be interview questions for software
                            engineers
                            from
                            junior to senior levels. Moreover, understanding how different data structures work will
                            influence
                            the
                            libraries and frameworks that you choose when writing software.</li>
                    </ol>
                    <p>When you are done, you will be able to:</p>
                    <ol type="1">
                        <li>Explain and implement a Heap.</li>
                        <li>Explain and implement a Graph.</li>
                    </ol>
                    <hr />
                    <h1 id="introduction-to-heaps">Introduction to Heaps</h1>
                    <p>Let's explore the <strong>Heap</strong> data structure! In particular, we'll explore
                        <strong>Binary
                            Heaps</strong>. A binary heap is a type of binary tree. However, a heap is not a binary
                        <em>search</em>
                        tree. A heap is a partially ordered data structure, whereas a BST has full order. In a heap, the
                        root of
                        the
                        tree will be the maximum (max heap) or the minimum (min heap). Below is an example of a max
                        heap:
                    </p>
                    <figure>
                        <img src="images/max_heap.png" alt="max_heap" />
                        <figcaption>max_heap</figcaption>
                    </figure>
                    <p>Notice that the heap above does not follow search tree property where all values to the left of a
                        node
                        are
                        less
                        and all values to the right are greater or equal. Instead, the max heap invariant is:</p>
                    <ul>
                        <li>given any node, its children must be less than or equal to the node</li>
                    </ul>
                    <p>This constraint makes heaps much more relaxed in structure compared to a search tree. There is no
                        guaranteed
                        order among "siblings" or "cousins" in a heap. The relationship only flows down the tree from
                        parent to
                        child.
                        In other words, in a max heap, a node will be greater than all of it's children, it's
                        grandchildren, its
                        great-grandchildren, and so on. A consequence of this is the root being the absolute maximum of
                        the
                        entire
                        tree.
                        We'll be exploring max heaps together, but these arguments are symmetric for a min heap.</p>
                    <h3 id="complete-trees">Complete Trees</h3>
                    <p>We'll eventually implement a max heap together, but first we'll need to take a quick detour. Our
                        design
                        goal
                        is
                        to implement a data structure with efficient operations. Since a heap is a type of binary tree,
                        recall
                        the
                        circumstances where we had a "best case" binary tree. We'll need to ensure our heap has minimal
                        height,
                        that
                        is,
                        it must be a balanced tree!</p>
                    <p>Our heap implementation will not only be balanced, but it will also be <strong>complete</strong>.
                        To
                        clarify,
                        <strong>every complete tree is also a balanced tree</strong>, but not every balanced tree is
                        also
                        complete.
                        Our
                        definition of a complete tree is:
                    </p>
                    <ul>
                        <li>a tree where all levels have the maximal number of nodes, except the bottom the level</li>
                        <li>AND the bottom level has all nodes filled as far left as possible</li>
                    </ul>
                    <p>Here are few examples of the definition:</p>
                    <figure>
                        <img src="images/complete_tree.png" alt="complete_tree" />
                        <figcaption>complete_tree</figcaption>
                    </figure>
                    <p>Notice that the tree is on the right fails the second point of our definition because there is a
                        gap in
                        the
                        last
                        level. Informally, you can think about a complete tree as packing its nodes as closely together
                        as
                        possible.
                        This line of thinking will come into play when we code heaps later.</p>
                    <h3 id="when-to-use-heaps">When to Use Heaps?</h3>
                    <p>Heaps are the most useful when attacking problems that require you to "partially sort" data. This
                        usually
                        takes
                        form in problems that have us calculate the largest or smallest n numbers of a collection. For
                        example:
                        What
                        if
                        you were asked to find the largest 5 numbers in an array in linear time, O(n)? The fastest
                        sorting
                        algorithms
                        are O(n logn), so none of those algorithms will be good enough. However, we can use a heap to
                        solve this
                        problem
                        in linear time.</p>
                    <p>We'll analyze this in depth when we implement a heap in the next section!</p>
                    <p>One of the most common uses of a binary heap is to implement a "<a
                            href="https://en.wikipedia.org/wiki/Priority_queue">priority queue</a>". We learned before
                        that a
                        queue
                        is a
                        FIFO (First In, First Out) data structure. With a priority queue, items are removed from the
                        queue based
                        on
                        a
                        priority number. The priority number is used to place the items into the heap and pull them out
                        in the
                        correct
                        priority order!</p>
                    <hr />
                    <h2 id="binary-heap-implementation">Binary Heap Implementation</h2>
                    <p>Now that we are familiar with the structure of a heap, let's implement one! What may be
                        surprising is
                        that
                        the
                        usual way to implement a heap is by simply using an array. That is, we won't need to create a
                        node class
                        with
                        pointers. Instead, each index of the array will represent a node, with the root being at index
                        1. We'll
                        avoid
                        using index 0 of the array so our math works out nicely. From this point, we'll use the
                        following rules
                        to
                        interpret the array as a heap:</p>
                    <ul>
                        <li>index <code class="language-javascript  highlight" id="button">i</code> represents a node in
                            the heap</li>
                        <li>the left child of node <code class="language-javascript  highlight" id="button">i</code> can
                            be found at index <code class="language-javascript  highlight" id="button">2 * i</code></li>
                        <li>the right child of code <code class="language-javascript  highlight" id="button">i</code>
                            can be found at index <code class="language-javascript  highlight" id="button">2 * i +
                                1</code></li>
                    </ul>
                    <p>In other words, the array <code class="language-javascript  highlight" id="button">[null, 42, 32,
                            24, 30, 9, 20, 18, 2, 7]</code> represents the
                        heap below.
                        Take a
                        moment to analyze how the array indices work out to represent left and right children.</p>
                    <figure>
                        <img src="https://s3-us-west-1.amazonaws.com/appacademy-open-assets/data_structures_algorithms/heaps/images/max_heap.png"
                            alt="max_heap" />
                        <figcaption>max_heap</figcaption>
                    </figure>
                    <p>Pretty clever math right? We can also describe the relationship from child to parent node. Say we
                        are
                        given a
                        node at index <code class="language-javascript  highlight" id="button">i</code> in the heap,
                        then it's parent is found at index <code class="language-javascript  highlight"
                            id="button">Math.floor(i
                            /
                            2)</code>.
                    </p>
                    <p>It's useful to visualize heap algorithms using the classic image of nodes and edges, but we'll
                        translate
                        that
                        into array index operations.</p>
                    <h3 id="insert">Insert</h3>
                    <p>What's a heap if we can't add data into it? We'll need a <code
                            class="language-javascript  highlight" id="button">insert</code> method that will add
                        a new
                        value
                        into the heap without voiding our heap property. In our <code
                            class="language-javascript  highlight" id="button">MaxHeap</code>, the property
                        states that a
                        node
                        must be greater than its children.</p>
                    <h4 id="visualizing-our-heap-as-a-tree-of-nodes">Visualizing our heap as a tree of nodes:</h4>
                    <ol type="1">
                        <li>We begin an insertion by adding the new node to the bottom leaf level of the heap,
                            preferring to
                            place
                            the
                            new node as far left in the level as possible. This ensures the tree remains complete.</li>
                        <li>Placing the new node there may momentarily break our heap property, so we need to restore it
                            by
                            moving
                            the
                            node up the tree into a legal position. Restoring the heap property is a matter of
                            continually
                            swapping
                            the
                            new node with it's parent while it's parent contains a smaller value. We refer to this
                            process as
                            <code class="language-javascript  highlight" id="button">siftUp</code>
                        </li>
                    </ol>
                    <h4 id="translating-that-into-array-operations">Translating that into array operations:</h4>
                    <ol type="1">
                        <li><code class="language-javascript  highlight" id="button">push</code> the new value to the
                            end of the array</li>
                        <li>continually swap that value toward the front of the array (following our child-parent index
                            rules)
                            until
                            heap property is restored</li>
                    </ol>
                    <h3 id="deletemax">DeleteMax</h3>
                    <p>This is the "fetch" operation of a heap. Since we maintain heap property throughout, the root of
                        the heap
                        will
                        always be the maximum value. We want to delete and return the root, whilst keeping the heap
                        property.
                    </p>
                    <h4 id="visualizing-our-heap-as-a-tree-of-nodes-1">Visualizing our heap as a tree of nodes:</h4>
                    <ol type="1">
                        <li>We begin the deletion by saving a reference to the root value (the max) to return later. We
                            then
                            locate
                            the
                            right most node of the bottom level and copy it's value into the root of the tree. We easily
                            delete
                            the
                            duplicate node at the leaf level. This ensures the tree remains complete.</li>
                        <li>Copying that value into the root may momentarily break our heap property, so we need to
                            restore it
                            by
                            moving
                            the node down the tree into a legal position. Restoring the heap property is a matter of
                            continually
                            swapping the node with the greater of it's two children. We refer to this process as
                            <code class="language-javascript  highlight" id="button">siftDown</code>.
                        </li>
                    </ol>
                    <h4 id="translating-that-into-array-operations-1">Translating that into array operations:</h4>
                    <ol type="1">
                        <li>The root is at index 1, so save it to return later. The right most node of the bottom level
                            would
                            just
                            be
                            the very last element of the array. Copy the last element into index 1, and pop off the last
                            element
                            (since
                            it now appears at the root).</li>
                        <li>Continually swap the new root toward the back of the array (following our parent-child index
                            rules)
                            until
                            heap property is restored. A node can have two children, so we should always prefer to swap
                            with the
                            greater
                            child.</li>
                    </ol>
                    <h3 id="time-complexity-analysis-1">Time Complexity Analysis</h3>
                    <ul>
                        <li>insert: <code class="language-javascript  highlight" id="button">O(log(n))</code></li>
                        <li>deleteMax: <code class="language-javascript  highlight" id="button">O(log(n))</code></li>
                    </ul>
                    <p>Recall that our heap will be a complete/balanced tree. This means it's height is
                        <code class="language-javascript  highlight" id="button">log(n)</code>
                        where
                        <code class="language-javascript  highlight" id="button">n</code> is the number of items. Both
                        <code class="language-javascript  highlight" id="button">insert</code> and <code
                            class="language-javascript  highlight" id="button">deleteMax</code> have
                        a time
                        complexity of <code class="language-javascript  highlight" id="button">log(n)</code> because of
                        <code class="language-javascript  highlight" id="button">siftUp</code> and <code
                            class="language-javascript  highlight" id="button">siftDown</code>
                        respectively.
                        In
                        worst case <code class="language-javascript  highlight" id="button">insert</code>, we will have
                        to <code class="language-javascript  highlight" id="button">siftUp</code> a leaf all the way to
                        the
                        root of
                        the
                        tree.
                        In the worst case <code class="language-javascript  highlight" id="button">deleteMax</code>, we
                        will have to <code class="language-javascript  highlight" id="button">siftDown</code> the new
                        root all
                        the way
                        down to
                        the leaf level. In either case, we'll have to traverse the full height of the tree,
                        <code class="language-javascript  highlight" id="button">log(n)</code>.
                    </p>
                    <h4 id="array-heapify-analysis">Array Heapify Analysis</h4>
                    <p>Now that we have established <code class="language-javascript  highlight"
                            id="button">O(log(n))</code> for a single insertion, let's analyze the
                        time
                        complexity
                        for
                        turning an array into a heap (we call this heapify, coming in the next project :)). The
                        algorithm itself
                        is
                        simple, just perform an <code class="language-javascript  highlight" id="button">insert</code>
                        for every element. Since there are <code class="language-javascript  highlight"
                            id="button">n</code>
                        elements
                        and
                        each
                        insert requires <code class="language-javascript  highlight" id="button">log(n)</code> time, our
                        total complexity for heapify is
                        <code class="language-javascript  highlight" id="button">O(nlog(n))</code>…
                        Or is
                        it?
                        There is actually a tighter bound on heapify. The proof requires some math that you won't find
                        valuable
                        in
                        your
                        job search, but do understand that the true time complexity of heapify is amortized
                        <code class="language-javascript  highlight" id="button">O(n)</code>.
                        Amortized
                        refers to the fact that our analysis is about performance over many insertions.
                    </p>
                    <h3 id="space-complexity-analysis">Space Complexity Analysis</h3>
                    <ul>
                        <li>
                            <p><code class="language-javascript  highlight" id="button">O(n)</code>, since we use a
                                single array to store heap data.heap, let's implement
                                one! What
                                may
                                be
                                surprising is that the usual way to implement a heap is by simply using an array. That
                                is, we
                                won't
                                need
                                to create a node class with pointers. Instead, each index of the array will represent a
                                node,
                                with
                                the
                                root being at index 1. We'll avoid using index 0 of the array so our math works out
                                nicely. From
                                this
                                point, we'll use the following rules to interpret the array as a heap:</p>
                        </li>
                        <li>index <code class="language-javascript  highlight" id="button">i</code> represents a node in
                            the heap</li>
                        <li>the left child of node <code class="language-javascript  highlight" id="button">i</code> can
                            be found at index <code class="language-javascript  highlight" id="button">2 * i</code></li>
                        <li>
                            <p>the right child of code <code class="language-javascript  highlight" id="button">i</code>
                                can be found at index <code class="language-javascript  highlight" id="button">2 * i +
                                    1</code></p>
                        </li>
                    </ul>
                    <p>In other words, the array <code class="language-javascript  highlight" id="button">[null, 42, 32,
                            24, 30, 9, 20, 18, 2, 7]</code> represents the
                        heap below.
                        Take a
                        moment to analyze how the array indices work out to represent left and right children.</p>
                    <figure>
                        <img src="https://s3-us-west-1.amazonaws.com/appacademy-open-assets/data_structures_algorithms/heaps/images/max_heap.png"
                            alt="max_heap" />
                        <figcaption>max_heap</figcaption>
                    </figure>
                    <p>Pretty clever math right? We can also describe the relationship from child to parent node. Say we
                        are
                        given a
                        node at index <code class="language-javascript  highlight" id="button">i</code> in the heap,
                        then it's parent is found at index <code class="language-javascript  highlight"
                            id="button">Math.floor(i
                            /
                            2)</code>.
                    </p>
                    <p>It's useful to visualize heap algorithms using the classic image of nodes and edges, but we'll
                        translate
                        that
                        into array index operations.</p>
                    <h3 id="insert-1">Insert</h3>
                    <p>What's a heap if we can't add data into it? We'll need a <code
                            class="language-javascript  highlight" id="button">insert</code> method that will add
                        a new
                        value
                        into the heap without voiding our heap property. In our <code
                            class="language-javascript  highlight" id="button">MaxHeap</code>, the property
                        states that a
                        node
                        must be greater than its children.</p>
                    <h4 id="visualizing-our-heap-as-a-tree-of-nodes-2">Visualizing our heap as a tree of nodes:</h4>
                    <ol type="1">
                        <li>We begin an insertion by adding the new node to the bottom leaf level of the heap,
                            preferring to
                            place
                            the
                            new node as far left in the level as possible. This ensures the tree remains complete.</li>
                        <li>Placing the new node there may momentarily break our heap property, so we need to restore it
                            by
                            moving
                            the
                            node up the tree into a legal position. Restoring the heap property is a matter of
                            continually
                            swapping
                            the
                            new node with it's parent while it's parent contains a smaller value. We refer to this
                            process as
                            <code class="language-javascript  highlight" id="button">siftUp</code>
                        </li>
                    </ol>
                    <h4 id="translating-that-into-array-operations-2">Translating that into array operations:</h4>
                    <ol type="1">
                        <li><code class="language-javascript  highlight" id="button">push</code> the new value to the
                            end of the array</li>
                        <li>continually swap that value toward the front of the array (following our child-parent index
                            rules)
                            until
                            heap property is restored</li>
                    </ol>
                    <h3 id="deletemax-1">DeleteMax</h3>
                    <p>This is the "fetch" operation of a heap. Since we maintain heap property throughout, the root of
                        the heap
                        will
                        always be the maximum value. We want to delete and return the root, whilst keeping the heap
                        property.
                    </p>
                    <h4 id="visualizing-our-heap-as-a-tree-of-nodes-3">Visualizing our heap as a tree of nodes:</h4>
                    <ol type="1">
                        <li>We begin the deletion by saving a reference to the root value (the max) to return later. We
                            then
                            locate
                            the
                            right most node of the bottom level and copy it's value into the root of the tree. We easily
                            delete
                            the
                            duplicate node at the leaf level. This ensures the tree remains complete.</li>
                        <li>Copying that value into the root may momentarily break our heap property, so we need to
                            restore it
                            by
                            moving
                            the node down the tree into a legal position. Restoring the heap property is a matter of
                            continually
                            swapping the node with the greater of it's two children. We refer to this process as
                            <code class="language-javascript  highlight" id="button">siftDown</code>.
                        </li>
                    </ol>
                    <h4 id="translating-that-into-array-operations-3">Translating that into array operations:</h4>
                    <ol type="1">
                        <li>The root is at index 1, so save it to return later. The right most node of the bottom level
                            would
                            just
                            be
                            the very last element of the array. Copy the last element into index 1, and pop off the last
                            element
                            (since
                            it now appears at the root).</li>
                        <li>Continually swap the new root toward the back of the array (following our parent-child index
                            rules)
                            until
                            heap property is restored. A node can have two children, so we should always prefer to swap
                            with the
                            greater
                            child.</li>
                    </ol>
                    <h3 id="time-complexity-analysis-2">Time Complexity Analysis</h3>
                    <ul>
                        <li>insert: <code class="language-javascript  highlight" id="button">O(log(n))</code></li>
                        <li>deleteMax: <code class="language-javascript  highlight" id="button">O(log(n))</code></li>
                    </ul>
                    <p>Recall that our heap will be a complete/balanced tree. This means it's height is
                        <code class="language-javascript  highlight" id="button">log(n)</code>
                        where
                        <code class="language-javascript  highlight" id="button">n</code> is the number of items. Both
                        <code class="language-javascript  highlight" id="button">insert</code> and <code
                            class="language-javascript  highlight" id="button">deleteMax</code> have
                        a time
                        complexity of <code class="language-javascript  highlight" id="button">log(n)</code> because of
                        <code class="language-javascript  highlight" id="button">siftUp</code> and <code
                            class="language-javascript  highlight" id="button">siftDown</code>
                        respectively.
                        In
                        worst case <code class="language-javascript  highlight" id="button">insert</code>, we will have
                        to <code class="language-javascript  highlight" id="button">siftUp</code> a leaf all the way to
                        the
                        root of
                        the
                        tree.
                        In the worst case <code class="language-javascript  highlight" id="button">deleteMax</code>, we
                        will have to <code class="language-javascript  highlight" id="button">siftDown</code> the new
                        root all
                        the way
                        down to
                        the leaf level. In either case, we'll have to traverse the full height of the tree,
                        <code class="language-javascript  highlight" id="button">log(n)</code>.
                    </p>
                    <h4 id="array-heapify-analysis-1">Array Heapify Analysis</h4>
                    <p>Now that we have established <code class="language-javascript  highlight"
                            id="button">O(log(n))</code> for a single insertion, let's analyze the
                        time
                        complexity
                        for
                        turning an array into a heap (we call this heapify, coming in the next project :)). The
                        algorithm itself
                        is
                        simple, just perform an <code class="language-javascript  highlight" id="button">insert</code>
                        for every element. Since there are <code class="language-javascript  highlight"
                            id="button">n</code>
                        elements
                        and
                        each
                        insert requires <code class="language-javascript  highlight" id="button">log(n)</code> time, our
                        total complexity for heapify is
                        <code class="language-javascript  highlight" id="button">O(nlog(n))</code>…
                        Or is
                        it?
                        There is actually a tighter bound on heapify. The proof requires some math that you won't find
                        valuable
                        in
                        your
                        job search, but do understand that the true time complexity of heapify is amortized
                        <code class="language-javascript  highlight" id="button">O(n)</code>.
                        Amortized
                        refers to the fact that our analysis is about performance over many insertions.
                    </p>
                    <h3 id="space-complexity-analysis-1">Space Complexity Analysis</h3>
                    <ul>
                        <li><code class="language-javascript  highlight" id="button">O(n)</code>, since we use a single
                            array to store heap data.</li>
                    </ul>
                    <hr />
                    <h2 id="heap-sort">Heap Sort</h2>
                    <p>We've emphasized heavily that heaps are a <em>partially ordered</em> data structure. However, we
                        can
                        still
                        leverage heaps in a sorting algorithm to end up with fully sorted array. The strategy is simple
                        using
                        our
                        previous <code class="language-javascript  highlight" id="button">MaxHeap</code> implementation:
                    </p>
                    <ol type="1">
                        <li>build the heap: <code class="language-javascript  highlight" id="button">insert</code> all
                            elements of the array into a <code class="language-javascript  highlight"
                                id="button">MaxHeap</code>
                        </li>
                        <li>construct the sorted list: continue to <code class="language-javascript  highlight"
                                id="button">deleteMax</code> until the heap is empty, every
                            deletion
                            will
                            return the next element in decreasing order</li>
                    </ol>
                    <p>The code is straightforward:</p>
                    <div class="sourceCode" id="cb65">
                        <pre data-filter-output="(out)" class="sourceCode javascript" class="sourceCode javascript"><code  class="language-javascript  highlight" id="button" class="sourceCode javascript"><a class="sourceLine" id="cb65-1" title="1"><span class="co">// assuming our `MaxHeap` from the previous section</span></a>
<a class="sourceLine" id="cb65-2" title="2"></a>
<a class="sourceLine" id="cb65-3" title="3"><span class="kw">function</span> <span class="at">heapSort</span>(array) <span class="op">{</span></a>
<a class="sourceLine" id="cb65-4" title="4">    <span class="co">// Step 1: build the heap</span></a>
<a class="sourceLine" id="cb65-5" title="5">    <span class="kw">let</span> heap <span class="op">=</span> <span class="kw">new</span> <span class="at">MaxHeap</span>()<span class="op">;</span></a>
<a class="sourceLine" id="cb65-6" title="6">    <span class="va">array</span>.<span class="at">forEach</span>(num <span class="kw">=&gt;</span> <span class="va">heap</span>.<span class="at">insert</span>(num))<span class="op">;</span></a>
<a class="sourceLine" id="cb65-7" title="7"></a>
<a class="sourceLine" id="cb65-8" title="8">    <span class="co">// Step 2: constructed the sorted array</span></a>
<a class="sourceLine" id="cb65-9" title="9">    <span class="kw">let</span> sorted <span class="op">=</span> []<span class="op">;</span></a>
<a class="sourceLine" id="cb65-10" title="10">    <span class="cf">while</span> (<span class="va">heap</span>.<span class="va">array</span>.<span class="at">length</span> <span class="op">&gt;</span> <span class="dv">1</span>) <span class="op">{</span></a>
<a class="sourceLine" id="cb65-11" title="11">        <span class="va">sorted</span>.<span class="at">push</span>(<span class="va">heap</span>.<span class="at">deleteMax</span>())<span class="op">;</span></a>
<a class="sourceLine" id="cb65-12" title="12">    <span class="op">}</span></a>
<a class="sourceLine" id="cb65-13" title="13"></a>
<a class="sourceLine" id="cb65-14" title="14">    <span class="cf">return</span> sorted<span class="op">;</span></a>
<a class="sourceLine" id="cb65-15" title="15"><span class="op">}</span></a></code></pre>
                    </div>
                    <h3 id="time-complexity-analysis-onlogn">Time Complexity Analysis: O(nlog(n))</h3>
                    <ul>
                        <li><code class="language-javascript  highlight" id="button">n</code> is the size of the input
                            array</li>
                        <li>step-1 requires <code class="language-javascript  highlight" id="button">O(n)</code> time as
                            previously discussed</li>
                        <li>step-2's while loop requires <code class="language-javascript  highlight"
                                id="button">n</code> steps in isolation and each
                            <code class="language-javascript  highlight" id="button">deleteMax</code> will
                            require
                            <code class="language-javascript  highlight" id="button">log(n)</code> steps to restore max
                            heap property (due to sifting-down). This means
                            step 2
                            costs
                            <code class="language-javascript  highlight" id="button">O(nlog(n))</code>
                        </li>
                        <li>the total time complexity of the algorithm is <code class="language-javascript  highlight"
                                id="button">O(n + nlog(n)) = O(nlog(n))</code></li>
                    </ul>
                    <h3 id="space-complexity-analysis-2">Space Complexity Analysis:</h3>
                    <p>So <code class="language-javascript  highlight" id="button">heapSort</code> performs as fast as
                        our other efficient sorting algorithms, but how does
                        it fair
                        in
                        space complexity? Our implementation above requires an extra <code
                            class="language-javascript  highlight" id="button">O(n)</code> amount of space
                        because
                        the
                        heap
                        is maintained separately from the input array. If we can figure out a way to do all of these
                        heap
                        operations
                        in-place we can get constant <code class="language-javascript  highlight"
                            id="button">O(1)</code> space! Let's work on this now.</p>
                    <h2 id="in-place-heap-sort">In-Place Heap Sort</h2>
                    <p>The in-place algorithm will have the same 2 steps, but it will differ in the implementation
                        details.
                        Since we
                        need to have all operations take place in a single array, we're going to have to denote two
                        regions of
                        the
                        array. That is, we'll need a heap region and a sorted region. We begin by turning the entire
                        region into
                        a
                        heap.
                        Then we continually delete max to get the next element in increasing order. As the heap region
                        shrinks,
                        the
                        sorted region will grow.</p>
                    <h3 id="heapify">Heapify</h3>
                    <p>Let's focus on designing step-1 as an in-place algorithm. In other words, we'll need to reorder
                        elements
                        of
                        the
                        input array so they follow max heap property. This is usually refered to as
                        <code class="language-javascript  highlight" id="button">heapify</code>. Our
                        <code class="language-javascript  highlight" id="button">heapify</code> will use much of the
                        same logic as <code class="language-javascript  highlight" id="button">MaxHeap#siftDown</code>.
                    </p>
                    <div class="sourceCode" id="cb66">
                        <pre data-filter-output="(out)" class="sourceCode javascript" class="sourceCode javascript"><code  class="language-javascript  highlight" id="button" class="sourceCode javascript"><a class="sourceLine" id="cb66-1" title="1"><span class="co">// swap the elements at indices i and j of array</span></a>
<a class="sourceLine" id="cb66-2" title="2"><span class="kw">function</span> <span class="at">swap</span>(array<span class="op">,</span> i<span class="op">,</span> j) <span class="op">{</span></a>
<a class="sourceLine" id="cb66-3" title="3">    [ array[i]<span class="op">,</span> array[j] ] <span class="op">=</span> [ array[j]<span class="op">,</span> array[i] ]<span class="op">;</span></a>
<a class="sourceLine" id="cb66-4" title="4"><span class="op">}</span></a>
<a class="sourceLine" id="cb66-5" title="5"></a>
<a class="sourceLine" id="cb66-6" title="6"><span class="co">// sift-down the node at index i until max heap property is restored</span></a>
<a class="sourceLine" id="cb66-7" title="7"><span class="co">// n represents the size of the heap</span></a>
<a class="sourceLine" id="cb66-8" title="8"><span class="kw">function</span> <span class="at">heapify</span>(array<span class="op">,</span> n<span class="op">,</span> i) <span class="op">{</span></a>
<a class="sourceLine" id="cb66-9" title="9">    <span class="kw">let</span> leftIdx <span class="op">=</span> <span class="dv">2</span> <span class="op">*</span> i <span class="op">+</span> <span class="dv">1</span><span class="op">;</span></a>
<a class="sourceLine" id="cb66-10" title="10">    <span class="kw">let</span> rightIdx <span class="op">=</span> <span class="dv">2</span> <span class="op">*</span> i <span class="op">+</span> <span class="dv">2</span><span class="op">;</span></a>
<a class="sourceLine" id="cb66-11" title="11"></a>
<a class="sourceLine" id="cb66-12" title="12">    <span class="kw">let</span> leftVal <span class="op">=</span> array[leftIdx]<span class="op">;</span></a>
<a class="sourceLine" id="cb66-13" title="13">    <span class="kw">let</span> rightVal <span class="op">=</span> array[rightIdx]<span class="op">;</span></a>
<a class="sourceLine" id="cb66-14" title="14"></a>
<a class="sourceLine" id="cb66-15" title="15">    <span class="cf">if</span> (leftIdx <span class="op">&gt;=</span> n) leftVal <span class="op">=</span> <span class="op">-</span><span class="kw">Infinity</span><span class="op">;</span></a>
<a class="sourceLine" id="cb66-16" title="16">    <span class="cf">if</span> (rightIdx <span class="op">&gt;=</span> n) rightVal <span class="op">=</span> <span class="op">-</span><span class="kw">Infinity</span><span class="op">;</span></a>
<a class="sourceLine" id="cb66-17" title="17"></a>
<a class="sourceLine" id="cb66-18" title="18">    <span class="cf">if</span> (array[i] <span class="op">&gt;</span> leftVal <span class="op">&amp;&amp;</span> array[i] <span class="op">&gt;</span> rightVal) <span class="cf">return</span><span class="op">;</span></a>
<a class="sourceLine" id="cb66-19" title="19"></a>
<a class="sourceLine" id="cb66-20" title="20">    <span class="kw">let</span> swapIdx<span class="op">;</span></a>
<a class="sourceLine" id="cb66-21" title="21">    <span class="cf">if</span> (leftVal <span class="op">&lt;</span> rightVal) <span class="op">{</span></a>
<a class="sourceLine" id="cb66-22" title="22">        swapIdx <span class="op">=</span> rightIdx<span class="op">;</span></a>
<a class="sourceLine" id="cb66-23" title="23">    <span class="op">}</span> <span class="cf">else</span> <span class="op">{</span></a>
<a class="sourceLine" id="cb66-24" title="24">        swapIdx <span class="op">=</span> leftIdx<span class="op">;</span></a>
<a class="sourceLine" id="cb66-25" title="25">    <span class="op">}</span></a>
<a class="sourceLine" id="cb66-26" title="26">    <span class="at">swap</span>(array<span class="op">,</span> i<span class="op">,</span> swapIdx)<span class="op">;</span></a>
<a class="sourceLine" id="cb66-27" title="27">    <span class="at">heapify</span>(array<span class="op">,</span> n<span class="op">,</span> swapIdx)<span class="op">;</span></a>
<a class="sourceLine" id="cb66-28" title="28"><span class="op">}</span></a></code></pre>
                    </div>
                    <p>We weren't kidding when we said this would be similar to <code
                            class="language-javascript  highlight" id="button">MaxHeap#siftDown</code>. If you
                        are not
                        convinced,
                        flip to the previous section and take a look! The few differences we want to emphasize are:</p>
                    <ul>
                        <li>Given a node at index <code class="language-javascript  highlight" id="button">i</code>,
                            it's left index is <code class="language-javascript  highlight" id="button">2 * i + 1</code>
                            and it's
                            right index
                            is
                            <code class="language-javascript  highlight" id="button">2 * i + 2</code>
                            <ul>
                                <li>Using these as our child index formulas will allow us to avoid using a placeholder
                                    element
                                    at
                                    index
                                    0. The root of the heap will be at index 0.</li>
                            </ul>
                        </li>
                        <li>The parameter <code class="language-javascript  highlight" id="button">n</code> represents
                            the number of nodes in the heap
                            <ul>
                                <li>You may feel that <code class="language-javascript  highlight"
                                        id="button">array.length</code> also represents the number of nodes in
                                    the heap.
                                    That is
                                    true, but only in step-1. Later we will need to dynamically state the size of the
                                    heap.
                                    Remember, we
                                    are trying to do this without creating any extra arrays. We'll need to separate the
                                    heap and
                                    sorted
                                    regions of the array and <code class="language-javascript  highlight"
                                        id="button">n</code> will dictate the end of the heap.</li>
                            </ul>
                        </li>
                        <li>We created a separate <code class="language-javascript  highlight" id="button">swap</code>
                            helper function.
                            <ul>
                                <li>Nothing fancy here. Swapping will be valuable in step-2 of the algorithm as well, so
                                    we'll
                                    want
                                    to
                                    keep our code DRY (don't repeat yourself).</li>
                            </ul>
                        </li>
                    </ul>
                    <p>To correctly convert the input array into a heap, we'll need to call <code
                            class="language-javascript  highlight" id="button">heapify</code> on
                        children
                        nodes
                        before their parents. This is easy to do, just call <code class="language-javascript  highlight"
                            id="button">heapify</code> on each element
                        right-to-left
                        in
                        the
                        array:</p>
                    <div class="sourceCode" id="cb67">
                        <pre data-filter-output="(out)" class="sourceCode javascript" class="sourceCode javascript"><code  class="language-javascript  highlight" id="button" class="sourceCode javascript"><a class="sourceLine" id="cb67-1" title="1"><span class="kw">function</span> <span class="at">heapSort</span>(array) <span class="op">{</span></a>
<a class="sourceLine" id="cb67-2" title="2">    <span class="co">// heapify the tree from the bottom up</span></a>
<a class="sourceLine" id="cb67-3" title="3">    <span class="cf">for</span> (<span class="kw">let</span> i <span class="op">=</span> <span class="va">array</span>.<span class="at">length</span> <span class="op">-</span> <span class="dv">1</span><span class="op">;</span> i <span class="op">&gt;=</span> <span class="dv">0</span><span class="op">;</span> i<span class="op">--</span>) <span class="op">{</span></a>
<a class="sourceLine" id="cb67-4" title="4">        <span class="at">heapify</span>(array<span class="op">,</span> <span class="va">array</span>.<span class="at">length</span><span class="op">,</span> i)<span class="op">;</span></a>
<a class="sourceLine" id="cb67-5" title="5">    <span class="op">}</span></a>
<a class="sourceLine" id="cb67-6" title="6">    <span class="co">// the entire array is now a heap</span></a>
<a class="sourceLine" id="cb67-7" title="7">    <span class="co">// ...</span></a>
<a class="sourceLine" id="cb67-8" title="8"><span class="op">}</span></a></code></pre>
                    </div>
                    <p>Nice! Now the elements of the array have been moved around to obey max heap property.</p>
                    <h3 id="construct-the-sorted-array">Construct the Sorted Array</h3>
                    <p>To put everything together, we'll need to continually "delete max" from our heap. From our
                        previous
                        lecture,
                        we
                        learned the steps for deletion are to swap the last node of the heap into the root and then sift
                        the new
                        root
                        down to restore max heap property. We'll follow the same logic here, except we'll need to
                        account for
                        the
                        sorted
                        region of the array. The array will contain the heap region in the front and the sorted region
                        at the
                        rear:
                    </p>
                    <div class="sourceCode" id="cb68">
                        <pre data-filter-output="(out)" class="sourceCode javascript" class="sourceCode javascript"><code  class="language-javascript  highlight" id="button" class="sourceCode javascript"><a class="sourceLine" id="cb68-1" title="1"><span class="kw">function</span> <span class="at">heapSort</span>(array) <span class="op">{</span></a>
<a class="sourceLine" id="cb68-2" title="2">    <span class="co">// heapify the tree from the bottom up</span></a>
<a class="sourceLine" id="cb68-3" title="3">    <span class="cf">for</span> (<span class="kw">let</span> i <span class="op">=</span> <span class="va">array</span>.<span class="at">length</span> <span class="op">-</span> <span class="dv">1</span><span class="op">;</span> i <span class="op">&gt;=</span> <span class="dv">0</span><span class="op">;</span> i<span class="op">--</span>) <span class="op">{</span></a>
<a class="sourceLine" id="cb68-4" title="4">        <span class="at">heapify</span>(array<span class="op">,</span> <span class="va">array</span>.<span class="at">length</span><span class="op">,</span> i)<span class="op">;</span></a>
<a class="sourceLine" id="cb68-5" title="5">    <span class="op">}</span></a>
<a class="sourceLine" id="cb68-6" title="6">    <span class="co">// the entire array is now a heap</span></a>
<a class="sourceLine" id="cb68-7" title="7"></a>
<a class="sourceLine" id="cb68-8" title="8">    <span class="co">// until the heap is empty, continue to &quot;delete max&quot;</span></a>
<a class="sourceLine" id="cb68-9" title="9">    <span class="cf">for</span> (<span class="kw">let</span> endOfHeap <span class="op">=</span> <span class="va">array</span>.<span class="at">length</span> <span class="op">-</span> <span class="dv">1</span><span class="op">;</span> endOfHeap <span class="op">&gt;=</span> <span class="dv">0</span><span class="op">;</span> endOfHeap<span class="op">--</span>) <span class="op">{</span></a>
<a class="sourceLine" id="cb68-10" title="10">        <span class="co">// swap the root of the heap with the last element of the heap,</span></a>
<a class="sourceLine" id="cb68-11" title="11">        <span class="co">// this effecively shrinks the heap by one and grows the sorted array by one</span></a>
<a class="sourceLine" id="cb68-12" title="12">        <span class="at">swap</span>(array<span class="op">,</span> endOfHeap<span class="op">,</span> <span class="dv">0</span>)<span class="op">;</span></a>
<a class="sourceLine" id="cb68-13" title="13"></a>
<a class="sourceLine" id="cb68-14" title="14">        <span class="co">// sift down the new root, but not past the end of the heap</span></a>
<a class="sourceLine" id="cb68-15" title="15">        <span class="at">heapify</span>(array<span class="op">,</span> endOfHeap<span class="op">,</span> <span class="dv">0</span>)<span class="op">;</span></a>
<a class="sourceLine" id="cb68-16" title="16">    <span class="op">}</span></a>
<a class="sourceLine" id="cb68-17" title="17">    <span class="cf">return</span> array<span class="op">;</span></a>
<a class="sourceLine" id="cb68-18" title="18"><span class="op">}</span></a></code></pre>
                    </div>
                    <p>You'll definitely want to watch the lecture that follows this reading to get a visual of how the
                        array is
                        divided
                        into the heap and sorted regions.</p>
                    <h3 id="in-place-heap-sort-javascript-implementation">In-Place Heap Sort JavaScript Implementation
                    </h3>
                    <p>Here is the full code for your reference:</p>
                    <div class="sourceCode" id="cb69">
                        <pre data-filter-output="(out)" class="sourceCode javascript" class="sourceCode javascript"><code  class="language-javascript  highlight" id="button" class="sourceCode javascript"><a class="sourceLine" id="cb69-1" title="1"><span class="kw">function</span> <span class="at">heapSort</span>(array) <span class="op">{</span></a>
<a class="sourceLine" id="cb69-2" title="2">    <span class="cf">for</span> (<span class="kw">let</span> i <span class="op">=</span> <span class="va">array</span>.<span class="at">length</span> <span class="op">-</span> <span class="dv">1</span><span class="op">;</span> i <span class="op">&gt;=</span> <span class="dv">0</span><span class="op">;</span> i<span class="op">--</span>) <span class="op">{</span></a>
<a class="sourceLine" id="cb69-3" title="3">        <span class="at">heapify</span>(array<span class="op">,</span> <span class="va">array</span>.<span class="at">length</span><span class="op">,</span> i)<span class="op">;</span></a>
<a class="sourceLine" id="cb69-4" title="4">    <span class="op">}</span></a>
<a class="sourceLine" id="cb69-5" title="5"></a>
<a class="sourceLine" id="cb69-6" title="6">    <span class="cf">for</span> (<span class="kw">let</span> endOfHeap <span class="op">=</span> <span class="va">array</span>.<span class="at">length</span> <span class="op">-</span> <span class="dv">1</span><span class="op">;</span> endOfHeap <span class="op">&gt;=</span> <span class="dv">0</span><span class="op">;</span> endOfHeap<span class="op">--</span>) <span class="op">{</span></a>
<a class="sourceLine" id="cb69-7" title="7">        <span class="at">swap</span>(array<span class="op">,</span> endOfHeap<span class="op">,</span> <span class="dv">0</span>)<span class="op">;</span></a>
<a class="sourceLine" id="cb69-8" title="8">        <span class="at">heapify</span>(array<span class="op">,</span> endOfHeap<span class="op">,</span> <span class="dv">0</span>)<span class="op">;</span></a>
<a class="sourceLine" id="cb69-9" title="9">    <span class="op">}</span></a>
<a class="sourceLine" id="cb69-10" title="10">    </a>
<a class="sourceLine" id="cb69-11" title="11">    <span class="cf">return</span> array<span class="op">;</span></a>
<a class="sourceLine" id="cb69-12" title="12"><span class="op">}</span></a>
<a class="sourceLine" id="cb69-13" title="13"></a>
<a class="sourceLine" id="cb69-14" title="14"><span class="kw">function</span> <span class="at">heapify</span>(array<span class="op">,</span> n<span class="op">,</span> i) <span class="op">{</span></a>
<a class="sourceLine" id="cb69-15" title="15">    <span class="kw">let</span> leftIdx <span class="op">=</span> <span class="dv">2</span> <span class="op">*</span> i <span class="op">+</span> <span class="dv">1</span><span class="op">;</span></a>
<a class="sourceLine" id="cb69-16" title="16">    <span class="kw">let</span> rightIdx <span class="op">=</span> <span class="dv">2</span> <span class="op">*</span> i <span class="op">+</span> <span class="dv">2</span><span class="op">;</span></a>
<a class="sourceLine" id="cb69-17" title="17"></a>
<a class="sourceLine" id="cb69-18" title="18">    <span class="kw">let</span> leftVal <span class="op">=</span> array[leftIdx]<span class="op">;</span></a>
<a class="sourceLine" id="cb69-19" title="19">    <span class="kw">let</span> rightVal <span class="op">=</span> array[rightIdx]<span class="op">;</span></a>
<a class="sourceLine" id="cb69-20" title="20"></a>
<a class="sourceLine" id="cb69-21" title="21">    <span class="cf">if</span> (leftIdx <span class="op">&gt;=</span> n) leftVal <span class="op">=</span> <span class="op">-</span><span class="kw">Infinity</span><span class="op">;</span></a>
<a class="sourceLine" id="cb69-22" title="22">    <span class="cf">if</span> (rightIdx <span class="op">&gt;=</span> n) rightVal <span class="op">=</span> <span class="op">-</span><span class="kw">Infinity</span><span class="op">;</span></a>
<a class="sourceLine" id="cb69-23" title="23"></a>
<a class="sourceLine" id="cb69-24" title="24">    <span class="cf">if</span> (array[i] <span class="op">&gt;</span> leftVal <span class="op">&amp;&amp;</span> array[i] <span class="op">&gt;</span> rightVal) <span class="cf">return</span><span class="op">;</span></a>
<a class="sourceLine" id="cb69-25" title="25"></a>
<a class="sourceLine" id="cb69-26" title="26">    <span class="kw">let</span> swapIdx<span class="op">;</span></a>
<a class="sourceLine" id="cb69-27" title="27">    <span class="cf">if</span> (leftVal <span class="op">&lt;</span> rightVal) <span class="op">{</span></a>
<a class="sourceLine" id="cb69-28" title="28">        swapIdx <span class="op">=</span> rightIdx<span class="op">;</span></a>
<a class="sourceLine" id="cb69-29" title="29">    <span class="op">}</span> <span class="cf">else</span> <span class="op">{</span></a>
<a class="sourceLine" id="cb69-30" title="30">        swapIdx <span class="op">=</span> leftIdx<span class="op">;</span></a>
<a class="sourceLine" id="cb69-31" title="31">    <span class="op">}</span></a>
<a class="sourceLine" id="cb69-32" title="32">    <span class="at">swap</span>(array<span class="op">,</span> i<span class="op">,</span> swapIdx)<span class="op">;</span></a>
<a class="sourceLine" id="cb69-33" title="33">    <span class="at">heapify</span>(array<span class="op">,</span> n<span class="op">,</span> swapIdx)<span class="op">;</span></a>
<a class="sourceLine" id="cb69-34" title="34"><span class="op">}</span></a>
<a class="sourceLine" id="cb69-35" title="35"></a>
<a class="sourceLine" id="cb69-36" title="36"><span class="kw">function</span> <span class="at">swap</span>(array<span class="op">,</span> i<span class="op">,</span> j) <span class="op">{</span></a>
<a class="sourceLine" id="cb69-37" title="37">    [ array[i]<span class="op">,</span> array[j] ] <span class="op">=</span> [ array[j]<span class="op">,</span> array[i] ]<span class="op">;</span></a>
<a class="sourceLine" id="cb69-38" title="38"><span class="op">}</span></a></code></pre>
                    </div>
                    
                    
                    
                    
                    
                    <script async defer>
                        $( document ).ready( function () {
                            $( 'code, pre' ).append(
                                '<span class="command-copy"><i class="fa fa-clipboard" aria-hidden="true"></i></span>'
                            );

                            $( 'code span.command-copy' ).click( function ( e ) {
                                var text = $( this ).parent().text().trim(); //.text();
                                var copyHex = document.createElement( 'input' );
                                copyHex.value = text
                                document.body.appendChild( copyHex );
                                copyHex.select();
                                document.execCommand( 'copy' );
                                console.log( copyHex.value )
                                document.body.removeChild( copyHex );
                            } );


                            $( 'pre span.command-copy' ).click( function ( e ) {
                                var text = $( this ).parent().text().trim();
                                var copyHex = document.createElement( 'input' );
                                copyHex.value = text
                                document.body.appendChild( copyHex );
                                copyHex.select();
                                document.execCommand( 'copy' );
                                console.log( copyHex.value )
                                document.body.removeChild( copyHex );
                            } );
                        } )
                    </script>
                    <script async defer>
                        document.querySelectorAll( 'pre > code' ).forEach( function ( codeBlock ) {
                            var button = document.createElement( 'button' );
                            button.className = 'copy-code-button';
                            button.type = 'button';
                            button.innerText = 'Copy';

                            var pre = codeBlock.parentNode;
                            if ( pre.parentNode.classList.contains( 'highlight' ) ) {
                                var highlight = pre.parentNode;
                                highlight.parentNode.insertBefore( button, highlight );
                            } else {
                                pre.parentNode.insertBefore( button, pre );
                            }
                        } );
                        document.querySelector( 'button' ).addEventListener( 'click', () => {
                            const code = document.getElementByTagName( 'code' );
                            navigator.clipboard.writeText( code.innerHTML );
                        } );
                    </script>

</body>

</html>