In this section we consider two sorting algorithms that are not
comparison-based. These algorithms are specialized for sorting
small integers.
These algorithms get around the lower-bounds of
Theorem 11.5 by using (parts of) the
elements of 
 as indices into an array.  Consider a statement of
the form
Suppose we have an input array 
 consisting of 
 integers, each in
the range 
.  The counting-sort algorithm sorts 
using an auxiliary array 
 of counters.  It outputs a sorted version
of 
 as an auxiliary array 
.
The idea behind counting-sort is simple:  For each
, count the number of occurrences of 
 in 
and store this in 
.  Now, after sorting, the output will look like
 occurrences of 0, followed by 
 occurrences of 1, followed by
 occurrences of 2,..., followed by 
 occurrences of 
.
The code that does this is very slick, and its execution is illustrated in
Figure 11.7:
void countingSort(array<int> &a, int k) {
  array<int> c(k, 0);
  for (int i = 0; i < a.length; i++)
    c[a[i]]++;
  for (int i = 1; i < k; i++)
    c[i] += c[i-1];
  array<int> b(a.length);
  for (int i = a.length-1; i >= 0; i--)
    b[--c[a[i]]] = a[i];
  a = b;
}
The first 
 loop in this code sets each counter 
 so that it
counts the number of occurrences of 
 in 
.  By using the values
of 
 as indices, these counters can all be computed in 
 time
with a single for loop.  At this point, we could use 
 to
fill in the output array 
 directly. However, this would not work if
the elements of 
 have associated data.  Therefore we spend a little
extra effort to copy the elements of 
 into 
.
The next 
 loop, which takes 
 time, computes a running-sum
of the counters so that 
 becomes the number of elements in
 that are less than or equal to 
.  In particular, for every
, the output array, 
, will have
The counting-sort algorithm has the nice property of being stable;
it preserves the relative order of elements that are equal.  If two
elements 
 and 
 have the same value, and 
 then
 will appear before 
 in 
.  This will be useful in the
next section.
Counting-sort is very efficient for sorting an array of integers when the
length, 
, of the array is not much smaller than the maximum value,
, that appears in the array.  The radix-sort algorithm,
which we now describe, uses several passes of counting-sort to allow
for a much greater range of maximum values.
Radix-sort sorts 
-bit integers by using 
 passes of counting-sort
to sort these integers 
 bits at a time.2  More precisely, radix sort first sorts the integers by
their least significant 
 bits, then their next significant 
 bits,
and so on until, in the last pass, the integers are sorted by their most
significant 
 bits.
void radixSort(array<int> &a) {
  int d = 8, w = 32;
  for (int p = 0; p < w/d; p++) {
    array<int> c(1<<d, 0);
    // the next three for loops implement counting-sort
    array<int> b(a.length);
    for (int i = 0; i < a.length; i++)
      c[(a[i] >> d*p)&((1<<d)-1)]++;
    for (int i = 1; i < 1<<d; i++)
      c[i] += c[i-1];
    for (int i = a.length-1; i >= 0; i--)
      b[--c[(a[i] >> d*p)&((1<<d)-1)]] = a[i];
    a = b;
  }
}
(In this code, the expression 
 
  
 | 
This remarkable algorithm sorts correctly because counting-sort is
a stable sorting algorithm.  If 
 are two elements of 
and the most significant bit at which 
 differs from 
 has index 
,
then 
 will be placed before 
 during pass 
and subsequent passes will not change the relative order of 
 and 
.
Radix-sort performs 
 passes of counting-sort.  Each pass requires
 time. Therefore, the performance of radix-sort is given
by the following theorem.
If we think, instead, of the elements of the array being in the range
, and take 
 we obtain
the following version of Theorem 11.8.