Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Added Sorting

  • Loading branch information...
commit d9fd6617f9add5d6fb0b726f9c542e21a7411882 0 parents
@daniel-w daniel-w authored
BIN  AsmSort.zip
Binary file not shown
176 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;
+}
BIN  Radix Quicksort - sort within sort.zip
Binary file not shown
BIN  RadixSort vs std sort.zip
Binary file not shown
BIN  RadixSortExample - sort within sort.zip
Binary file not shown
BIN  Sorting.zip
Binary file not shown
85 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;
+}
+
176 source/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;
+}
85 source/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;
+}
+
Please sign in to comment.
Something went wrong with that request. Please try again.