Skip to content

Commit

Permalink
Added Sorting
Browse files Browse the repository at this point in the history
  • Loading branch information
Daniel Wallin committed Jun 24, 2011
0 parents commit d9fd661
Show file tree
Hide file tree
Showing 9 changed files with 522 additions and 0 deletions.
Binary file added AsmSort.zip
Binary file not shown.
176 changes: 176 additions & 0 deletions MultiKey Quicksort Example.cpp
@@ -0,0 +1,176 @@
// SortingLib.cpp : Defines the entry point for the DLL application.
//
#include <iostream>
#include <deque>
namespace boost
{
namespace detail
{
template<typename T, typename Holder>
class qobjclass //I use a class because only class templates can be partially specialized
{
public:
inline static const T& qobj(typename const Holder& a, int d)
{
return a[d];
}
};
template<typename T>
class qobjclass<T, typename std::deque<T>::iterator>//I use a class because only class templates can be partially specialized
{
public:
inline static const T& qobj(typename const std::deque<T>::iterator& a, int d)
{
return *(a + d);
}
};
//I need all of these special functions because I cannot do partial specializations for function templates, but I need the simulate it
template<typename T>
inline T& _get(typename T* a, int d)
{
return a[d];
}
template<typename T>
inline T& _get(typename std::deque<T>::iterator& a, int d)
{
return *(a + d);
}
#define qobj(a, b) qobjclass<KeyHolds, Key>::qobj((a), (b))
#define get(a, b) _get<Key>((a), (b))
template<typename KeyHolds, typename Key>
void mkquicksort(typename Key* ar, int l, int r, int bit, typename const KeyHolds& term)
{
if(r <= l) return;
typename register Key* a = ar;
register int i = l - 1, j = r, d = bit; typename const KeyHolds v = qobj(get(a, j), d);//speed increase with registers
int p = i, q = j;
while(i < j)
{
while(qobj(get(a, ++i), d) < v) ;
while(v < qobj(get(a, --j), d)) if(j == l) break;
if(i > j) break;
std::swap(get(a, i), get(a, j));
if(qobj(get(a, i), d) == v) {++p; std::swap(get(a, p), get(a, i));}
if(qobj(get(a, j), d) == v) {--q; std::swap(get(a, q), get(a, j));}
}
if(p == q)
{
if(!(v == term)) mkquicksort(a, l, r, d + 1, term);
return;
}
if(qobj(get(a, i), d) < v) ++i;
int k = l;
for( ; k <= p; j--, k++) std::swap(get(a, k), get(a, j));
for(k = r; k >= q; i++, k--) std::swap(get(a, k), get(a, i));
mkquicksort(a, l, j, d, term);
if((i == r) && (qobj(get(a, i), d) == v)) ++i;
if(!(v == term)) mkquicksort(a, j + 1, i - 1, d + 1, term);
mkquicksort(a, i, r, d, term);
}
//////////////////
template<typename KeyHolds, typename Key>
void rmkquicksort(typename Key* ar, int l, int r, int bit, typename const KeyHolds& term)
{
if(r <= l) return;
typename register Key* a = ar;
register int i = l - 1, j = r, d = bit; typename const KeyHolds v = qobj(get(a, j), d);//speed increase with registers
int p = i, q = j;
while(i < j)
{
while(v < qobj(get(a, ++i), d)) ;
while(qobj(get(a, --j), d) < v) if(j == l) break;
if(i > j) break;
std::swap(get(a, i), get(a, j));
if(qobj(get(a, i), d) == v) {++p; std::swap(get(a, p), get(a, i));}
if(qobj(get(a, j), d) == v) {--q; std::swap(get(a, q), get(a, j));}
}
if(p == q)
{
if(!(v == term)) rmkquicksort(a, l, r, d + 1, term);
return;
}
if(v < qobj(get(a, i), d)) ++i;
int k = l;
for( ; k <= p; j--, k++) std::swap(get(a, k), get(a, j));
for(k = r; k >= q; i++, k--) std::swap(get(a, k), get(a, i));
rmkquicksort(a, l, j, d, term);
if((i == r) && (qobj(get(a, i), d) == v)) ++i;
if(!(v == term)) rmkquicksort(a, j + 1, i - 1, d + 1, term);
rmkquicksort(a, i, r, d, term);
}
}
template<typename KeyHolds, typename Key>
inline void mk_qsort(typename Key* data, int size, typename const KeyHolds term) //normal
{
detail::mkquicksort<KeyHolds, Key>(data, 0, size, 0, term);
}
template<typename KeyHolds, typename Key>
inline void r_mk_qsort(typename Key* data, int size, typename const KeyHolds term) //reverse
{
detail::rmkquicksort<KeyHolds, Key>(data, 0, size, 0, term);
}
}
#include <time.h>
//can't sort these with normal quicksort but you can with multikey quicksort
//these aren't real
int rrr[10];
int rrr1[10];
int rrr2[10];
int rrr3[10];
//cna't sort this with normal quicksort but you can with multikey quicksort
int* rrrr[4] = {rrr, rrr1, rrr2, rrr3};
void test()
{
time_t repeatable = time(NULL);
srand((unsigned)repeatable);
for(int x = 0; x < 4; x++)
{
for(int y = 0; y < 5; y++)
{
rrrr[x][y] = rand() % 2;
}
for(int y = 5; y < 10; y++)
{
rrrr[x][y] = rand() % 3;
}
rrrr[x][10] = 255;
}
cout << "Normal" << endl;
boost::mk_qsort<int, int*>(rrrr, 3, 255);
for(int x = 0; x < 4; x++)
{
cout << endl;
for(int y = 0; y < 10; y++)
{
cout << rrrr[x][y] << " ";
}
}
cout << endl << endl << "Reverse" << endl << endl;
srand((unsigned)repeatable);
for(int x = 0; x < 4; x++)
{
for(int y = 0; y < 5; y++)
{
rrrr[x][y] = rand() % 2;
}
for(int y = 5; y < 10; y++)
{
rrrr[x][y] = rand() % 3;
}
rrrr[x][10] = 255;
}
boost::r_mk_qsort<int, int*>(rrrr, 3, 255);
for(int x = 0; x < 4; x++)
{
for(int y = 0; y < 10; y++)
{
cout << rrrr[x][y] << " ";
}
cout << endl;
}
}
int main()
{
test();
return 0;
}
Binary file added Radix Quicksort - sort within sort.zip
Binary file not shown.
Binary file added RadixSort vs std sort.zip
Binary file not shown.
Binary file added RadixSortExample - sort within sort.zip
Binary file not shown.
Binary file added Sorting.zip
Binary file not shown.
85 changes: 85 additions & 0 deletions radixsort.cpp
@@ -0,0 +1,85 @@
// radixsort.cpp : Defines the entry point for the console application.
// this program sorts the class radixtest by the numbers array contained in radixtest.
//It first examines the first integer in the numbers array, then the second.
//the array test of radixtests is sorted, then outputed to the standard output.
//they will be in the proper order.
//this could also be done by an operator< and used with std::sort
//but that operator would have multiple branches
//I wrote an operator< to show why it would be slow

