Sort values by mapping them to a dense rank space and ordering by compressed indices.
Coordinate compression sort maps arbitrary values to a dense integer range based on their sorted order, then sorts using these compact indices. It is useful when values are large, sparse, or not directly suitable for counting or radix methods.
Problem
Given an array of values, possibly large integers or non-integer comparable items, sort the array efficiently by reducing the value domain.
Idea
Replace each value with its rank in the sorted order of distinct values.
Let:
Define mapping:
Then:
- map each value to its rank
- sort by ranks
- optionally map back to original values
Algorithm
coordinate_compression_sort(A):
V = sorted unique values of A
create map from value to index
B = array of size n
for i from 0 to n-1:
B[i] = map[A[i]]
sort B
for i from 0 to n-1:
A[i] = V[B[i]]
return AExample
Let:
Unique sorted values:
Mapping:
| value | rank |
|---|---|
| 1000 | 0 |
| 2000 | 1 |
| 5000 | 2 |
Mapped array:
Sorted:
Mapped back:
Correctness
The mapping preserves order:
Thus sorting compressed values yields the correct order of original values.
Complexity
Let:
- be number of elements
- be number of distinct values
Time:
- building :
- mapping:
- sorting compressed array:
Total:
If combined with counting or radix sort after compression:
Space:
Properties
| property | value |
|---|---|
| stable | depends on underlying sort |
| in place | no |
| comparison based | partly |
| handles large values | yes |
When to Use
Use coordinate compression when:
- values are large or sparse
- you want to apply counting or radix sort afterward
- relative ordering matters but exact values are not needed during sorting
Avoid when:
- values are already small integers
- direct sorting is simpler
Implementation
def coordinate_compression_sort(a):
if not a:
return a
vals = sorted(set(a))
rank = {v: i for i, v in enumerate(vals)}
comp = [rank[x] for x in a]
comp.sort()
return [vals[i] for i in comp]