Fact-checked by Grok 2 weeks ago

Counting sort

Counting sort is a non-comparison-based sorting algorithm designed for sorting a collection of integers within a small, known range, achieving linear time complexity by counting the occurrences of each possible value and using these counts to place elements in their correct positions in the output array. The algorithm assumes the input consists of n elements drawn from the set {0, 1, ..., k-1}, where k is the range of key values, and it operates by first initializing a count array of size k to zero, then incrementing the count for each input element, computing cumulative sums to determine positions, and finally building the sorted array by placing elements in reverse order to maintain stability. This process ensures the relative order of equal elements is preserved, making it a stable sort. Invented by Harold H. Seward in 1954 as part of early work on digital computer applications for business operations at , counting sort laid foundational techniques for efficient and was integrated into implementations to handle multi-digit keys. Its of Θ(n + k) makes it optimal when k is O(n), outperforming comparison-based sorts like or mergesort in such scenarios, though it requires additional space proportional to k and is impractical for large or unknown ranges without modifications. Counting sort is often used as a subroutine in more advanced algorithms, such as for larger , and remains a key example in algorithm education for illustrating space-time tradeoffs in .

Fundamentals

Description

Counting sort is a non-comparative sorting algorithm that determines the sorted order of elements by first counting the occurrences of each possible value in the input and then using these counts, along with arithmetic operations, to directly compute and place each element in its final position in the output array. This approach was originally described as a subroutine within digital sorting methods by Harold H. Seward in his 1954 master's thesis at . Unlike comparison-based algorithms that rely on pairwise element comparisons to establish order, counting sort leverages the discrete nature of the input values and a known bounded , employing indices directly corresponding to those values to avoid comparisons altogether. It operates by initializing a count sized to the input , incrementing entries for each input value's frequency, and then transforming this into a cumulative that specifies output positions. As a distribution-based sorting method, counting sort partitions elements into temporary storage based on their values—effectively using the count array as a set of buckets—and reconstructs the sorted sequence by placing elements according to the cumulative counts, akin to a single-pass variant of the distribution step in . This design enables efficient handling of discrete data when the value range is not excessively large, though it involves a space trade-off proportional to that range.

Assumptions

Counting sort requires a specific set of input conditions to function correctly and efficiently. The input is an of n elements, where each is a non-negative with values ranging from 0 to k, and k represents the maximum value in the array, which must be known beforehand to determine the of the auxiliary count array. This known range allows for the allocation of a count array of k+1, enabling the algorithm to tally occurrences without exceeding memory bounds proportional to the input range. The output of counting sort is a new array of the same size n, containing the input elements rearranged in non-decreasing order. The assumption of non-negative integers is crucial because negative values would correspond to invalid negative indices in the count array, which are not supported in standard array implementations. Although adaptations exist—such as shifting all values by adding the of the minimum element to map them to a non-negative range—this approach deviates from the standard and can inflate the effective range k, thereby reducing efficiency in both time and space when the input span is large.

The Algorithm

Counting sort assumes the input consists of non-negative integers within a known range [0, k]. The following pseudocode describes the stable version of the algorithm, using zero-based indexing for arrays. It operates on an input A of length n, producing a sorted output B of the same length, with a count C of size k+1.
procedure countingSort(A[0..n-1], B[0..n-1], k)
    C ← array of size (k + 1), initialized to 0  // Count occurrences of each value
    for i ← 0 to n-1 do
        C[A[i]] ← C[A[i]] + 1  // Increment count for A[i]
    for j ← 1 to k do
        C[j] ← C[j] + C[j-1]  // Compute cumulative counts for placement positions
    for i ← n-1 downto 0 do
        B[C[A[i]] - 1] ← A[i]  // Place A[i] at the correct position in B
        C[A[i]] ← C[A[i]] - 1  // Decrement the count to handle multiples
This initializes the count array C to zeros, which tracks the of each possible value in the [0, k]. The first increments C by 1 for each occurrence of value j in A, building the . The second transforms C into a cumulative sum array, where C now represents the number of elements less than or equal to j, providing the ending position for placing elements of value j in the sorted output. The third iterates backward through A to ensure stability—preserving the relative order of equal elements—by placing each A at position C[A] - 1 in B and then decrementing C[A] to adjust for subsequent identical elements.

Step-by-Step Execution

