{
  "nbformat": 4,
  "nbformat_minor": 0,
  "metadata": {
    "colab": {
      "provenance": []
    },
    "kernelspec": {
      "name": "python3",
      "display_name": "Python 3"
    },
    "language_info": {
      "name": "python"
    }
  },
  "cells": [
    {
      "cell_type": "markdown",
      "source": [
        "# Lecture 22 - Heaps\n",
        "In this lecture, we will discuss -\n",
        "\n",
        "1. Tree data structures\n",
        "2. Binary trees\n",
        "3. Heap - structure, set up\n",
        "4. Heap types - Max Heaps, Min Heaps\n",
        "4. Heap operations - extract min, change value, insert, delete\n",
        "5. Dijkstra's algorithm with heaps\n",
        "\n",
        "**Learning Objectives**\n",
        "\n",
        "1. Identifying trees\n",
        "2. Height of a binary tree\n",
        "3. Identifying binary tree types - Complete, Perfect, Full\n",
        "4. Identifying heaps\n",
        "5. Implementing operations on heaps - extract min/max, update value, insert\n",
        "6. Analyzing run times of heap operations\n",
        "\n",
        "Announcements -\n",
        "\n",
        "1. Homework 5 out TONIGHT\n",
        "2. Lab 9 on Dijkstras and shortest path this Friday\n"
      ],
      "metadata": {
        "id": "dPeKpOcDx2Qq"
      }
    },