{
  "id": "trees/heap",
  "version": 1,
  "deterministic": true,
  "url": "/dsa/trees/heap",
  "topic": {
    "slug": "trees",
    "title": "Trees"
  },
  "title": "Heap & Priority Queue",
  "tagline": "A tree that always keeps the biggest thing on top, ready to grab.",
  "vizKind": "tree",
  "complexity": {
    "time": {
      "best": "O(1)",
      "average": "O(log n)",
      "worst": "O(log n)"
    },
    "space": "O(n)",
    "growth": "log",
    "note": "Inserting sifts up one path from leaf to root — O(log n). Peeking at the maximum is O(1), because it's always the root. Removing the max is O(log n) too. That log-n cost for always knowing the top is what makes a heap the go-to priority queue."
  },
  "code": {
    "javascript": "function insert(heap, value) {\n  heap.push(value);\n  let i = heap.length - 1;\n  while (i > 0) {\n    const parent = (i - 1) >> 1;\n    if (heap[parent] >= heap[i]) break;\n    swap(heap, i, parent);\n    i = parent;\n  }\n}",
    "python": "def insert(heap, value):\n    heap.append(value)\n    i = len(heap) - 1\n    while i > 0:\n        parent = (i - 1) // 2\n        if heap[parent] >= heap[i]: break\n        heap[i], heap[parent] = heap[parent], heap[i]\n        i = parent\n",
    "java": "void insert(List<Integer> heap, int value) {\n  heap.add(value);\n  int i = heap.size() - 1;\n  while (i > 0) {\n    int parent = (i - 1) / 2;\n    if (heap.get(parent) >= heap.get(i)) break;\n    Collections.swap(heap, i, parent);\n    i = parent;\n  }\n}",
    "cpp": "void insert(vector<int>& heap, int value) {\n  heap.push_back(value);\n  int i = heap.size() - 1;\n  while (i > 0) {\n    int parent = (i - 1) / 2;\n    if (heap[parent] >= heap[i]) break;\n    swap(heap[i], heap[parent]);\n    i = parent;\n  }\n}"
  },
  "defaultInput": [
    15,
    20,
    8,
    25,
    10,
    30,
    5
  ],
  "defaultTarget": null,
  "inputHint": "Each value is added at the bottom, then climbs to its rightful level.",
  "pitfalls": [
    {
      "wrong": "Expecting a heap to be fully sorted.",
      "right": "It isn't. A heap only guarantees the max (or min) is on top. The rest is loosely ordered — enough to find the top fast, but not a sorted list."
    },
    {
      "wrong": "Confusing a heap with a binary search tree.",
      "right": "A BST orders left-vs-right by value so you can search. A heap orders parent-vs-child so the extreme is on top. You can't binary-search a heap."
    },
    {
      "wrong": "Sifting the new value down instead of up.",
      "right": "A freshly inserted value goes in at the bottom and climbs up toward the root. Sifting down is for removal, when you drop the last value into the empty top."
    }
  ],
  "quiz": [
    {
      "q": "In a max-heap, where is the largest value always found?",
      "options": [
        "A leaf at the bottom",
        "The root, at the top",
        "The leftmost node",
        "It varies"
      ],
      "answer": 1,
      "why": "Every parent is bigger than its children, so following 'bigger' upward always leads to the root. The maximum is always on top — that's the entire point."
    },
    {
      "q": "You insert a new value into a heap. What happens?",
      "options": [
        "It's placed at the root",
        "It goes in at the bottom and sifts up while it's bigger than its parent",
        "The whole heap is re-sorted",
        "It replaces the smallest value"
      ],
      "answer": 1,
      "why": "The new value enters at the next open bottom spot and climbs, swapping with its parent as long as it's larger, until the heap rule holds again. That's O(log n)."
    },
    {
      "q": "What is a heap most commonly used to build?",
      "options": [
        "A sorted list",
        "A priority queue",
        "A hash table",
        "A search tree"
      ],
      "answer": 1,
      "why": "Because the top item is always the most extreme, a heap is the natural priority queue — always serving the highest-priority item next, in O(log n) per operation."
    }
  ],
  "problems": [
    {
      "name": "Last Stone Weight",
      "difficulty": "Easy",
      "url": "https://leetcode.com/problems/last-stone-weight/"
    },
    {
      "name": "Kth Largest Element in an Array",
      "difficulty": "Medium",
      "url": "https://leetcode.com/problems/kth-largest-element-in-an-array/"
    },
    {
      "name": "Top K Frequent Elements",
      "difficulty": "Medium",
      "url": "https://leetcode.com/problems/top-k-frequent-elements/"
    }
  ],
  "trace": {
    "note": "Each frame is one immutable step: data snapshot, pointers, per-index roles, executing code line, and a one-sentence explanation.",
    "length": 22,
    "frames": [
      {
        "data": {
          "nodes": [],
          "rootId": null
        },
        "pointers": [],
        "highlights": [],
        "codeLine": 1,
        "variables": {},
        "explanation": "A heap is a binary tree with one rule: every parent is bigger than its children (a max-heap). That means the biggest value is always sitting right at the top, ready to grab.",
        "stats": {
          "comparisons": 0,
          "swaps": 0
        }
      },
      {
        "data": {
          "nodes": [
            {
              "id": "h0-15",
              "value": 15,
              "left": null,
              "right": null,
              "role": "active"
            }
          ],
          "rootId": "h0-15"
        },
        "pointers": [],
        "highlights": [],
        "codeLine": 2,
        "variables": {
          "inserting": 15,
          "size": 1
        },
        "explanation": "Add 15 at the next open spot — the bottom of the tree. It probably breaks the heap rule, so now it has to climb.",
        "stats": {
          "comparisons": 0,
          "swaps": 0
        },
        "accent": "active"
      },
      {
        "data": {
          "nodes": [
            {
              "id": "h0-15",
              "value": 15,
              "left": "h1-20",
              "right": null
            },
            {
              "id": "h1-20",
              "value": 20,
              "left": null,
              "right": null,
              "role": "active"
            }
          ],
          "rootId": "h0-15"
        },
        "pointers": [],
        "highlights": [],
        "codeLine": 2,
        "variables": {
          "inserting": 20,
          "size": 2
        },
        "explanation": "Add 20 at the next open spot — the bottom of the tree. It probably breaks the heap rule, so now it has to climb.",
        "stats": {
          "comparisons": 0,
          "swaps": 0
        },
        "accent": "active"
      },
      {
        "data": {
          "nodes": [
            {
              "id": "h0-15",
              "value": 15,
              "left": "h1-20",
              "right": null,
              "role": "compare"
            },
            {
              "id": "h1-20",
              "value": 20,
              "left": null,
              "right": null,
              "role": "active"
            }
          ],
          "rootId": "h0-15"
        },
        "pointers": [],
        "highlights": [],
        "codeLine": 6,
        "variables": {
          "child": 20,
          "parent": 15
        },
        "explanation": "20 is bigger than its parent 15. In a max-heap the parent must be bigger, so they swap.",
        "stats": {
          "comparisons": 1,
          "swaps": 0
        },
        "accent": "compare"
      },
      {
        "data": {
          "nodes": [
            {
              "id": "h1-20",
              "value": 20,
              "left": "h0-15",
              "right": null,
              "role": "active"
            },
            {
              "id": "h0-15",
              "value": 15,
              "left": null,
              "right": null
            }
          ],
          "rootId": "h1-20"
        },
        "pointers": [],
        "highlights": [],
        "codeLine": 7,
        "variables": {
          "swaps": 1
        },
        "explanation": "20 climbs one level up.",
        "stats": {
          "comparisons": 1,
          "swaps": 1
        },
        "accent": "swap"
      },
      {
        "data": {
          "nodes": [
            {
              "id": "h1-20",
              "value": 20,
              "left": "h0-15",
              "right": "h2-8"
            },
            {
              "id": "h0-15",
              "value": 15,
              "left": null,
              "right": null
            },
            {
              "id": "h2-8",
              "value": 8,
              "left": null,
              "right": null,
              "role": "active"
            }
          ],
          "rootId": "h1-20"
        },
        "pointers": [],
        "highlights": [],
        "codeLine": 2,
        "variables": {
          "inserting": 8,
          "size": 3
        },
        "explanation": "Add 8 at the next open spot — the bottom of the tree. It probably breaks the heap rule, so now it has to climb.",
        "stats": {
          "comparisons": 1,
          "swaps": 1
        },
        "accent": "active"
      },
      {
        "data": {
          "nodes": [
            {
              "id": "h1-20",
              "value": 20,
              "left": "h0-15",
              "right": "h2-8",
              "role": "compare"
            },
            {
              "id": "h0-15",
              "value": 15,
              "left": null,
              "right": null
            },
            {
              "id": "h2-8",
              "value": 8,
              "left": null,
              "right": null,
              "role": "active"
            }
          ],
          "rootId": "h1-20"
        },
        "pointers": [],
        "highlights": [],
        "codeLine": 6,
        "variables": {
          "child": 8,
          "parent": 20
        },
        "explanation": "8 is not bigger than its parent 20. The heap rule holds — 8 stops climbing.",
        "stats": {
          "comparisons": 2,
          "swaps": 1
        },
        "accent": "compare"
      },
      {
        "data": {
          "nodes": [
            {
              "id": "h1-20",
              "value": 20,
              "left": "h0-15",
              "right": "h2-8"
            },
            {
              "id": "h0-15",
              "value": 15,
              "left": "h3-25",
              "right": null
            },
            {
              "id": "h2-8",
              "value": 8,
              "left": null,
              "right": null
            },
            {
              "id": "h3-25",
              "value": 25,
              "left": null,
              "right": null,
              "role": "active"
            }
          ],
          "rootId": "h1-20"
        },
        "pointers": [],
        "highlights": [],
        "codeLine": 2,
        "variables": {
          "inserting": 25,
          "size": 4
        },
        "explanation": "Add 25 at the next open spot — the bottom of the tree. It probably breaks the heap rule, so now it has to climb.",
        "stats": {
          "comparisons": 2,
          "swaps": 1
        },
        "accent": "active"
      },
      {
        "data": {
          "nodes": [
            {
              "id": "h1-20",
              "value": 20,
              "left": "h0-15",
              "right": "h2-8"
            },
            {
              "id": "h0-15",
              "value": 15,
              "left": "h3-25",
              "right": null,
              "role": "compare"
            },
            {
              "id": "h2-8",
              "value": 8,
              "left": null,
              "right": null
            },
            {
              "id": "h3-25",
              "value": 25,
              "left": null,
              "right": null,
              "role": "active"
            }
          ],
          "rootId": "h1-20"
        },
        "pointers": [],
        "highlights": [],
        "codeLine": 6,
        "variables": {
          "child": 25,
          "parent": 15
        },
        "explanation": "25 is bigger than its parent 15. In a max-heap the parent must be bigger, so they swap.",
        "stats": {
          "comparisons": 3,
          "swaps": 1
        },
        "accent": "compare"
      },
      {
        "data": {
          "nodes": [
            {
              "id": "h1-20",
              "value": 20,
              "left": "h3-25",
              "right": "h2-8"
            },
            {
              "id": "h3-25",
              "value": 25,
              "left": "h0-15",
              "right": null,
              "role": "active"
            },
            {
              "id": "h2-8",
              "value": 8,
              "left": null,
              "right": null
            },
            {
              "id": "h0-15",
              "value": 15,
              "left": null,
              "right": null
            }
          ],
          "rootId": "h1-20"
        },
        "pointers": [],
        "highlights": [],
        "codeLine": 7,
        "variables": {
          "swaps": 2
        },
        "explanation": "25 climbs one level up.",
        "stats": {
          "comparisons": 3,
          "swaps": 2
        },
        "accent": "swap"
      },
      {
        "data": {
          "nodes": [
            {
              "id": "h1-20",
              "value": 20,
              "left": "h3-25",
              "right": "h2-8",
              "role": "compare"
            },
            {
              "id": "h3-25",
              "value": 25,
              "left": "h0-15",
              "right": null,
              "role": "active"
            },
            {
              "id": "h2-8",
              "value": 8,
              "left": null,
              "right": null
            },
            {
              "id": "h0-15",
              "value": 15,
              "left": null,
              "right": null
            }
          ],
          "rootId": "h1-20"
        },
        "pointers": [],
        "highlights": [],
        "codeLine": 6,
        "variables": {
          "child": 25,
          "parent": 20
        },
        "explanation": "25 is bigger than its parent 20. In a max-heap the parent must be bigger, so they swap.",
        "stats": {
          "comparisons": 4,
          "swaps": 2
        },
        "accent": "compare"
      },
      {
        "data": {
          "nodes": [
            {
              "id": "h3-25",
              "value": 25,
              "left": "h1-20",
              "right": "h2-8",
              "role": "active"
            },
            {
              "id": "h1-20",
              "value": 20,
              "left": "h0-15",
              "right": null
            },
            {
              "id": "h2-8",
              "value": 8,
              "left": null,
              "right": null
            },
            {
              "id": "h0-15",
              "value": 15,
              "left": null,
              "right": null
            }
          ],
          "rootId": "h3-25"
        },
        "pointers": [],
        "highlights": [],
        "codeLine": 7,
        "variables": {
          "swaps": 3
        },
        "explanation": "25 climbs one level up.",
        "stats": {
          "comparisons": 4,
          "swaps": 3
        },
        "accent": "swap"
      },
      {
        "data": {
          "nodes": [
            {
              "id": "h3-25",
              "value": 25,
              "left": "h1-20",
              "right": "h2-8"
            },
            {
              "id": "h1-20",
              "value": 20,
              "left": "h0-15",
              "right": "h4-10"
            },
            {
              "id": "h2-8",
              "value": 8,
              "left": null,
              "right": null
            },
            {
              "id": "h0-15",
              "value": 15,
              "left": null,
              "right": null
            },
            {
              "id": "h4-10",
              "value": 10,
              "left": null,
              "right": null,
              "role": "active"
            }
          ],
          "rootId": "h3-25"
        },
        "pointers": [],
        "highlights": [],
        "codeLine": 2,
        "variables": {
          "inserting": 10,
          "size": 5
        },
        "explanation": "Add 10 at the next open spot — the bottom of the tree. It probably breaks the heap rule, so now it has to climb.",
        "stats": {
          "comparisons": 4,
          "swaps": 3
        },
        "accent": "active"
      },
      {
        "data": {
          "nodes": [
            {
              "id": "h3-25",
              "value": 25,
              "left": "h1-20",
              "right": "h2-8"
            },
            {
              "id": "h1-20",
              "value": 20,
              "left": "h0-15",
              "right": "h4-10",
              "role": "compare"
            },
            {
              "id": "h2-8",
              "value": 8,
              "left": null,
              "right": null
            },
            {
              "id": "h0-15",
              "value": 15,
              "left": null,
              "right": null
            },
            {
              "id": "h4-10",
              "value": 10,
              "left": null,
              "right": null,
              "role": "active"
            }
          ],
          "rootId": "h3-25"
        },
        "pointers": [],
        "highlights": [],
        "codeLine": 6,
        "variables": {
          "child": 10,
          "parent": 20
        },
        "explanation": "10 is not bigger than its parent 20. The heap rule holds — 10 stops climbing.",
        "stats": {
          "comparisons": 5,
          "swaps": 3
        },
        "accent": "compare"
      },
      {
        "data": {
          "nodes": [
            {
              "id": "h3-25",
              "value": 25,
              "left": "h1-20",
              "right": "h2-8"
            },
            {
              "id": "h1-20",
              "value": 20,
              "left": "h0-15",
              "right": "h4-10"
            },
            {
              "id": "h2-8",
              "value": 8,
              "left": "h5-30",
              "right": null
            },
            {
              "id": "h0-15",
              "value": 15,
              "left": null,
              "right": null
            },
            {
              "id": "h4-10",
              "value": 10,
              "left": null,
              "right": null
            },
            {
              "id": "h5-30",
              "value": 30,
              "left": null,
              "right": null,
              "role": "active"
            }
          ],
          "rootId": "h3-25"
        },
        "pointers": [],
        "highlights": [],
        "codeLine": 2,
        "variables": {
          "inserting": 30,
          "size": 6
        },
        "explanation": "Add 30 at the next open spot — the bottom of the tree. It probably breaks the heap rule, so now it has to climb.",
        "stats": {
          "comparisons": 5,
          "swaps": 3
        },
        "accent": "active"
      },
      {
        "data": {
          "nodes": [
            {
              "id": "h3-25",
              "value": 25,
              "left": "h1-20",
              "right": "h2-8"
            },
            {
              "id": "h1-20",
              "value": 20,
              "left": "h0-15",
              "right": "h4-10"
            },
            {
              "id": "h2-8",
              "value": 8,
              "left": "h5-30",
              "right": null,
              "role": "compare"
            },
            {
              "id": "h0-15",
              "value": 15,
              "left": null,
              "right": null
            },
            {
              "id": "h4-10",
              "value": 10,
              "left": null,
              "right": null
            },
            {
              "id": "h5-30",
              "value": 30,
              "left": null,
              "right": null,
              "role": "active"
            }
          ],
          "rootId": "h3-25"
        },
        "pointers": [],
        "highlights": [],
        "codeLine": 6,
        "variables": {
          "child": 30,
          "parent": 8
        },
        "explanation": "30 is bigger than its parent 8. In a max-heap the parent must be bigger, so they swap.",
        "stats": {
          "comparisons": 6,
          "swaps": 3
        },
        "accent": "compare"
      },
      {
        "data": {
          "nodes": [
            {
              "id": "h3-25",
              "value": 25,
              "left": "h1-20",
              "right": "h5-30"
            },
            {
              "id": "h1-20",
              "value": 20,
              "left": "h0-15",
              "right": "h4-10"
            },
            {
              "id": "h5-30",
              "value": 30,
              "left": "h2-8",
              "right": null,
              "role": "active"
            },
            {
              "id": "h0-15",
              "value": 15,
              "left": null,
              "right": null
            },
            {
              "id": "h4-10",
              "value": 10,
              "left": null,
              "right": null
            },
            {
              "id": "h2-8",
              "value": 8,
              "left": null,
              "right": null
            }
          ],
          "rootId": "h3-25"
        },
        "pointers": [],
        "highlights": [],
        "codeLine": 7,
        "variables": {
          "swaps": 4
        },
        "explanation": "30 climbs one level up.",
        "stats": {
          "comparisons": 6,
          "swaps": 4
        },
        "accent": "swap"
      },
      {
        "data": {
          "nodes": [
            {
              "id": "h3-25",
              "value": 25,
              "left": "h1-20",
              "right": "h5-30",
              "role": "compare"
            },
            {
              "id": "h1-20",
              "value": 20,
              "left": "h0-15",
              "right": "h4-10"
            },
            {
              "id": "h5-30",
              "value": 30,
              "left": "h2-8",
              "right": null,
              "role": "active"
            },
            {
              "id": "h0-15",
              "value": 15,
              "left": null,
              "right": null
            },
            {
              "id": "h4-10",
              "value": 10,
              "left": null,
              "right": null
            },
            {
              "id": "h2-8",
              "value": 8,
              "left": null,
              "right": null
            }
          ],
          "rootId": "h3-25"
        },
        "pointers": [],
        "highlights": [],
        "codeLine": 6,
        "variables": {
          "child": 30,
          "parent": 25
        },
        "explanation": "30 is bigger than its parent 25. In a max-heap the parent must be bigger, so they swap.",
        "stats": {
          "comparisons": 7,
          "swaps": 4
        },
        "accent": "compare"
      },
      {
        "data": {
          "nodes": [
            {
              "id": "h5-30",
              "value": 30,
              "left": "h1-20",
              "right": "h3-25",
              "role": "active"
            },
            {
              "id": "h1-20",
              "value": 20,
              "left": "h0-15",
              "right": "h4-10"
            },
            {
              "id": "h3-25",
              "value": 25,
              "left": "h2-8",
              "right": null
            },
            {
              "id": "h0-15",
              "value": 15,
              "left": null,
              "right": null
            },
            {
              "id": "h4-10",
              "value": 10,
              "left": null,
              "right": null
            },
            {
              "id": "h2-8",
              "value": 8,
              "left": null,
              "right": null
            }
          ],
          "rootId": "h5-30"
        },
        "pointers": [],
        "highlights": [],
        "codeLine": 7,
        "variables": {
          "swaps": 5
        },
        "explanation": "30 climbs one level up.",
        "stats": {
          "comparisons": 7,
          "swaps": 5
        },
        "accent": "swap"
      },
      {
        "data": {
          "nodes": [
            {
              "id": "h5-30",
              "value": 30,
              "left": "h1-20",
              "right": "h3-25"
            },
            {
              "id": "h1-20",
              "value": 20,
              "left": "h0-15",
              "right": "h4-10"
            },
            {
              "id": "h3-25",
              "value": 25,
              "left": "h2-8",
              "right": "h6-5"
            },
            {
              "id": "h0-15",
              "value": 15,
              "left": null,
              "right": null
            },
            {
              "id": "h4-10",
              "value": 10,
              "left": null,
              "right": null
            },
            {
              "id": "h2-8",
              "value": 8,
              "left": null,
              "right": null
            },
            {
              "id": "h6-5",
              "value": 5,
              "left": null,
              "right": null,
              "role": "active"
            }
          ],
          "rootId": "h5-30"
        },
        "pointers": [],
        "highlights": [],
        "codeLine": 2,
        "variables": {
          "inserting": 5,
          "size": 7
        },
        "explanation": "Add 5 at the next open spot — the bottom of the tree. It probably breaks the heap rule, so now it has to climb.",
        "stats": {
          "comparisons": 7,
          "swaps": 5
        },
        "accent": "active"
      },
      {
        "data": {
          "nodes": [
            {
              "id": "h5-30",
              "value": 30,
              "left": "h1-20",
              "right": "h3-25"
            },
            {
              "id": "h1-20",
              "value": 20,
              "left": "h0-15",
              "right": "h4-10"
            },
            {
              "id": "h3-25",
              "value": 25,
              "left": "h2-8",
              "right": "h6-5",
              "role": "compare"
            },
            {
              "id": "h0-15",
              "value": 15,
              "left": null,
              "right": null
            },
            {
              "id": "h4-10",
              "value": 10,
              "left": null,
              "right": null
            },
            {
              "id": "h2-8",
              "value": 8,
              "left": null,
              "right": null
            },
            {
              "id": "h6-5",
              "value": 5,
              "left": null,
              "right": null,
              "role": "active"
            }
          ],
          "rootId": "h5-30"
        },
        "pointers": [],
        "highlights": [],
        "codeLine": 6,
        "variables": {
          "child": 5,
          "parent": 25
        },
        "explanation": "5 is not bigger than its parent 25. The heap rule holds — 5 stops climbing.",
        "stats": {
          "comparisons": 8,
          "swaps": 5
        },
        "accent": "compare"
      },
      {
        "data": {
          "nodes": [
            {
              "id": "h5-30",
              "value": 30,
              "left": "h1-20",
              "right": "h3-25",
              "role": "found"
            },
            {
              "id": "h1-20",
              "value": 20,
              "left": "h0-15",
              "right": "h4-10"
            },
            {
              "id": "h3-25",
              "value": 25,
              "left": "h2-8",
              "right": "h6-5"
            },
            {
              "id": "h0-15",
              "value": 15,
              "left": null,
              "right": null
            },
            {
              "id": "h4-10",
              "value": 10,
              "left": null,
              "right": null
            },
            {
              "id": "h2-8",
              "value": 8,
              "left": null,
              "right": null
            },
            {
              "id": "h6-5",
              "value": 5,
              "left": null,
              "right": null
            }
          ],
          "rootId": "h5-30"
        },
        "pointers": [],
        "highlights": [],
        "codeLine": 10,
        "variables": {
          "max": 30,
          "size": 7
        },
        "explanation": "Heap complete. The largest value, 30, sits at the root — and it got there in about log n steps per insert, never having to look at the whole tree.",
        "stats": {
          "comparisons": 8,
          "swaps": 5
        },
        "accent": "found"
      }
    ]
  }
}