To illustrate the execution of counting sort, consider an input A of length n = 8 containing integers in the range $0 to k = 5: A = [2, 5, 3, 0, 2, 3, 0, 3]. This example follows the standard implementation of the algorithm as described in introductory algorithms texts. The process begins by initializing a count C of size k+1 = 6 (indices 0 to 5) to all zeros. Then, for each element in A, the corresponding entry in C is incremented to record the frequency of each value:
Value012345
Count202301
Next, the count is transformed into a cumulative count by setting C = C + C[i-1] for i = 1 to k, where C{{grok:render&&&type=render_inline_citation&&&citation_id=0&&&citation_type=wikipedia}} remains unchanged. This step computes the starting position in the output for each , ensuring appear in non-decreasing order:
Value012345
Cumulative224778
An output array B of size n is then initialized (typically to empty or a placeholder). To produce a sort, the input array is scanned from right to left. For each element A, it is placed at position C[A] - 1 in B, and C[A] is decremented. This backward pass preserves the relative order of equal elements. The placements proceed as follows:
  • For A{{grok:render&&&type=render_inline_citation&&&citation_id=7&&&citation_type=wikipedia}} = 3, place 3 at position 6 in B, decrement C{{grok:render&&&type=render_inline_citation&&&citation_id=3&&&citation_type=wikipedia}} to 6.
  • For A{{grok:render&&&type=render_inline_citation&&&citation_id=6&&&citation_type=wikipedia}} = 0, place 0 at position 1 in B, decrement C{{grok:render&&&type=render_inline_citation&&&citation_id=0&&&citation_type=wikipedia}} to 1.
  • For A{{grok:render&&&type=render_inline_citation&&&citation_id=5&&&citation_type=wikipedia}} = 3, place 3 at position 5 in B, decrement C{{grok:render&&&type=render_inline_citation&&&citation_id=3&&&citation_type=wikipedia}} to 5.
  • For A{{grok:render&&&type=render_inline_citation&&&citation_id=4&&&citation_type=wikipedia}} = 2, place 2 at position 3 in B, decrement C{{grok:render&&&type=render_inline_citation&&&citation_id=2&&&citation_type=wikipedia}} to 3.
  • For A{{grok:render&&&type=render_inline_citation&&&citation_id=3&&&citation_type=wikipedia}} = 0, place 0 at position 0 in B, decrement C{{grok:render&&&type=render_inline_citation&&&citation_id=0&&&citation_type=wikipedia}} to 0.
  • For A{{grok:render&&&type=render_inline_citation&&&citation_id=2&&&citation_type=wikipedia}} = 3, place 3 at position 4 in B, decrement C{{grok:render&&&type=render_inline_citation&&&citation_id=3&&&citation_type=wikipedia}} to 4.
  • For A{{grok:render&&&type=render_inline_citation&&&citation_id=1&&&citation_type=wikipedia}} = 5, place 5 at position 7 in B, decrement C{{grok:render&&&type=render_inline_citation&&&citation_id=5&&&citation_type=wikipedia}} to 7.
  • For A{{grok:render&&&type=render_inline_citation&&&citation_id=0&&&citation_type=wikipedia}} = 2, place 2 at position 2 in B, decrement C{{grok:render&&&type=render_inline_citation&&&citation_id=2&&&citation_type=wikipedia}} to 2.
The final output array is B = [0, 0, 2, 2, 3, 3, 3, 5]. Throughout this execution, positions for elements in the output are determined directly from the precomputed counts and cumulative sums, without any direct comparisons between input values.

Analysis

Time Complexity

The time complexity of counting sort is O(n + k), where n is the length of the input and k is the number of possible values (i.e., one more than the difference between the possible values in the input). This bound holds regardless of the input distribution, as the algorithm performs a fixed set of operations independent of the specific arrangement of elements. The analysis breaks down as follows: the initial counting phase iterates over the n input elements exactly once to tally occurrences in the auxiliary array, requiring O(n) time; the cumulative sum phase (or prefix sum computation for stable placement) iterates over the k possible values in the auxiliary array, requiring O(k) time; and the output phase iterates over the n input elements once more to construct the sorted array, again requiring O(n) time. Initialization of the auxiliary array also takes O(k) time, which is subsumed in the overall O(k) term. More precisely, the exact running time can be expressed as T(n, k) = n + k + o(1), reflecting the linear traversal costs with lower-order terms for overhead. When k = O(n), this simplifies to linear time O(n), making counting sort particularly efficient for inputs with bounded integer keys. As a non-comparison-based sorting algorithm, counting sort avoids the \Omega(n \log n) lower bound that applies to comparison sorts, enabling its linear performance in suitable scenarios.

Space Complexity

The of counting sort is O(n + k), where n is the number of elements to sort and k is the of input values (specifically, the difference between the maximum and minimum keys plus one). This arises primarily from the count array, which requires O(k) space to tally frequencies of each possible key value, and the output array, which needs O(n) space to build the sorted result without overwriting the input. More precisely, the total auxiliary space is given by S(n, k) = n + k + o(1), where the o(1) term captures minor overhead from temporary variables and indices. A key trade-off occurs when k \gg n, as the space then scales with k, rendering counting sort inefficient or infeasible for datasets with expansive key ranges, such as when keys span up to n^3 or more.

Variants

Stable Variant

A stable sorting algorithm preserves the relative order of records with equal keys as they appear in the sorted output compared to the input. The standard implementation of counting sort fills the output array by traversing the input from beginning to end using cumulative counts, which places earlier occurrences of equal keys toward the end of their group in the output, thereby reversing their relative order and making the sort unstable. To ensure stability, the algorithm is modified to traverse the input array in reverse order during the placement phase, assigning positions such that earlier input elements with equal keys receive lower indices in the output. This reverse traversal works because the cumulative count array tracks the rightmost available position for each key initially; processing later input elements first places them at higher indices within the key group, leaving lower indices for earlier elements encountered subsequently. The pseudocode for the stable variant, adapted to zero-based indexing, highlights the backward loop:
COUNTING-SORT(A, B, k)
1  let [count](/page/Count)[0..k] be a new array
2  for i ← 0 to k
3      [count](/page/Count)[i] ← 0
4  for j ← 0 to n - 1
5      [count](/page/Count)[A[j]] ← [count](/page/Count)[A[j]] + 1
6  for i ← 1 to k
7      [count](/page/Count)[i] ← [count](/page/Count)[i] + [count](/page/Count)[i - 1]
8  for j ← n - 1 downto 0
9      B[[count](/page/Count)[A[j]] - 1] ← A[j]
10     [count](/page/Count)[A[j]] ← [count](/page/Count)[A[j]] - 1
The loop at lines 8–10 iterates backward over the input, decrementing the count after each placement to fill positions from right to left within equal-key groups.

Generalized Variant

Counting sort can be generalized to sort objects with arbitrary keys by first mapping those keys to a of non-negative integers, enabling the use of the standard counting mechanism on the mapped values. This mapping ensures a correspondence between the original keys and integers within a feasible [0, k], where k is the number of distinct keys or buckets. A common application of this generalized form is as a stable subroutine in , where counting sort processes individual digits or characters of the keys in multiple passes to achieve overall of larger integers or strings. Each pass treats the digit positions as small integer keys, mapping them directly to counts without needing additional hashing. To handle negative integers, which fall outside the non-negative assumption of basic counting sort, an offset is applied by adding the of the minimum element to all keys, shifting the range to start at zero. For example, given keys {-3, -1, 0, 2}, the minimum is -3, so add 3 to each: {0, 2, 3, 5}; after counting and placement, subtract 3 during output to restore originals. This preserves the linear as long as the shifted range remains manageable. For floating-point numbers, counting sort is adapted by bucketing the values into ranges, such as by or to map continuous values to a of representing intervals (e.g., dividing the [min, max] into k equal buckets and assigning each to its bucket index). This transforms the problem into counting, though it introduces approximation if exact ordering within buckets is needed, often requiring a secondary sort on those buckets.

Applications and Limitations

Applications

Counting sort plays a crucial role in , particularly for sorting multi-digit numbers, where it serves as the stable subroutine applied to each digit position to achieve overall linear time sorting for fixed-length keys. The algorithm is well-suited for sorting data with small fixed ranges, such as student grades from 0 to 100, enabling efficient organization of educational records without comparison overhead. Similarly, in image processing, counting sort is suitable for sorting intensities from 0 to 255, as these values lie within a small discrete range ideal for linear-time sorting methods. As a preprocessing step in data structures, counting sort computes frequency distributions, which is essential for generation and subsequent analysis, such as in statistical or data summarization where the count directly represents occurrence tallies for values.

Limitations

Counting sort is fundamentally limited to sorting integers within a known, bounded [0, k], rendering it inapplicable to continuous types such as real numbers or unbounded domains where the cannot be predefined. This restriction arises because the algorithm relies on indexing to count occurrences of each possible value, which is infeasible for non- or sets. When the range k significantly exceeds the input size n (i.e., k >> n), counting sort suffers from excessive space usage due to the O(k) count array, leading to substantial memory waste for sparse or widely distributed keys. This space explosion makes the algorithm impractical in such scenarios, as the auxiliary storage requirements can dominate practical implementations. Additionally, counting sort is not an in its standard form, necessitating O(n + k) extra memory for the count and output arrays, which contrasts with space-efficient alternatives for general-purpose sorting. For general cases without the integer-range assumption, comparison-based algorithms like or mergesort are preferable, as they handle arbitrary data types and orders without proportional space overhead to the key range.

Historical Development

Origins

Counting sort was invented by Harold H. Seward in 1954 while he was a graduate student at the (). Seward first described the algorithm in his master's thesis titled Information Sorting in the Application of Electronic Digital Computers to Business Operations, published as MIT Digital Computer Laboratory Report R-232 in May 1954. In this work, he presented counting sort—referred to as a "floating digital sort"—as an efficient method for internal of represented by decimal digits, particularly suited for the constraints of early computers. The development occurred during the early computing era, when data processing in business applications relied heavily on punched card systems, such as those from , which processed cards at rates like 450 per minute per digit using electric brushes to detect punched holes. Seward's algorithm addressed the need for streamlined sorting on limited hardware, including magnetic tape units and the computer project at , by minimizing passes over the data and leveraging direct frequency-based distribution rather than comparisons. Preceding mechanical techniques, such as manual "Keysort" cards that used sorting with needles to separate punched cards by holes, also informed the digit-by-digit central to the algorithm.

Significance

Counting sort represents a pioneering example of non-comparative algorithms, achieving linear O(n + k) under the assumption of a limited range of input values, which challenges the Ω(n log n) lower bound for general comparison-based sorts and has influenced the development of other linear-time techniques. As a foundational building block, counting sort serves as a key subroutine in more advanced algorithms like and , enabling efficient handling of larger or distributed datasets by breaking down into digit-by-digit or bucket-level operations. In educational contexts, counting sort plays a crucial role in illustrating design trade-offs, such as the balance between time efficiency and space requirements, as well as the impact of input assumptions on performance, making it a staple in curricula for demonstrating non-comparison-based methods and in . Its modern relevance persists in big data environments, where it supports distributed sorting for data with known distributions, such as through radix sort variants in MapReduce frameworks for partitioning and processing large-scale integer keys efficiently.

References

  1. [1]
    [PDF] Counting Sort - csail
    Counting sort is an algorithm that takes an array A of n elements in the range {1, 2, ..., k} and sorts the array in O(n + k) time.
  2. [2]
    [PDF] 1 Lower bound on runtime of comparison sorts
    Input: Counting sort is a sorting algorithm that relies on the values in the input array. Specifically, it assumes that the inputs are integers in the range 0 ...<|control11|><|separator|>
  3. [3]
    [PDF] WHIRLWIND
    INFORMATION SORTING IN THE APPLICATION OF ELECTRONIC. DIGITAL COMPUTERS TO BUSINESS OPERATIONS by. HAROLD H. SEWARD. DIGITAL COMPUTER LABORATORY. MASSACHUSETTS ...
  4. [4]
    [PDF] Counting sort - CS@Cornell
    It is called counting sort because it counts (and then uses) the number of times each value occurs in c. Here is the difference between pigeonhole sort and ...
  5. [5]
    [PDF] Design and Analysis of Algorithms Lecture 7 Leonidas Guibas
    Assumption: input is n numbers in the range. 1..k. Basic idea: Count number of ... Use a stable sort (like counting sort) for each stage. Each pass over n ...
  6. [6]
    [PDF] David - CS 4102: Algorithms
    Oct 1, 2019 · Assumption: Small number of unique values. Idea: Count how many ... Why not always use counting sort? For 64-bit numbers, requires an ...
  7. [7]
    Counting Sort - GeeksforGeeks
    Sep 29, 2025 · Counting Sort is a non-comparison-based sorting algorithm. It is particularly efficient when the range of input values is small compared to the number of ...
  8. [8]
    [PDF] Ranking Ranking
    'Beat' the Lower Bound. Linear-Time Sorting Algorithms: Counting. Sort. • Assumptions. – Each of the n input elements is an integer in the range.
  9. [9]
  10. [10]
    [PDF] CountingSort - CMSC 351 - UMD MATH
    Our particular pseudocode implementation of CountingSort is stable. CountingSort is not in-place. CountingSort can be modified to manage other types of data.
  11. [11]
    8.2 Counting sort - CLRS Solutions
    ### Summary of Counting Sort from https://walkccc.me/CLRS/Chap08/8.2/
  12. [12]
    [PDF] CSE 502 Class 15
    Counting sort is a correct Θ(n) sort. • How is this possible? • Must not fit ... • However, it cannot sort in place – CountingSort needs extra mem- ory.
  13. [13]
    [PDF] 6.006- Introduction to Algorithms - csail
    Counting-sort example. A: 4 1 3 4 3. B: 1. 2. 3. 4. 5. C: 1. 2. 3. 4 one index for each possible key stored in A. Page 14. Loop 1: initialization. A: 4 1 3 4 3.Missing: cormen | Show results with:cormen
  14. [14]
    An Efficient Generalization of Counting Sort for Large, possibly ...
    Dec 4, 2019 · Counting sort is a well-known algorithm that sorts objects of any kind mapped to integer keys, or else to keys in one-to-one correspondence ...
  15. [15]
    Radix Sort | Brilliant Math & Science Wiki
    Radix sort uses counting sort as a subroutine to sort an array of numbers. Because integers can be used to represent strings (by hashing the strings to integers) ...
  16. [16]
    11.2 Counting Sort and Radix Sort - Open Data Structures
    In this section we consider two sorting algorithms that are not comparison-based. These algorithms are specialized for sorting small integers.
  17. [17]
    Counting Sort – Algorithm, Source Code, Time Complexity
    Rating 5.0 (20) Sep 2, 2020 · Counting Sort is a very efficient, stable sorting algorithm with a time and space complexity of O(n + k).Missing: forward unstable<|control11|><|separator|>
  18. [18]
    Bucket Sort - GeeksforGeeks
    Sep 30, 2025 · Bucket sort is a sorting technique that involves dividing elements into various groups, or buckets. These buckets are formed by uniformly distributing the ...
  19. [19]
    [PDF] Sorting Lower Bounds, Counting Sort, and Radix Sort - CS 161
    Radix Sort is another non-comparison-based sorting algorithm that will use Counting Sort as a subroutine. Assuming that the input array contains d-digit numbers ...
  20. [20]
    [PDF] 9 Counting - Computer Science
    Apr 5, 2021 · shows one, called counting sort, which allows us to sort without comparing elements to each other. As long as the elements of the array are ...
  21. [21]
    [PDF] Computing the Nearest Neighbor Transform Exactly with only ...
    We can create this ordered list easily from pixels in a given image in O(U2) time and O(n) additional space, or from an unordered list by counting sort in O(n + ...
  22. [22]
    histogram sort
    A histogram sort sets up buckets of exactly the right size in a first pass. A counting sort is a histogram sort with one bucket per possible key value. The ...<|separator|>
  23. [23]
    [PDF] Counting, Sorting and Distributed Coordination - Luis Galárraga
    Feb 6, 2010 · The algorithm has three steps: 1. Threads choose p−1 splitter keys to partition the data set into p buckets. The splitters are implemented, in ...
  24. [24]
    [PDF] Introduction to Algorithms, Third Edition
    Introduction to algorithms / Thomas H. Cormen . . . [et al.].—3rd ed. p. cm. Includes bibliographical references and index.
  25. [25]
    [PDF] Counting Sort, HashTable CISC4080 CIS, Fordham Univ.
    CountingSort (L[0…n-1], k) !22. Which sorting algorithm to use,. Selection sort or counting sort? * to sort a list of 100 employees by their SSN. Page 23. Radix ...
  26. [26]
    [PDF] Bibliography 26. Computer Sorting - People | MIT CSAIL
    SEWARD, HAROLD H. Information sorting in the application of electronic digital computers to business operations. Master's. Thesis, Rep. R-232, MIT Digital ...
  27. [27]
    Evaluation of sorting methods - ACM Digital Library
    I have been asked to report to you on the present state of the art of sorting. In order to do so, I have obtained help and information from more people than ...<|control11|><|separator|>
  28. [28]
    Counting Sort: A Linear Time Sorting Algorithm – AlgoCademy Blog
    Counting Sort is a non-comparison-based sorting algorithm that works efficiently when dealing with a limited range of input values.
  29. [29]
    Counting Sort vs. Bucket Sort vs. Radix Sort - Algorithms - Baeldung
    Mar 18, 2024 · Counting sort is simple and straightforward and is used as a subroutine for Radix sort. Bucket sort is an interesting algorithm but has the ...2. Counting Sort · 3. Bucket Sort · 4. Radix Sort
  30. [30]
    Counting Sort Algorithm - Scaler Topics
    Mar 6, 2024 · The Space Complexity is O(N+M), accounting for the space used by the output array and the count array. Applications of Counting Sort Algorithm.
  31. [31]
    Distributed Sorting Algorithms - Bruno Magalhaes
    Jun 21, 2014 · counting sort: highly efficient for integer values distributed across a small range of values. Navigates the list of unsorted elements once and ...Missing: partitioning | Show results with:partitioning