/*
* Radix sort
* We can use a bitset to represent positive or negative number to accelarate the algorithm
*/
#include <iostream>
#include <vector>
#include <assert.h>
using namespace std;
typedef vector <int> Vector;
static int digits(Vector &);
static void scatter(Vector &,vector<Vector> &,int );
static void gather(Vector &,vector <Vector> &);
static void clearBucket(vector <Vector>&);
static void radix(Vector & );
int main(void)
{
vector <int> array;
array.push_back(12);
array.push_back(124);
array.push_back(24);
array.push_back(5);
array.push_back(343);
array.push_back(35);
array.push_back(134);
array.push_back(INT_MAX);
array.push_back(-23);
for(size_t i=0;i<array.size();i++)
cout<<array[i]<<" ";
cout<<endl;
radix(array);
for(size_t i=0;i<array.size();i++)
cout<<array[i]<<" ";
cout<<endl;
return 0;
}
/*
* Get the largest digits
*/
static int digits(Vector & a)
{
assert(a.size()>0);
int d=0,largest=a[0];
for(size_t i=1;i<a.size();i++)
if(a[i]>=0 && a[i]>largest)
largest=a[i];
else if(a[i]<0 && (-a[i])>largest)
largest=-a[i];
while(largest){
++d;
largest/=10;
}
return d;
}
/*
* Scatter numbers in buckets
*/
static void scatter(Vector &a,vector<Vector> & bucket,int digit)
{
int id,div=1;
for(int i=0;i<digit;i++)
div*=10;
for(size_t j=0;j<a.size();j++){
if(a[j]>=0){
id=(a[j]%div-a[j]%(div/10)) / (div/10)+10;
bucket[id].push_back(a[j]);
}
else{
a[j]=-a[j];
id=(a[j]%div-a[j]%(div/10)) / (div/10);
a[j]=-a[j];
bucket[id].push_back(a[j]);
}
}
}
/*
* Gather numbers from buckets
*/
static void gather(Vector &a,vector<Vector>&bucket)
{
int i,j,index,temp;
for(i=0,index=-1;i<10;i++)
for(j=0;j<bucket[i].size();j++)
a[++index]=bucket[i][j];
for(i=0,j=index;i<j;i++,j--){
temp=a[i];
a[i]=a[j];
a[j]=temp;
}
for(i=10;i<20;i++)
for(j=0;j<bucket[i].size();j++)
a[++index]=bucket[i][j];
}
/*
* Clear bucket
*/
static void clearBucket(vector <Vector> &bucket)
{
for(int i=0;i<20;i++)
bucket[i].clear();
}
/*
* Radix Sort
*/
static void radix(Vector & a)
{
int d=digits(a);
Vector temp;
vector <Vector>bucket(20,temp);
for(int i=1;i<=d;i++){
scatter(a,bucket,i);
gather(a,bucket);
if(i!=d)
clearBucket(bucket);
}
}