
    {
      "cell_type": "markdown",
      "source": [
        "# Discovery clicker\n",
        "\n",
        "Scan and use join code 277\n",
        "\n",
        "OR Visit clicker.cs.illinois.edu and use join code 277\n",
        "\n",
        "![Q1.png](data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAABAIAAAQCCAYAAAA2IFq1AAAAAXNSR0IArs4c6QAAIABJREFUeF7s29GOJr0RbFfp/R9aBnxn2HBjz2lyYlhLtxNdZO4IJqvy+/Xf//3vf//7j/8hgAACCCCAAAIIIIAAAggggMAnCPzXIOATPisSAQQQQAABBBBAAAEEEEAAgf+bgEGAICCAAAIIIIAAAggggAACCCDwIQIGAR8yW6kIIIAAAggggAACCCCAAAIIGATIAAIIIIAAAggggAACCCCAAAIfImAQ8CGzlYoAAggggAACCCCAAAIIIICAQYAMIIAAAggggAACCCCAAAIIIPAhAgYBHzJbqQgggAACCCCAAAIIIIAAAggYBMgAAggggAACCCCAAAIIIIAAAh8iYBDwIbOVigACCCCAAAIIIIAAAggggIBBgAwggAACCCCAAAIIIIAAAggg8CECBgEfMlupCCCAAAIIIIAAAggggAACCBgEyAACCCCAAAIIIIAAAggggAACHyJgEPAhs5WKAAIIIIAAAggggAACCCCAgEGADCCAAAIIIIAAAggggAACCCDwIQIGAR8yW6kIIIAAAggggAACCCCAAAIIGATIAAIIIIAAAggggAACCCCAAAIfImAQ8CGzlYoAAggggAACCCCAAAIIIICAQYAMIIAAAggggAACCCCAAAIIIPAhAgYBHzJbqQgggAACCCCAAAIIIIAAAggYBMgAAggggAACCCCAAAIIIIAAAh8iYBDwIbOVigACCCCAAAIIIIAAAggggIBBgAwggAACCCCAAAIIIIAAAggg8CECBgEfMlupCCCAAAIIIIAAAggggAACCBgEyAACCCCAAAIIIIAAAggggAACHyJgEPAhs5WKAAIIIIAAAggggAACCCCAgEGADCCAAAIIIIAAAggggAACCCDwIQIGAR8yW6kIIIAAAggggAACCCCAAAIIGATIAAIIIIAAAggggAACCCCAAAIfImAQ8CGzlYoAAggggAACCCCAAAIIIICAQYAMIIAAAggggAACCCCAAAIIIPAhAgYBHzJbqQgggAACCCCAAAIIIIAAAggYBMgAAggggAACCCCAAAIIIIAAAh8iYBDwIbOVigACCCCAAAIIIIAAAggggIBBgAwggAACCCCAAAIIIIAAAggg8CECBgEfMlupCCCAAAIIIIAAAggg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QgK+uLdmVH8QbatQXRWo7sdq7nltSebFaxPYqqv52lahmsAmYBCweakmQCAk4It7a0b1B9G2CtVVgep+rOae15ZkXrw2ga26mq9tFaoJbAIGAZuXagIEQgK+uLdmVH8QbatQXRWo7sdq7nltSebFaxPYqqv52lahmsAmYBCweakmQCAk4It7a0b1B9G2CtVVgep+rOae15ZkXrw2ga26mq9tFaoJbAIGAZuXagIEQgK+uLdmVH8QbatQXRWo7sdq7nltSebFaxPYqqv52lahmsAmYBCweakmQCAk4It7a0b1B9G2CtVVgep+rOae15ZkXrw2ga26mq9tFaoJbAIGAZuXagIEQgK+uLdmVH8QbatQXRWo7sdq7nltSebFaxPYqqv52lahmsAmYBCweakmQCAk4It7a0b1B9G2CtVVgep+rOae15ZkXrw2ga26mq9tFaoJbAIGAZuXagIEQgK+uLdmVH8QbatQXRWo7sdq7nltSebFaxPYqqv52lahmsAmYBCweakmQCAk4It7a0b1B9G2CtVVgep+rOae15ZkXrw2ga26mq9tFaoJbAIGAZuXagIEQgK+uLdmVH8QbatQXRWo7sdq7nltSeawbNNSAAAgAElEQVTFaxPYqqv52lahmsAmYBCweakmQCAk4It7a0b1B9G2CtVVgep+rOae15ZkXrw2ga26mq9tFaoJbAIGAZuXagIEQgK+uLdmVH8QbatQXRWo7sdq7nltSebFaxPYqqv52lahmsAmYBCweakmQCAk4It7a0b1B9G2CtVVgep+rOae15ZkXrw2ga26mq9tFaoJbAIGAZuXagIEQgK+uLdmVH8QbatQXRWo7sdq7nltSebFaxPYqqv52lahmsAmYBCweakmQCAk4It7a0b1B9G2CtVVgep+rOae15ZkXrw2ga26mq9tFaoJbAIGAZuXagIEQgK+uLdmVH8QbatQXRWo7sdq7nltSebFaxPYqqv52lahmsAmYBCweakmQCAk4It7a0b1B9G2CtVVgep+rOae15ZkXrw2ga26mq9tFaoJbAIGAZuXagIEQgK+uLdmVH8QbatQXRWo7sdq7nltSebFaxPYqqv52lahmsAmYBCweakmQCAk4It7a0b1B9G2CtVVgep+rOae15ZkXrw2ga26mq9tFaoJbAIGAZuXagIEQgK+uLdmVH8QbatQXRWo7sdq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sepVzVe1j1Wvar70cesMr81LNYGTAtX9eHLNnzzbIGDUE7ARTPkTAtWLdHU/Vr2qYaz2sepVzVe1j1Wvar70cesMr81LNYGTAtX9eHLNnzzbIGDUE7ARTPkTAtWLdHU/Vr2qYaz2sepVzVe1j1Wvar70cesMr81LNYGTAtX9eHLNnzzbIGDUE7ARTPkTAtWLdHU/Vr2qYaz2sepVzVe1j1Wvar70cesMr81LNYGTAtX9eHLNnzzbIGDUE7ARTPkTAtWLdHU/Vr2qYaz2sepVzVe1j1Wvar70cesMr81LNYGTAtX9eHLNnzzbIGDUE7ARTPkTAtWLdHU/Vr2qYaz2sepVzVe1j1Wvar70cesMr81LNYGTAtX9eHLNnzzbIGDUE7ARTPkTAtWLdHU/Vr2qYaz2sepVzVe1j1Wvar70cesMr81LNYGTAtX9eHLNnzzbIGDUE7ARTPkTAtWLdHU/Vr2qYaz2sepVzVe1j1Wvar70cesMr81LNYGTAtX9eHLNnzzbIGDUE7ARTPkTAtWLdHU/Vr2qYaz2sepVzVe1j1Wvar70cesMr81LNYGTAtX9eHLNnzzbIGDUE7ARTPkTAtWLdHU/Vr2qYaz2sepVzVe1j1Wvar70cesMr81LNYGTAtX9eHLNnzzbIGDUE7ARTPkTAtWLdHU/Vr2qYaz2sepVzVe1j1Wvar70cesMr81LNYGTAtX9eHLNnzzbIGDUE7ARTPkTAtWLdHU/Vr2qYaz2sepVzVe1j1Wvar70cesMr81LNYGTAtX9eHLNnzzbIGDUE7ARTPkTAtWLdHU/Vr2qYaz2sepVzVe1j1Wvar70cesMr81LNYGTAtX9eHLNnzzbIGDUE7ARTPkTAtWLdHU/Vr2qYaz2sepVzVe1j1Wvar70cesMr81LNYGTAtX9eHLNnzzbIGDUE7ARTPkTAtWLdHU/Vr2qYaz2sepVzVe1j1Wvar70cesMr81LNYGTAtX9eHLNnzzbIGDUE7ARTPkTAtWLdHU/Vr2qYaz2sepVzVe1j1Wvar70cesMr81LNYGTAtX9eHLNnzzbIGDUE7ARTPkTAtWLdHU/Vr2qYaz2sepVzVe1j1Wvar70cesMr81LNYGTAtX9eHLNnzzbIGDUE7ARTPkTAtWLdHU/Vr2qYaz2sepVzVe1j1Wvar70cesMr81LNYGTAtX9eHLNnzzbIGDU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)"
      ],
      "metadata": {
        "id": "QJu-_4Oryjj2"
      }
    },