#include "radix.hpp"
#include <cstdlib>
#include <iostream>
#include <time.h>
class radixtest
{
public:
int numbers[5];
radixtest()
{
numbers[0] = rand() % 10;
numbers[1] = rand() % 10;
numbers[2] = rand() % 10;
numbers[3] = rand() % 10;
numbers[4] = rand() % 10;
}
inline unsigned char operator[](int num)
{return ((unsigned char*)numbers)[num];}
//if this was a template class you would have to generate 20-40
//different versions of it before all the code made for this function
//added up to the same amount of code generated just for one operator<
//the size of code this function takes is constant and does not increase with the amount of numbers
//operator< increases for each number added on
inline unsigned char operator[](int num) const
{return ((unsigned char*)numbers)[num];}
bool operator<(const radixtest& a) const
{
//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
//if this was a template class that was used for many different types
//think of how much code bloat you would have just from this function
//not to mention all of the other functions that you would have
if(numbers[0] < a.numbers[0])
return true;
else if(numbers[0] == a.numbers[0])
{
if (numbers[1] < a.numbers[1])
return true;
else if(numbers[1] == a.numbers[1])
{
if(numbers[2] < a.numbers[2])
return true;
else if(numbers[2] == a.numbers[2])
{
if(numbers[3] < a.numbers[3])
return true;
else if(numbers[3] == a.numbers[3])
{
if(numbers[4] < a.numbers[4])
{ return true;}
}
}
}
}
return false;
}
};
std::ostream& operator<<(std::ostream& o, radixtest& t)
{
return o << "{" << t.numbers[0] << ", " << t.numbers[1] << ", " << t.numbers[2] << ", " << t.numbers[3] << ", " << t.numbers[4] << "}";
}
int main(int argc, char* argv[])
{
srand((unsigned)time(NULL));
radixtest tests[1000];
boost::radix_sort(tests, 1000);
for(int x = 0; x < 999; x++)
{
std::cout << tests[x] << " ";
if(tests[x + 1] < tests[x])
{
cout << "ERROR" << endl;
}
}
return 0;
}

0 comments on commit d9fd661

Please sign in to comment.