{
  "slug": "hash-linear-probing",
  "title": "Hash Table — Linear Probing",
  "category": "Hashing",
  "difficulty": "medium",
  "complexity": {
    "time": "O(1) average",
    "space": "O(m)"
  },
  "idea": "A hash function turns a key into a slot index. When two keys want the same slot (a collision), open addressing simply probes forward to the next free slot. Lookups repeat the same walk.",
  "code": [
    "slot = k mod m",
    "while table[slot] is occupied:",
    "    slot = (slot + 1) mod m      # probe forward",
    "table[slot] = k"
  ],
  "example": {
    "array": [
      15,
      11,
      27,
      8,
      12
    ]
  },
  "invariant": "Each step is the real data structure at that step — the picture is a pure function of it.",
  "stepCount": 13,
  "steps": [
    {
      "i": 0,
      "op": "lanes",
      "caption": "Insert each key into 7 slots using h(k) = k mod 7, probing forward on collision.",
      "note": null,
      "codeLine": 1,
      "stats": null,
      "lanes": [
        {
          "id": "keys",
          "label": "keys to insert",
          "array": [
            15,
            11,
            27,
            8,
            12
          ],
          "focus": [
            null,
            null,
            null,
            null,
            null
          ],
          "markers": [],
          "regions": []
        },
        {
          "id": "table",
          "label": "table (m = 7, index = slot)",
          "array": [
            0,
            0,
            0,
            0,
            0,
            0,
            0
          ],
          "focus": [
            null,
            null,
            null,
            null,
            null,
            null,
            null
          ],
          "placeholders": [
            true,
            true,
            true,
            true,
            true,
            true,
            true
          ],
          "markers": [],
          "regions": []
        }
      ]
    },
    {
      "i": 1,
      "op": "lanes",
      "caption": "h(15) = 15 mod 7 = 1.",
      "note": null,
      "codeLine": 1,
      "stats": null,
      "lanes": [
        {
          "id": "keys",
          "label": "keys to insert",
          "array": [
            15,
            11,
            27,
            8,
            12
          ],
          "focus": [
            "read",
            null,
            null,
            null,
            null
          ],
          "markers": [],
          "regions": []
        },
        {
          "id": "table",
          "label": "table (m = 7, index = slot)",
          "array": [
            0,
            0,
            0,
            0,
            0,
            0,
            0
          ],
          "focus": [
            null,
            null,
            null,
            null,
            null,
            null,
            null
          ],
          "placeholders": [
            true,
            true,
            true,
            true,
            true,
            true,
            true
          ],
          "markers": [
            {
              "name": "h",
              "index": 1,
              "tone": "compare"
            }
          ],
          "regions": []
        }
      ]
    },
    {
      "i": 2,
      "op": "lanes",
      "caption": "Slot 1 is free — place 15 there.",
      "note": null,
      "codeLine": 4,
      "stats": {
        "probes": 0
      },
      "lanes": [
        {
          "id": "keys",
          "label": "keys to insert",
          "array": [
            15,
            11,
            27,
            8,
            12
          ],
          "focus": [
            "settled",
            null,
            null,
            null,
            null
          ],
          "markers": [],
          "regions": []
        },
        {
          "id": "table",
          "label": "table (m = 7, index = slot)",
          "array": [
            0,
            15,
            0,
            0,
            0,
            0,
            0
          ],
          "focus": [
            null,
            "insert",
            null,
            null,
            null,
            null,
            null
          ],
          "placeholders": [
            true,
            false,
            true,
            true,
            true,
            true,
            true
          ],
          "markers": [
            {
              "name": "h",
              "index": 1,
              "tone": "compare"
            }
          ],
          "regions": []
        }
      ]
    },
    {
      "i": 3,
      "op": "lanes",
      "caption": "h(11) = 11 mod 7 = 4.",
      "note": null,
      "codeLine": 1,
      "stats": {
        "probes": 0
      },
      "lanes": [
        {
          "id": "keys",
          "label": "keys to insert",
          "array": [
            15,
            11,
            27,
            8,
            12
          ],
          "focus": [
            null,
            "read",
            null,
            null,
            null
          ],
          "markers": [],
          "regions": []
        },
        {
          "id": "table",
          "label": "table (m = 7, index = slot)",
          "array": [
            0,
            15,
            0,
            0,
            0,
            0,
            0
          ],
          "focus": [
            null,
            null,
            null,
            null,
            null,
            null,
            null
          ],
          "placeholders": [
            true,
            false,
            true,
            true,
            true,
            true,
            true
          ],
          "markers": [
            {
              "name": "h",
              "index": 4,
              "tone": "compare"
            }
          ],
          "regions": []
        }
      ]
    },
    {
      "i": 4,
      "op": "lanes",
      "caption": "Slot 4 is free — place 11 there.",
      "note": null,
      "codeLine": 4,
      "stats": {
        "probes": 0
      },
      "lanes": [
        {
          "id": "keys",
          "label": "keys to insert",
          "array": [
            15,
            11,
            27,
            8,
            12
          ],
          "focus": [
            null,
            "settled",
            null,
            null,
            null
          ],
          "markers": [],
          "regions": []
        },
        {
          "id": "table",
          "label": "table (m = 7, index = slot)",
          "array": [
            0,
            15,
            0,
            0,
            11,
            0,
            0
          ],
          "focus": [
            null,
            null,
            null,
            null,
            "insert",
            null,
            null
          ],
          "placeholders": [
            true,
            false,
            true,
            true,
            false,
            true,
            true
          ],
          "markers": [
            {
              "name": "h",
              "index": 4,
              "tone": "compare"
            }
          ],
          "regions": []
        }
      ]
    },
    {
      "i": 5,
      "op": "lanes",
      "caption": "h(27) = 27 mod 7 = 6.",
      "note": null,
      "codeLine": 1,
      "stats": {
        "probes": 0
      },
      "lanes": [
        {
          "id": "keys",
          "label": "keys to insert",
          "array": [
            15,
            11,
            27,
            8,
            12
          ],
          "focus": [
            null,
            null,
            "read",
            null,
            null
          ],
          "markers": [],
          "regions": []
        },
        {
          "id": "table",
          "label": "table (m = 7, index = slot)",
          "array": [
            0,
            15,
            0,
            0,
            11,
            0,
            0
          ],
          "focus": [
            null,
            null,
            null,
            null,
            null,
            null,
            null
          ],
          "placeholders": [
            true,
            false,
            true,
            true,
            false,
            true,
            true
          ],
          "markers": [
            {
              "name": "h",
              "index": 6,
              "tone": "compare"
            }
          ],
          "regions": []
        }
      ]
    },
    {
      "i": 6,
      "op": "lanes",
      "caption": "Slot 6 is free — place 27 there.",
      "note": null,
      "codeLine": 4,
      "stats": {
        "probes": 0
      },
      "lanes": [
        {
          "id": "keys",
          "label": "keys to insert",
          "array": [
            15,
            11,
            27,
            8,
            12
          ],
          "focus": [
            null,
            null,
            "settled",
            null,
            null
          ],
          "markers": [],
          "regions": []
        },
        {
          "id": "table",
          "label": "table (m = 7, index = slot)",
          "array": [
            0,
            15,
            0,
            0,
            11,
            0,
            27
          ],
          "focus": [
            null,
            null,
            null,
            null,
            null,
            null,
            "insert"
          ],
          "placeholders": [
            true,
            false,
            true,
            true,
            false,
            true,
            false
          ],
          "markers": [
            {
              "name": "h",
              "index": 6,
              "tone": "compare"
            }
          ],
          "regions": []
        }
      ]
    },
    {
      "i": 7,
      "op": "lanes",
      "caption": "h(8) = 8 mod 7 = 1.",
      "note": null,
      "codeLine": 1,
      "stats": {
        "probes": 0
      },
      "lanes": [
        {
          "id": "keys",
          "label": "keys to insert",
          "array": [
            15,
            11,
            27,
            8,
            12
          ],
          "focus": [
            null,
            null,
            null,
            "read",
            null
          ],
          "markers": [],
          "regions": []
        },
        {
          "id": "table",
          "label": "table (m = 7, index = slot)",
          "array": [
            0,
            15,
            0,
            0,
            11,
            0,
            27
          ],
          "focus": [
            null,
            null,
            null,
            null,
            null,
            null,
            null
          ],
          "placeholders": [
            true,
            false,
            true,
            true,
            false,
            true,
            false
          ],
          "markers": [
            {
              "name": "h",
              "index": 1,
              "tone": "compare"
            }
          ],
          "regions": []
        }
      ]
    },
    {
      "i": 8,
      "op": "lanes",
      "caption": "Slot 1 already holds 15 — collision, probe forward.",
      "note": null,
      "codeLine": 3,
      "stats": {
        "probes": 0
      },
      "lanes": [
        {
          "id": "keys",
          "label": "keys to insert",
          "array": [
            15,
            11,
            27,
            8,
            12
          ],
          "focus": [
            null,
            null,
            null,
            "read",
            null
          ],
          "markers": [],
          "regions": []
        },
        {
          "id": "table",
          "label": "table (m = 7, index = slot)",
          "array": [
            0,
            15,
            0,
            0,
            11,
            0,
            27
          ],
          "focus": [
            null,
            "compare",
            null,
            null,
            null,
            null,
            null
          ],
          "placeholders": [
            true,
            false,
            true,
            true,
            false,
            true,
            false
          ],
          "markers": [
            {
              "name": "h",
              "index": 1,
              "tone": "compare"
            }
          ],
          "regions": []
        }
      ]
    },
    {
      "i": 9,
      "op": "lanes",
      "caption": "Slot 2 is free after 1 probe — place 8 there.",
      "note": null,
      "codeLine": 4,
      "stats": {
        "probes": 1
      },
      "lanes": [
        {
          "id": "keys",
          "label": "keys to insert",
          "array": [
            15,
            11,
            27,
            8,
            12
          ],
          "focus": [
            null,
            null,
            null,
            "settled",
            null
          ],
          "markers": [],
          "regions": []
        },
        {
          "id": "table",
          "label": "table (m = 7, index = slot)",
          "array": [
            0,
            15,
            8,
            0,
            11,
            0,
            27
          ],
          "focus": [
            null,
            null,
            "insert",
            null,
            null,
            null,
            null
          ],
          "placeholders": [
            true,
            false,
            false,
            true,
            false,
            true,
            false
          ],
          "markers": [
            {
              "name": "h",
              "index": 2,
              "tone": "compare"
            }
          ],
          "regions": []
        }
      ]
    },
    {
      "i": 10,
      "op": "lanes",
      "caption": "h(12) = 12 mod 7 = 5.",
      "note": null,
      "codeLine": 1,
      "stats": {
        "probes": 1
      },
      "lanes": [
        {
          "id": "keys",
          "label": "keys to insert",
          "array": [
            15,
            11,
            27,
            8,
            12
          ],
          "focus": [
            null,
            null,
            null,
            null,
            "read"
          ],
          "markers": [],
          "regions": []
        },
        {
          "id": "table",
          "label": "table (m = 7, index = slot)",
          "array": [
            0,
            15,
            8,
            0,
            11,
            0,
            27
          ],
          "focus": [
            null,
            null,
            null,
            null,
            null,
            null,
            null
          ],
          "placeholders": [
            true,
            false,
            false,
            true,
            false,
            true,
            false
          ],
          "markers": [
            {
              "name": "h",
              "index": 5,
              "tone": "compare"
            }
          ],
          "regions": []
        }
      ]
    },
    {
      "i": 11,
      "op": "lanes",
      "caption": "Slot 5 is free — place 12 there.",
      "note": null,
      "codeLine": 4,
      "stats": {
        "probes": 0
      },
      "lanes": [
        {
          "id": "keys",
          "label": "keys to insert",
          "array": [
            15,
            11,
            27,
            8,
            12
          ],
          "focus": [
            null,
            null,
            null,
            null,
            "settled"
          ],
          "markers": [],
          "regions": []
        },
        {
          "id": "table",
          "label": "table (m = 7, index = slot)",
          "array": [
            0,
            15,
            8,
            0,
            11,
            12,
            27
          ],
          "focus": [
            null,
            null,
            null,
            null,
            null,
            "insert",
            null
          ],
          "placeholders": [
            true,
            false,
            false,
            true,
            false,
            false,
            false
          ],
          "markers": [
            {
              "name": "h",
              "index": 5,
              "tone": "compare"
            }
          ],
          "regions": []
        }
      ]
    },
    {
      "i": 12,
      "op": "lanes",
      "caption": "All keys placed. A lookup repeats the same probe walk.",
      "note": null,
      "codeLine": 4,
      "stats": {
        "probes": 0
      },
      "lanes": [
        {
          "id": "keys",
          "label": "keys to insert",
          "array": [
            15,
            11,
            27,
            8,
            12
          ],
          "focus": [
            null,
            null,
            null,
            null,
            null
          ],
          "markers": [],
          "regions": []
        },
        {
          "id": "table",
          "label": "table (m = 7, index = slot)",
          "array": [
            0,
            15,
            8,
            0,
            11,
            12,
            27
          ],
          "focus": [
            null,
            null,
            null,
            null,
            null,
            null,
            null
          ],
          "placeholders": [
            true,
            false,
            false,
            true,
            false,
            false,
            false
          ],
          "markers": [],
          "regions": []
        }
      ]
    }
  ]
}