
    {
      "cell_type": "markdown",
      "source": [
        "# Dijkstra's Algorithm (Greedy Approach )\n",
        "\n",
        "**Main Idea**\n",
        "\n",
        "To find shortest paths in weighted graphs, where all the weights are positive, graphs can be explored in a lowest cost vertex first manner.\n",
        "\n",
        "This is a **Greedy** approach for this reason.\n",
        "\n",
        "Visualization - https://visualgo.net/en/sssp"
      ],
      "metadata": {
        "id": "8JAGT8cxEFha"
      }
    },
    {
      "cell_type": "markdown",
      "source": [
        "# Dijkstra's algorithm - requirements\n",
        "\n",
        "1. In order to store the final distance of each vertex from $s$, we need a distance list.\n",
        "\n",
        "2. In order to be able to trace paths, we need to maintain a parent list.\n",
        "\n",
        "3. When a vertex has to be picked to be explored, we need to have the distance values of all vertices to pick the cheapest one. (We can use the distance list for this but that is not the most efficient way)\n"
      ],
      "metadata": {
        "id": "Tx0lUrNp5vpC"
      }
    },
    {
      "cell_type": "markdown",
      "source": [
        "# Dijkstra's - Implementation details\n",
        "\n",
        "\n",
        "\n",
        "**Initialization**\n",
        "\n",
        " All vertices have distances set to infinity and parent set to None since we haven't explored the graph yet.\n",
        "\n",
        " The start vertex must be the one from which we want to establish shortest paths. Set its distance to 0 and update the **priority queue**.\n",
        "\n",
        " ---\n",
        "\n",
        "**Exploring edges**\n",
        "\n",
        "Consider a vertex u that is currently being explored and an edge (u,v) of weight w.\n",
        "\n",
        "Processing this edge should check if the current path to go from s -----> u -> v is shorter than the previous shortest path to go from s to v.\n",
        "\n",
        "If the new path is shorter, we must update the shortest path to be\n",
        "s -----> u -> v. This means we must - 1) set parent[v] to u, 2) update dist[v] to be dist[u] + w since the cost of the new path s -----> u -> v is dist[u] + w.\n",
        "\n",
        "If the old path was shorter, we should not change the shortest path from s to v.\n",
        "\n",
        "We must do this for all outgoing edges of u.\n",
        "\n",
        "---\n",
        "\n",
        "**Picking Next vertex**\n",
        "\n",
        "Since we want to pick the cheapest vertex among all remaining, our queue must support this functionality. We use **Priority Queues** for this.\n",
        "\n",
        "What must the priority queue do? Since we want to explore vertices in increasing order of their costs, the priority queue must support returning the cheapest vertex.\n",
        "\n",
        "In order to do this, we must update the queue every time a vertex undergoes a change in dist value. The function `update_vertex` does just this - it updates the position of vertex `v` when its `dist` value is updated.\n"
      ],
      "metadata": {
        "id": "r8MsF_qFEdpH"
      }
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "outputId": "17455938-1e55-4a17-fb39-b3170531ce6c",
        "id": "Ha-oYxbD5ZaQ"
      },
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "[0, 50, 90, 150, 105]\n"
          ]
        }
      ],
      "source": [
        "# Implementation of Dijkstra's greedy algorithm for shortest paths\n",
        "\n",
        "def Dijkstras(G, s):\n",
        "    n = len(G)\n",
        "\n",
        "    # initializing dist values to infinity and parent values to none\n",
        "    dist = [float('inf')] * len(G)\n",
        "    parent = [None] * len(G)\n",
        "\n",
        "    # priority queue that maintains vertices with priority for lower distance\n",
        "    priority_queue = []\n",
        "    for i in range(len(G)):       #initially all have dist inf - order immaterial\n",
        "        priority_queue.append(i)\n",
        "\n",
        "    # setting s as the start vertex and updating priority queue\n",
        "    dist[s] = 0\n",
        "    priority_queue = update_vertex(priority_queue, s, dist)\n",
        "\n",
        "    while priority_queue != []:\n",
        "      #pick the cheapest vertex\n",
        "        u = priority_queue.pop(0)\n",
        "\n",
        "        for (v, weight) in G[u]:             #processing edge (u,v)\n",
        "            if dist[v] > dist[u] + weight:   #if new s-v path is cheaper, update\n",
        "                parent[v] = u\n",
        "                dist[v] = dist[u] + weight\n",
        "                priority_queue = update_vertex(priority_queue, v, dist) #update priority queue with updated value for v\n",
        "\n",
        "    return dist\n",
        "\n",
        "\n",
        "# updating the position of v in the priority queue based on new distance value\n",
        "def update_vertex(pq, v, dist):\n",
        "    for i in range(len(pq)):\n",
        "        if pq[i] == v:        #identify position of v\n",
        "            while i > 0 and dist[pq[i - 1]] > dist[v]:  #insert v into right position after update\n",
        "                pq[i] = pq[i - 1]\n",
        "                pq[i - 1] = v\n",
        "                i -= 1\n",
        "            return pq\n",
        "\n",
        "\n",
        "print(Dijkstras([[(1, 50), (2, 90), (3, 150), (4, 161)],[(4, 55)],[(1, 375), (3, 140), (4, 140)],[(4, 60)],[]],0))"
      ]
    },
    {
      "cell_type": "markdown",
      "source": [
        "# Data Structures we have seen so far\n",
        "\n",
        "We have seen sorted and unsorted lists as structures for storing data.\n",
        "\n",
        "For BFS, we used queues to help identify the next vertex to be explored since we wanted vertices to be explored in the order of their discovery.\n",
        "\n",
        "For Dijsktra's algorithm, we used a priority queue that maintains vertices in a linear order based on their distance values since we wanted cheapest vertices to be explored first.\n",
        "\n"
      ],
      "metadata": {
        "id": "9xNKWIzy1gSS"
      }
    },
    {
      "cell_type": "markdown",
      "source": [
        "# Dijkstra's data strcuture requirements\n",
        "\n",
        "Dijkstra's algorithm required the following functions from the data structure -\n",
        "\n",
        "1. Finding Cheapest vertex - (Extract Minimum) - $n$ times\n",
        "\n",
        "2. Updating priority of a vertex - (Update-vertex) - $m$ times\n",
        "\n",
        "Our priority queue implementation required -\n",
        "\n",
        ">$O(n)$ time for extracting the minimum (since deleting the first element in a list requires all subsequent elements to be moved to the previous memory location)\n",
        "\n",
        ">$O(n)$ time for updating the priority of a vertex since that can involve moving the vertex to the start of the priority queue.\n",
        "\n",
        "Overall, this led to a run time of $O(n^2 + mn)$.\n",
        "\n",
        " We will study heaps today since they bring singificant savings with them."
      ],
      "metadata": {
        "id": "pvrTgGsE7bZQ"
      }
    },
    {
      "cell_type": "markdown",
      "source": [
        "# Data Strcuture types - Linear vs Trees\n",
        "\n",
        "All data structures we have seen so far organize elements in a linear manner - lists (unsorted and sorted), queues, priority queues.\n",
        "\n",
        "But, there are other ways of organizing data - which are not linear.\n",
        "\n",
        "A tree is a non-linear, hierarchical data structure consisting of nodes connected through edges. It organizes data using parent-child relationships, where each node can have zero or more child nodes.\n",
        "\n",
        "Tree data strcutures such as Heaps, Binary Search Trees, AVL Trees, B Trees etc. provide alternative ways of organizing data.\n",
        "\n",
        "https://www.geeksforgeeks.org/dsa/data-structure-meaning/"
      ],
      "metadata": {
        "id": "TUofTlzn7z9I"
      }
    },
    {
      "cell_type": "markdown",
      "source": [
        "# Trees : Binary Trees\n",
        "\n",
        "A tree is an acylic, connected undirected graph. Trees on $n$ vertices will ALWAYS have exactly $n-1$ edges.\n",
        "\n",
        "\n",
        "https://www.geeksforgeeks.org/dsa/introduction-to-tree-data-structure/\n",
        "\n",
        "\n",
        "\n",
        "Tree terminology -\n",
        "\n",
        "* Parent node - node with at least one child  (predecessor/ internal nodes)\n",
        "\n",
        "* Child node - every non-root node is a child node (successor)\n",
        "\n",
        "* Leaf node - node with no children (external nodes)\n",
        "\n",
        "* Root node - node with no parents (\"head\")\n",
        "\n",
        "* Ancestor - Any node on the path from the root to a given node (other than itself)\n",
        "\n",
        "* Descendant - A node is a descendant of each of its ancestors\n",
        "\n",
        "* Sibling - nodes that share the same parent\n",
        "\n",
        "* Subtree - A node and all its descendants form a subtree\n",
        "\n",
        "* Depth of a node - The distance of a node from the root\n",
        "\n",
        "* Height of a Tree - The maximum depth of any node in the Tree\n",
        "\n",
        "\n",
        "\n",
        ">Binary trees are trees with nodes having at most 2 children.\n",
        "\n",
        ">Children in binary tree are typically called left and right child."
      ],
      "metadata": {
        "id": "aAWwKtjD_6zg"
      }
    },
    {
      "cell_type": "markdown",
      "source": [
        "# Types of Binary Trees\n",
        "\n",
        "1. Complete Binary Tree - All levels except last filled, last level filled left to right\n",
        "\n",
        "2. Perfect Binary tree - All levels perfectly filled\n",
        "\n",
        "3. Full Binary Tree - All nodes have either 0 or 2 children (Don't care)\n",
        "\n"
      ],
      "metadata": {
        "id": "fAv3WsOICdJj"
      }
    },
    {
      "cell_type": "markdown",
      "source": [
        "# Complete Binary Tree  (think left to right)\n",
        "\n",
        "A complete binary tree is a binary tree with all levels perfectly filled except for the last level - which is filled from left to right.\n",
        "\n",
        "The strutural rigidity of a complete binary tree ensures predictable tree structure - making it clear which nodes have which parents and which nodes are leaf nodes.\n",
        "\n",
        "We will exploit this predictability when working with heaps.\n",
        "\n",
        "* Height - The height $h$ of a complete binary tree on $n$ nodes is $\\log_{2}n$.\n",
        "\n",
        "At level 0, a complete binary tree has 1 node.\n",
        "\n",
        "At level 1, a complete binary tree has 2 nodes.\n",
        "\n",
        "At level 2, a complete binary tree has 4 nodes.\n",
        "\n",
        "At level $k$, a complete binary tree has $2^{k}$ nodes.\n",
        "\n",
        "For the total number of nodes to be $n$, we need $∑_{i=0}^{h} 2^{i} = n \\Rightarrow h ≃ \\log_{2}n$\n"
      ],
      "metadata": {
        "id": "4VSpdLX9FDO5"
      }
    },
    {
      "cell_type": "markdown",
      "source": [
        "# Perfect Binary Tree\n",
        "\n",
        "A perfect binary tree is a complete binary tree with the last level (also) fully filled.\n",
        "\n"
      ],
      "metadata": {
        "id": "7PvmyDXQFtPu"
      }
    },
    {
      "cell_type": "markdown",
      "source": [
        "# Heaps (and heap property)\n",
        "\n",
        "A heap is a tree data structure in which elements are stored in a **complete binary tree**.\n",
        "\n",
        "Heaps have the following constraint - **every (parent-child) pair must repsect the heap property**.\n",
        "\n",
        "The heap property for a **Min Heap** is that the` value at every parent must be smaller than the value at any of its children`. In other words, the parent has the smallest value among itself and all its children.\n",
        "\n",
        "(The other type of heap is a **Max Heap** whose heap property is that the `value at every parent must be larger than the value at any of its children`)\n",
        "\n",
        "Max Heap simulation - https://visualgo.net/en/heap?slide=1\n",
        "\n",
        "Min Heap simulation - https://crackr.dev/visualize/binary-heap"
      ],
      "metadata": {
        "id": "WO0qO8ZaC9br"
      }
    },
    {
      "cell_type": "markdown",
      "source": [
        "# Heap - fixed structure\n",
        "\n",
        "A heap on $n$ elements always has the same structure. The values at nodes may differ, but the structure is fixed due to the complete binary tree property.\n",
        "\n",
        "A heap on $n$ elements has exactly $\\frac{n}{2}$ leaf nodes and $\\frac{n}{2}$ parent nodes.\n",
        "\n",
        "(If $n$ is odd, there is one more leaf node than parent nodes)\n",
        "\n",
        "* The root vertex is at position 0. It can have up to two children - the left child at position 1 and the right child at position 2.\n",
        "\n",
        "**Node at position $i$ in a heap**\n",
        "\n",
        "* Children - The node at position $i$ in a heap can have two children - the left child $(2i+1)$ and the right child $(2i+2)$.\n",
        "\n",
        "* Parent - The parent of the node at position $i$ is always the one at position $⌊\\frac{i-1}{2}\\rfloor$.\n",
        "\n",
        ">Due to the fixed structure of heaps, we can simulate heap operations using lists.\n",
        "\n",
        "> The height of a heap on $n$ elements is $\\sim \\log_{2}n$"
      ],
      "metadata": {
        "id": "QR-74Mn0IApP"
      }
    },