algorithm - Very basic radix sort -
i wrote simple iterative radix sort , i'm wondering if have right idea.
recursive implementations seem more common.
i sorting 4-byte integers (unsigned keep simple).
using 1-byte 'digit'. have 2^8=256 buckets.
sorting significant digit (msd) first.
after each sort put them array in order exist in buckets , perform next sort.
end doing 4 bucket sorts.
seems work small set of data. since doing msd i'm guessing that's not stable , may fail different data.
did miss major?
#include <iostream> #include <vector> #include <list> using namespace std; void radix(vector<unsigned>&); void print(const vector<list<unsigned> >& listbuckets); unsigned getmaxforbytes(unsigned bytes); void merge(vector<unsigned>& data, vector<list<unsigned> >& listbuckets); int main() { unsigned d[] = {5,3,6,9,2,11,9, 65534, 4,10,17,13, 268435455, 4294967294,4294967293, 268435454,65537}; vector<unsigned> v(d,d+17); radix(v); return 0; } void radix(vector<unsigned>& data) { int bytes = 1; // how many bytes compare @ time unsigned numofbuckets = getmaxforbytes(bytes) + 1; cout << "numbuckets" << numofbuckets << endl; int chunks = sizeof(unsigned) / bytes; for(int = chunks - 1; >= 0; --i) { vector<list<unsigned> > buckets; // lazy, wasteful allocation buckets.resize(numofbuckets); unsigned mask = getmaxforbytes(bytes); unsigned shift = * bytes * 8; mask = mask << shift; for(unsigned j = 0; j < data.size(); ++j) { unsigned bucket = data[j] & mask; // isolate bits of current chunk bucket = bucket >> shift; // bring bits down least significant buckets[bucket].push_back(data[j]); } print(buckets); merge(data,buckets); } } unsigned getmaxforbytes(unsigned bytes) { unsigned max = 0; for(unsigned = 1; <= bytes; ++i) { max = max << 8; max |= 0xff; } return max; } void merge(vector<unsigned>& data, vector<list<unsigned> >& listbuckets) { int index = 0; for(unsigned = 0; < listbuckets.size(); ++i) { list<unsigned>& list = listbuckets[i]; std::list<unsigned>::const_iterator = list.begin(); for(; != list.end(); ++it) { data[index] = *it; ++index; } } } void print(const vector<list<unsigned> >& listbuckets) { cout << "printing listbuckets: " << endl; for(unsigned = 0; < listbuckets.size(); ++i) { const list<unsigned>& list = listbuckets[i]; if(list.size() == 0) continue; std::list<unsigned>::const_iterator = list.begin(); // why need std here!? for(; != list.end(); ++it) { cout << *it << ", "; } cout << endl; } }
update:
seems work in lsd form can modified changing the chunk loop in radix follows:
for(int = chunks - 1; >= 0; --i)
let's @ en example two-digit decimal numbers:
49, 25, 19, 27, 87, 67, 22, 90, 47, 91
sorting first digit yields
19, 25, 27, 22, 49, 47, 67, 87, 90, 91
next, sort second digit, yielding
90, 91, 22, 25, 27, 47, 67, 87, 19, 49
seems wrong, doesn't it? or isn't doing? maybe can show code if got wrong.
if doing second bucket sort on groups same first digit(s), algorithm equivalent recursive version. stable well. difference you'd bucket sorts breadth-first instead of depth-first.
Comments
Post a Comment