Extend counting sort to handle negative integers by shifting keys into a nonnegative index range.
Counting sort normally assumes keys lie in a nonnegative range. This variant handles negative integers by shifting all values so that the minimum becomes zero, then applying standard counting sort.
Problem
Given an array of integers that may include negative values, sort the array.
Let:
Idea
Shift every value by so all keys become nonnegative:
Then apply counting sort on in range , and map back if needed.
Algorithm
counting_sort_with_negatives(A):
lo = minimum(A)
hi = maximum(A)
k = hi - lo + 1
count = [0] * k
for x in A:
count[x - lo] += 1
i = 0
for v from 0 to k - 1:
while count[v] > 0:
A[i] = v + lo
i += 1
count[v] -= 1
return AExample
Let:
Shift:
Mapped values:
After sorting and shifting back:
Correctness
The transformation is a bijection between the original values and the shifted values. It preserves order:
Counting sort correctly orders the shifted values, so mapping back yields the correct sorted order of the original values.
Complexity
Let:
- be the number of elements
- be the range size
Time:
Space:
Properties
| property | value |
|---|---|
| stable | yes, if using stable variant |
| in place | no |
| comparison based | no |
| supports negatives | yes |
When to Use
Use this variant when:
- keys include negative integers
- the value range is small
- linear-time sorting is desired
Avoid when the range is large compared to , since memory usage becomes inefficient.
Implementation
def counting_sort_with_negatives(a):
if not a:
return a
lo = min(a)
hi = max(a)
k = hi - lo + 1
count = [0] * k
for x in a:
count[x - lo] += 1
i = 0
for v in range(k):
while count[v] > 0:
a[i] = v + lo
i += 1
count[v] -= 1
return a