
    {
      "cell_type": "markdown",
      "source": [
        "# Heap Operations\n",
        "\n",
        "Heaps are designed to support specific operations efficiently. A Min Heap is designed to support identifying the minimum value from data, and operations such as inserting an element and updating a value in the heap.\n",
        "\n",
        "1. Insert($x$) - Insert element with value $x$ in the heap and fix the heap\n",
        "\n",
        "2. Delete Min - extract the minimum value and fix the heap after deleting it\n",
        "\n",
        "3. Update($i,k$) - Update the value at position $i$ to $k$ - and fix the heap"
      ],
      "metadata": {
        "id": "SHgc9AWxLWM4"
      }
    },
    {
      "cell_type": "markdown",
      "source": [
        "# Heaps - Insert($x$)\n",
        "\n",
        "To insert value $x$ in heap $H$, we first observe that the new node should be added in a fixed position - that is $(n+1)$-th position on the heap.\n",
        "\n",
        "We can insert a node with value $x$ to position $n+1$. But this insertion can violate the heap property!\n",
        "\n",
        "So, we need to fix the heap to ensure heap property is not violated. Do we need to fix the entire heap? Not quite, since the only possible violations can occur on the path from root to position $(n+1)$.\n",
        "\n",
        "First, compare $x$ with its parent -\n",
        "\n",
        "Case 1 : $x$ is larger than its parent - Heap is perfectly alright - nothing else needs to be done.\n",
        "\n",
        "Case 2 : $x$ is smaller than its parent - in this case, swap $x$ with its parent to fix the issue at this level and then check $x$ against its new parent.\n",
        "\n",
        "Repeat this step until $x$ is larger than its parent or $x$ has reached the root posiiton.\n",
        "\n",
        ">This process is called Bubble up - and it restores the Heap property.\n",
        "\n",
        ">Since comparison at each level takes $O(1)$ time, and there are at most $\\log_{2}n$ levels, the total time complexity of insert is $O(\\log_{2}n)$."
      ],
      "metadata": {
        "id": "I-ZFKn6aNhW3"
      }
    },
    {
      "cell_type": "markdown",
      "source": [
        "# Heaps - Deletemin\n",
        "\n",
        "The minimum value in a Min-Heap is very easy to find - it is simply the value at the root node.\n",
        "\n",
        "However, to delete the node with the minimum value, we need to ensure that the heap structure and heap property are both maintained.\n",
        "\n",
        "Since deleting one element beings the size of the heap down to $(n-1)$ nodes, the final structure must lose the element in position $n$. So, we first swap the root value with the value at position $n$ and then delete the node at position $n$ (now containing the minimum value). The heap now has exactly $(n-1)$ elements. Are we done? Not quite since we need to maintain heap property.\n",
        "\n",
        "Since the value at the root is now different, it can potentially violate the heap property. We need to fix this.\n",
        "\n",
        "In order to fix this, we must identify the smaller value among both its children and swap them with the value at the root. This ensures that the minimum value is stored at the root and respects heap property at the root level.\n",
        "\n",
        "We need to then repeat this process of identifying smaller of both children and swapping until both children are larger than this value or we have reached a leaf node.\n",
        "\n",
        ">Delete min steps -\n",
        "\n",
        "1. Swap min value at root with value at position $n$\n",
        "2. Delete node at position $n$\n",
        "3. Let the value at root `sift down ` to its appropriate position respecting heap property.\n",
        "\n",
        ">Time Complexity -\n",
        "\n",
        "1. Swap - $O(1)$ time since we know we need to swap $H[0]$ with $H[n]$\n",
        "2. Delete node at position $n$ - $O(1)$ time\n",
        "3. Sift Down - At each level we need 2 comparisons - (value vs left child) and (value vs right child) followed by swapping in case value is larger than some child. Since we know the locations of left child and right child, these operations take $O(1)$ time. Since there are $\\log_{2}n$ levels, the total time is at most $O(1) * \\log_{2}n = O(\\log_{2}n)$.\n",
        "\n",
        "> Overall, delete min can be implemented in $O(\\log_{2}(n))$ time."
      ],
      "metadata": {
        "id": "lo73KaQKQARE"
      }
    },