{
  "slug": "counting-sort",
  "title": "Counting Sort",
  "category": "Sorting",
  "difficulty": "medium",
  "complexity": {
    "time": "O(n + k)",
    "space": "O(n + k)"
  },
  "idea": "For small non-negative integers, count how many of each value there are, turn the counts into end positions with a running sum, then place each input value where it belongs. Stable and comparison-free.",
  "code": [
    "for each value: counts[value]++",
    "counts[v] += counts[v-1]   # end positions",
    "for i = n-1 down to 0:",
    "    output[--counts[a[i]]] = a[i]   # stable",
    "output is sorted"
  ],
  "example": {
    "array": [
      4,
      2,
      2,
      8,
      3,
      3,
      1
    ]
  },
  "invariant": "Each step is the real data structure at that step — the picture is a pure function of it.",
  "stepCount": 17,
  "steps": [
    {
      "i": 0,
      "op": "lanes",
      "caption": "Counting sort: tally every value, then place them all in order.",
      "note": null,
      "codeLine": 1,
      "stats": null,
      "lanes": [
        {
          "id": "in",
          "label": "input",
          "array": [
            4,
            2,
            2,
            8,
            3,
            3,
            1
          ],
          "focus": [
            null,
            null,
            null,
            null,
            null,
            null,
            null
          ],
          "markers": [],
          "regions": []
        },
        {
          "id": "count",
          "label": "counts (index = value)",
          "array": [
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0
          ],
          "focus": [
            null,
            null,
            null,
            null,
            null,
            null,
            null,
            null,
            null
          ],
          "markers": [],
          "regions": []
        },
        {
          "id": "out",
          "label": "output",
          "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": "input[0] = 4 → counts[4] = 1.",
      "note": null,
      "codeLine": 1,
      "stats": null,
      "lanes": [
        {
          "id": "in",
          "label": "input",
          "array": [
            4,
            2,
            2,
            8,
            3,
            3,
            1
          ],
          "focus": [
            "read",
            null,
            null,
            null,
            null,
            null,
            null
          ],
          "markers": [],
          "regions": []
        },
        {
          "id": "count",
          "label": "counts (index = value)",
          "array": [
            0,
            0,
            0,
            0,
            1,
            0,
            0,
            0,
            0
          ],
          "focus": [
            null,
            null,
            null,
            null,
            "write",
            null,
            null,
            null,
            null
          ],
          "markers": [],
          "regions": []
        },
        {
          "id": "out",
          "label": "output",
          "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": 2,
      "op": "lanes",
      "caption": "input[1] = 2 → counts[2] = 1.",
      "note": null,
      "codeLine": 1,
      "stats": null,
      "lanes": [
        {
          "id": "in",
          "label": "input",
          "array": [
            4,
            2,
            2,
            8,
            3,
            3,
            1
          ],
          "focus": [
            null,
            "read",
            null,
            null,
            null,
            null,
            null
          ],
          "markers": [],
          "regions": []
        },
        {
          "id": "count",
          "label": "counts (index = value)",
          "array": [
            0,
            0,
            1,
            0,
            1,
            0,
            0,
            0,
            0
          ],
          "focus": [
            null,
            null,
            "write",
            null,
            null,
            null,
            null,
            null,
            null
          ],
          "markers": [],
          "regions": []
        },
        {
          "id": "out",
          "label": "output",
          "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": 3,
      "op": "lanes",
      "caption": "input[2] = 2 → counts[2] = 2.",
      "note": null,
      "codeLine": 1,
      "stats": null,
      "lanes": [
        {
          "id": "in",
          "label": "input",
          "array": [
            4,
            2,
            2,
            8,
            3,
            3,
            1
          ],
          "focus": [
            null,
            null,
            "read",
            null,
            null,
            null,
            null
          ],
          "markers": [],
          "regions": []
        },
        {
          "id": "count",
          "label": "counts (index = value)",
          "array": [
            0,
            0,
            2,
            0,
            1,
            0,
            0,
            0,
            0
          ],
          "focus": [
            null,
            null,
            "write",
            null,
            null,
            null,
            null,
            null,
            null
          ],
          "markers": [],
          "regions": []
        },
        {
          "id": "out",
          "label": "output",
          "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": 4,
      "op": "lanes",
      "caption": "input[3] = 8 → counts[8] = 1.",
      "note": null,
      "codeLine": 1,
      "stats": null,
      "lanes": [
        {
          "id": "in",
          "label": "input",
          "array": [
            4,
            2,
            2,
            8,
            3,
            3,
            1
          ],
          "focus": [
            null,
            null,
            null,
            "read",
            null,
            null,
            null
          ],
          "markers": [],
          "regions": []
        },
        {
          "id": "count",
          "label": "counts (index = value)",
          "array": [
            0,
            0,
            2,
            0,
            1,
            0,
            0,
            0,
            1
          ],
          "focus": [
            null,
            null,
            null,
            null,
            null,
            null,
            null,
            null,
            "write"
          ],
          "markers": [],
          "regions": []
        },
        {
          "id": "out",
          "label": "output",
          "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": 5,
      "op": "lanes",
      "caption": "input[4] = 3 → counts[3] = 1.",
      "note": null,
      "codeLine": 1,
      "stats": null,
      "lanes": [
        {
          "id": "in",
          "label": "input",
          "array": [
            4,
            2,
            2,
            8,
            3,
            3,
            1
          ],
          "focus": [
            null,
            null,
            null,
            null,
            "read",
            null,
            null
          ],
          "markers": [],
          "regions": []
        },
        {
          "id": "count",
          "label": "counts (index = value)",
          "array": [
            0,
            0,
            2,
            1,
            1,
            0,
            0,
            0,
            1
          ],
          "focus": [
            null,
            null,
            null,
            "write",
            null,
            null,
            null,
            null,
            null
          ],
          "markers": [],
          "regions": []
        },
        {
          "id": "out",
          "label": "output",
          "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": 6,
      "op": "lanes",
      "caption": "input[5] = 3 → counts[3] = 2.",
      "note": null,
      "codeLine": 1,
      "stats": null,
      "lanes": [
        {
          "id": "in",
          "label": "input",
          "array": [
            4,
            2,
            2,
            8,
            3,
            3,
            1
          ],
          "focus": [
            null,
            null,
            null,
            null,
            null,
            "read",
            null
          ],
          "markers": [],
          "regions": []
        },
        {
          "id": "count",
          "label": "counts (index = value)",
          "array": [
            0,
            0,
            2,
            2,
            1,
            0,
            0,
            0,
            1
          ],
          "focus": [
            null,
            null,
            null,
            "write",
            null,
            null,
            null,
            null,
            null
          ],
          "markers": [],
          "regions": []
        },
        {
          "id": "out",
          "label": "output",
          "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": 7,
      "op": "lanes",
      "caption": "input[6] = 1 → counts[1] = 1.",
      "note": null,
      "codeLine": 1,
      "stats": null,
      "lanes": [
        {
          "id": "in",
          "label": "input",
          "array": [
            4,
            2,
            2,
            8,
            3,
            3,
            1
          ],
          "focus": [
            null,
            null,
            null,
            null,
            null,
            null,
            "read"
          ],
          "markers": [],
          "regions": []
        },
        {
          "id": "count",
          "label": "counts (index = value)",
          "array": [
            0,
            1,
            2,
            2,
            1,
            0,
            0,
            0,
            1
          ],
          "focus": [
            null,
            "write",
            null,
            null,
            null,
            null,
            null,
            null,
            null
          ],
          "markers": [],
          "regions": []
        },
        {
          "id": "out",
          "label": "output",
          "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": 8,
      "op": "lanes",
      "caption": "Running-sum the counts, so each value knows its end position.",
      "note": null,
      "codeLine": 2,
      "stats": null,
      "lanes": [
        {
          "id": "in",
          "label": "input",
          "array": [
            4,
            2,
            2,
            8,
            3,
            3,
            1
          ],
          "focus": [
            null,
            null,
            null,
            null,
            null,
            null,
            null
          ],
          "markers": [],
          "regions": []
        },
        {
          "id": "count",
          "label": "counts (index = value)",
          "array": [
            0,
            1,
            3,
            5,
            6,
            6,
            6,
            6,
            7
          ],
          "focus": [
            "read",
            "read",
            "read",
            "read",
            "read",
            "read",
            "read",
            "read",
            "read"
          ],
          "markers": [],
          "regions": []
        },
        {
          "id": "out",
          "label": "output",
          "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": 9,
      "op": "lanes",
      "caption": "Place 1 at output[0] (right to left keeps it stable).",
      "note": null,
      "codeLine": 4,
      "stats": null,
      "lanes": [
        {
          "id": "in",
          "label": "input",
          "array": [
            4,
            2,
            2,
            8,
            3,
            3,
            1
          ],
          "focus": [
            null,
            null,
            null,
            null,
            null,
            null,
            "read"
          ],
          "markers": [],
          "regions": []
        },
        {
          "id": "count",
          "label": "counts (index = value)",
          "array": [
            0,
            0,
            3,
            5,
            6,
            6,
            6,
            6,
            7
          ],
          "focus": [
            null,
            "write",
            null,
            null,
            null,
            null,
            null,
            null,
            null
          ],
          "markers": [],
          "regions": []
        },
        {
          "id": "out",
          "label": "output",
          "array": [
            1,
            0,
            0,
            0,
            0,
            0,
            0
          ],
          "focus": [
            "insert",
            null,
            null,
            null,
            null,
            null,
            null
          ],
          "placeholders": [
            false,
            true,
            true,
            true,
            true,
            true,
            true
          ],
          "markers": [],
          "regions": []
        }
      ]
    },
    {
      "i": 10,
      "op": "lanes",
      "caption": "Place 3 at output[4] (right to left keeps it stable).",
      "note": null,
      "codeLine": 4,
      "stats": null,
      "lanes": [
        {
          "id": "in",
          "label": "input",
          "array": [
            4,
            2,
            2,
            8,
            3,
            3,
            1
          ],
          "focus": [
            null,
            null,
            null,
            null,
            null,
            "read",
            null
          ],
          "markers": [],
          "regions": []
        },
        {
          "id": "count",
          "label": "counts (index = value)",
          "array": [
            0,
            0,
            3,
            4,
            6,
            6,
            6,
            6,
            7
          ],
          "focus": [
            null,
            null,
            null,
            "write",
            null,
            null,
            null,
            null,
            null
          ],
          "markers": [],
          "regions": []
        },
        {
          "id": "out",
          "label": "output",
          "array": [
            1,
            0,
            0,
            0,
            3,
            0,
            0
          ],
          "focus": [
            null,
            null,
            null,
            null,
            "insert",
            null,
            null
          ],
          "placeholders": [
            false,
            true,
            true,
            true,
            false,
            true,
            true
          ],
          "markers": [],
          "regions": []
        }
      ]
    },
    {
      "i": 11,
      "op": "lanes",
      "caption": "Place 3 at output[3] (right to left keeps it stable).",
      "note": null,
      "codeLine": 4,
      "stats": null,
      "lanes": [
        {
          "id": "in",
          "label": "input",
          "array": [
            4,
            2,
            2,
            8,
            3,
            3,
            1
          ],
          "focus": [
            null,
            null,
            null,
            null,
            "read",
            null,
            null
          ],
          "markers": [],
          "regions": []
        },
        {
          "id": "count",
          "label": "counts (index = value)",
          "array": [
            0,
            0,
            3,
            3,
            6,
            6,
            6,
            6,
            7
          ],
          "focus": [
            null,
            null,
            null,
            "write",
            null,
            null,
            null,
            null,
            null
          ],
          "markers": [],
          "regions": []
        },
        {
          "id": "out",
          "label": "output",
          "array": [
            1,
            0,
            0,
            3,
            3,
            0,
            0
          ],
          "focus": [
            null,
            null,
            null,
            "insert",
            null,
            null,
            null
          ],
          "placeholders": [
            false,
            true,
            true,
            false,
            false,
            true,
            true
          ],
          "markers": [],
          "regions": []
        }
      ]
    },
    {
      "i": 12,
      "op": "lanes",
      "caption": "Place 8 at output[6] (right to left keeps it stable).",
      "note": null,
      "codeLine": 4,
      "stats": null,
      "lanes": [
        {
          "id": "in",
          "label": "input",
          "array": [
            4,
            2,
            2,
            8,
            3,
            3,
            1
          ],
          "focus": [
            null,
            null,
            null,
            "read",
            null,
            null,
            null
          ],
          "markers": [],
          "regions": []
        },
        {
          "id": "count",
          "label": "counts (index = value)",
          "array": [
            0,
            0,
            3,
            3,
            6,
            6,
            6,
            6,
            6
          ],
          "focus": [
            null,
            null,
            null,
            null,
            null,
            null,
            null,
            null,
            "write"
          ],
          "markers": [],
          "regions": []
        },
        {
          "id": "out",
          "label": "output",
          "array": [
            1,
            0,
            0,
            3,
            3,
            0,
            8
          ],
          "focus": [
            null,
            null,
            null,
            null,
            null,
            null,
            "insert"
          ],
          "placeholders": [
            false,
            true,
            true,
            false,
            false,
            true,
            false
          ],
          "markers": [],
          "regions": []
        }
      ]
    },
    {
      "i": 13,
      "op": "lanes",
      "caption": "Place 2 at output[2] (right to left keeps it stable).",
      "note": null,
      "codeLine": 4,
      "stats": null,
      "lanes": [
        {
          "id": "in",
          "label": "input",
          "array": [
            4,
            2,
            2,
            8,
            3,
            3,
            1
          ],
          "focus": [
            null,
            null,
            "read",
            null,
            null,
            null,
            null
          ],
          "markers": [],
          "regions": []
        },
        {
          "id": "count",
          "label": "counts (index = value)",
          "array": [
            0,
            0,
            2,
            3,
            6,
            6,
            6,
            6,
            6
          ],
          "focus": [
            null,
            null,
            "write",
            null,
            null,
            null,
            null,
            null,
            null
          ],
          "markers": [],
          "regions": []
        },
        {
          "id": "out",
          "label": "output",
          "array": [
            1,
            0,
            2,
            3,
            3,
            0,
            8
          ],
          "focus": [
            null,
            null,
            "insert",
            null,
            null,
            null,
            null
          ],
          "placeholders": [
            false,
            true,
            false,
            false,
            false,
            true,
            false
          ],
          "markers": [],
          "regions": []
        }
      ]
    },
    {
      "i": 14,
      "op": "lanes",
      "caption": "Place 2 at output[1] (right to left keeps it stable).",
      "note": null,
      "codeLine": 4,
      "stats": null,
      "lanes": [
        {
          "id": "in",
          "label": "input",
          "array": [
            4,
            2,
            2,
            8,
            3,
            3,
            1
          ],
          "focus": [
            null,
            "read",
            null,
            null,
            null,
            null,
            null
          ],
          "markers": [],
          "regions": []
        },
        {
          "id": "count",
          "label": "counts (index = value)",
          "array": [
            0,
            0,
            1,
            3,
            6,
            6,
            6,
            6,
            6
          ],
          "focus": [
            null,
            null,
            "write",
            null,
            null,
            null,
            null,
            null,
            null
          ],
          "markers": [],
          "regions": []
        },
        {
          "id": "out",
          "label": "output",
          "array": [
            1,
            2,
            2,
            3,
            3,
            0,
            8
          ],
          "focus": [
            null,
            "insert",
            null,
            null,
            null,
            null,
            null
          ],
          "placeholders": [
            false,
            false,
            false,
            false,
            false,
            true,
            false
          ],
          "markers": [],
          "regions": []
        }
      ]
    },
    {
      "i": 15,
      "op": "lanes",
      "caption": "Place 4 at output[5] (right to left keeps it stable).",
      "note": null,
      "codeLine": 4,
      "stats": null,
      "lanes": [
        {
          "id": "in",
          "label": "input",
          "array": [
            4,
            2,
            2,
            8,
            3,
            3,
            1
          ],
          "focus": [
            "read",
            null,
            null,
            null,
            null,
            null,
            null
          ],
          "markers": [],
          "regions": []
        },
        {
          "id": "count",
          "label": "counts (index = value)",
          "array": [
            0,
            0,
            1,
            3,
            5,
            6,
            6,
            6,
            6
          ],
          "focus": [
            null,
            null,
            null,
            null,
            "write",
            null,
            null,
            null,
            null
          ],
          "markers": [],
          "regions": []
        },
        {
          "id": "out",
          "label": "output",
          "array": [
            1,
            2,
            2,
            3,
            3,
            4,
            8
          ],
          "focus": [
            null,
            null,
            null,
            null,
            null,
            "insert",
            null
          ],
          "markers": [],
          "regions": []
        }
      ]
    },
    {
      "i": 16,
      "op": "lanes",
      "caption": "Sorted — the output holds every value in order.",
      "note": null,
      "codeLine": 5,
      "stats": null,
      "lanes": [
        {
          "id": "in",
          "label": "input",
          "array": [
            4,
            2,
            2,
            8,
            3,
            3,
            1
          ],
          "focus": [
            null,
            null,
            null,
            null,
            null,
            null,
            null
          ],
          "markers": [],
          "regions": []
        },
        {
          "id": "count",
          "label": "counts (index = value)",
          "array": [
            0,
            0,
            1,
            3,
            5,
            6,
            6,
            6,
            6
          ],
          "focus": [
            null,
            null,
            null,
            null,
            null,
            null,
            null,
            null,
            null
          ],
          "markers": [],
          "regions": []
        },
        {
          "id": "out",
          "label": "output",
          "array": [
            1,
            2,
            2,
            3,
            3,
            4,
            8
          ],
          "focus": [
            "settled",
            "settled",
            "settled",
            "settled",
            "settled",
            "settled",
            "settled"
          ],
          "markers": [],
          "regions": [
            {
              "label": "done",
              "from": 0,
              "to": 6,
              "tone": "settled"
            }
          ]
        }
      ]
    }
  ]
}