Totally untested C++ code
#include <array>
#include <vector>
#include <algorithm>
#include <numeric>
void counting_sort(std::vector<uint8_t>& values) {
std::array<uint8_t , 256> count;
for(auto& value : values)
count[value]++; // count
std::partial_sum(count.begin(), count.end(), count.begin()); // sum
std::array<uint8_t , 256> position;
position[0] = 0; // first position of first value
std::copy_n(count.begin(), count.size()-1, std::next(position.begin())); // moved by one
int pos = 0;
while (pos < count.size()) {
while (count[pos] > position[pos]) {
auto& from = position[pos]; // current position
auto& to = position[values[from]]; // final position
if (to != from)
std::swap(values[from], // from current position
values[to]); // where the value needs to go
to++; // update destination position
}
pos++;
}
}
In the while with the swap you keep swapping until the value that should be place in the first position is swapped into that position.
0 // pos
[3,2,1] // values
[0,1,1,1] // count
[_0_,1,2,3] // count
[_0_,0,1,2] // position
1 // pos
[0,_1_,2,3] // count
[0,_0_,1,2] // position
values[position[pos]] -> 3
position[3] -> 2
position[pos] -> 0
[_3_,2,_1_]
swap
[1,2,3]
position[values[pos]]++
[0,0,1,_2_] // position
[0,0,1,_3_] // position
1 // pos
[0,_1_,2,3] // count
[0,_0_,1,3] // position
values[position[pos]] -> 1
position[1] -> 0
position[pos] -> 0
positions are the same so update to
[0,_0_,1,3] // position
[0,_1_,1,3] // position
[0,_1_,2,3] // count
[0,_1_,1,3] // position
update pos
pos = 2
[0,1,_2_,3] // count
[0,1,_1_,3] // position
positions are the same to update to
[0,1,_1_,3] // position
[0,1,_2_,3] // position
count&position are the same so update pos
pos = 3
count&position are the same so update pos
pos = 4
done