
    {
      "cell_type": "markdown",
      "source": [
        "# Heaps - Update($i,k$)\n",
        "\n",
        "To update the value of position $i$ to $k$, we note that we just need to set $H[i] = k$. That updates the value. However, this can violate heap property - so we need to fix the heap!\n",
        "\n",
        "For a Min Heap, typically the update will result in lowering the value of the node (eg - Dijkstra's distance updates). In such cases, it may happen that the new value at position $i$ is lower than its parent. To fix this, we use the `bubble up` process as described in the insert operation.\n",
        "\n",
        "An update may also reesult in increasing the value of the node. In such cases, the potential violation invovles one of its children having a lower value than it. To fix this, we can use the `sift down` process described in delete min operation.\n",
        "\n",
        "An update may result either in `bubble up` or `sift down` - exactly one of them depending on the nature of the update. Since both operations require $O(\\log_{2}n)$ time, the time complexity of Update($i,k$) is $O(\\log_{2}n)$."
      ],
      "metadata": {
        "id": "jiNG2NW0TK5y"
      }
    },
    {
      "cell_type": "markdown",
      "source": [
        "# Aside - Building a Heap of $n$ elements\n",
        "\n",
        "\n",
        "Since inserting an element takes $O(\\log_{2}n)$ time and the heap has $n$ elements in total, inserting elements one after another and building the heap can be done in $O(n\\log_{2}n)$ time.\n",
        "\n",
        "There is a similar procedure that lazily inserts all elements and then fixes the heap property by sifting down from position $n/2$ through position $0$ - which only requires $O(n)$ time.  "
      ],
      "metadata": {
        "id": "ZI6F6LfOZGIr"
      }
    },
    {
      "cell_type": "markdown",
      "source": [
        "# Dijkstra's with Heaps\n",
        "\n",
        "We have seen that the time taken by the Dijkstra's algorithm depends heavily on the update_vertex operation.\n",
        "\n",
        "In particular, note that the running time of Dijkstra's depends on -\n",
        "\n",
        "1. $n$ calls to find cheapest vertex to explore\n",
        "2. $m$ calls to update priority of vertices $v$\n",
        "\n",
        "If we use a heap to store all distance values and function as a priority queue, then deletemin takes $O(\\log_{2}n)$ time and updating a distance value also takse $O(\\log_{2}n)$ time.\n",
        "\n",
        ">The total run time of Dijsktra's with heaps as the priority queue data structure is $n * O(\\log_{2}n) + m * O(\\log_{2}n) = O(n \\log_{2}n + m \\log_{2}n)$\n"
      ],
      "metadata": {
        "id": "JgR1FFplDjYT"
      }
    },
    {
      "cell_type": "markdown",
      "source": [
        "# Heaps - Pros and Cons\n",
        "\n",
        "Heaps are good for inserting a new value, finding the min/max value, deleting the min/max value, updating a value.\n",
        "\n",
        "Heaps are bad for searching for a value - because unlike sorted lists where we can use binary search, to search through heaps we need $O(n)$ time.\n",
        "\n",
        ">Min value is efficient to find in Min heaps but NOT in Max heaps.\n",
        "\n",
        ">Heaps are not efficient to support search queries."
      ],
      "metadata": {
        "id": "ofj-4Pp4X6No"
      }
    },
    {
      "cell_type": "markdown",
      "source": [
        "# Heaps - Python resources\n",
        "\n",
        "Documentation for heap implementation in Python -\n",
        "\n",
        "https://docs.python.org/3/library/heapq.html"
      ],
      "metadata": {
        "id": "utoIiMPCXH-B"
      }
    }
  ]
}