Counting Sort Non-comparison sort. Precondition: n numbers in the range 1..k. Key ideas: For each x count the number C(x) of elements ≤ x Insert x at output position C(x) and decrement C(x).
An Example A[1..n] C for i = 2 to 7 do C[i] = C[i] + C[i–1] Input C[1..k] Auxiliary storage k two 1’s in A 6 elements ≤ 3
Example (continued) C C B[6] = B[C[3]] = B[C[A[11]]] = A[11] = 3 C[A[11]] = C[A[11]] – 1 A[1..n] B[1..n] Output 3
Example (cont’d) B C C B[C[A[10]]] = A[10] = 4 C[A[10]] = C[A[10]] – 1 43
Example (cont’d) B C C B[C[A[6]]] = A[6] = 4 C[A[6]] = C[A[6]] – 1
Analysis of Counting Sort Counting-Sort(A, B, k) for i = 1 to k do C[i] = 0// (k) for j = 1 to length[A] do C[A[j]] = C[A[j]] + 1 // (n) // C[i] now contains the number of elements = i for i = 2 to k do C[i] = C[i] + C[i–1]// (k) // C[i] now contains the number of elements ≤ i for j = length[A] downto 1 do B[C[A[j]]] = A[j] C[A[j]] = C[A[j]] – 1// (n) Running time is (n+k) (or (n) if k = O(n))!
Stability Counting sort is stable: Input order maintained among items with equal keys. Stability is important because data are often carried with the keys being sorted. radix sort (which uses counting sort as a subroutine) relies on it to work correctly. for j = length[A] downto 1 do B[C[A[j]]] = A[j] C[A[j]] = C[A[j]] – 1 How is stability realized?
Radix Sort Sort a set of numbers in multiple passes, starting from the rightmost digit, then the 10’s digit, then the 100’s digit, etc. Example: sort 23, 45, 7, 56, 20, 19, 88, 77, 61, 13, 52, 39, 80, 2, Pass 1: Pass 2:
Analysis of Radix Sort Sort n d-digit numbers. Let k be the range of each digit. Each pass takes time (n+k). // use counting sort There are d passes in total. The running time for radix sort is (dn+dk). Linear running time when d is a constant and k = O(n). Correctness follows by induction on the number of passes.
Breaking into Digits …… b bits r-bit digit Each digit in the range – 1 r b/r passes, each spending time (n+2 ). r Running time ((b/r) (n + 2 )). r b/r digits If b ≤ lg n, choose r = b (n) If b > lg n, choose r = lg n (bn/lg n) Key:
Bucket Sort Assumption: input elements are uniformly distributed over [0, 1) In case the input range is larger than 1, normalize each element over the maximum first. n buckets are used for n input numbers. Insert A[i] into bucket nA[i] , 1 i n. Bucket sort runs in (n) expected time.
An Example Step 2: Concatenate all lists Step 1: equivalent of insertion sort within each list n inputs dropped into n equal-sized subintervals of [0, 1) A[ ]
Comparison of Sorting Methods (II) Method Space Average Max n=16 n=10000 Counting sort 2n 22n n Radix sort n + (n+200) 32n 32n Bucket sort n + (n+100).0175n + 18n 3.5n D. E. Knuth, “The Art of Computer Programming”, Vol 3, 2 nd ed., p.382, Implemented on the MIX Computer.
Comparison of Sorting Algorithms Insertion sort: suitable only for small n. Merge sort: guaranteed to be fast even in its worst case; stable. Heapsort: requiring minimum memory and guaranteed to run fast; average and maximum time both roughly twice the average time of quicksort. Quicksort: most useful general-purpose sorting for very little memory requirement and fastest average time. (choose the median of three elements as pivot in practice :-) Counting sort: very useful when the keys have small range; stable; memory space for counters and for 2n records. Radix sort: appropriate for keys either rather short or with a lexicographic collating sequence. Bucket sort: assuming keys to have uniform distribution.