1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105
|
#include <iostream>
#include <cstring>
using namespace std;
// 0 = none, 1 = template, 2 = overload, 3 = both
#define USE_SPECIALIZATION 3
// http://en.wikipedia.org/wiki/Gnome_sort
template <typename TElem>
void gnomesort(TElem arr[], size_t N) {
size_t i = 0;
while (i < N) {
if (i == 0 || arr[i - 1] <= arr[i]) {
++i;
} else {
TElem tmp = arr[i];
arr[i] = arr[i - 1];
arr[--i] = tmp;
}
}
}
#if (USE_SPECIALIZATION == 1) || (USE_SPECIALIZATION == 3)
template<>
void gnomesort<const char*>(const char* arr[], size_t N) {
size_t i = 0;
while (i < N) {
if (i == 0 || (strcmp(arr[i - 1], arr[i]) <= 0)) {
++i;
} else {
const char* tmp = arr[i];
arr[i] = arr[i - 1];
arr[--i] = tmp;
}
}
}
#endif
#if ((USE_SPECIALIZATION == 2) || (USE_SPECIALIZATION == 3))
void gnomesort(const char* arr[], size_t N) {
size_t i = 0;
while (i < N) {
if (i == 0 || (strcmp(arr[i - 1], arr[i]) <= 0)) {
++i;
} else {
const char* tmp = arr[i];
arr[i] = arr[i - 1];
arr[--i] = tmp;
}
}
}
#endif
#if ((USE_SPECIALIZATION != 0) && (USE_SPECIALIZATION != 1) && (USE_SPECIALIZATION != 2) && (USE_SPECIALIZATION != 3))
#error USE_SPECIALIZATION must be defined to be 0, 1, 2, or 3
#endif
// PI rounded to 8 sig fig = 3.1415927
void test_int() {
cout << "* * * test_int * * *" << endl;
cout << endl;
int data[] = {3, 1, 4, 1, 5, 9, 2, 7};
gnomesort(data, sizeof(data)/sizeof(data[0]));
cout << "data =";
for(size_t i = 0; i < sizeof(data)/sizeof(data[0]); ++i) {
std::cout << ' ' << data[i];
}
cout << endl;
cout << endl;
}
void test_char_star() {
cout << "* * * test_char_star * * *" << endl;
cout << endl;
const char* data[] = {"three", "one", "four", "one", "five", "nine", "two", "seven"};
gnomesort(data, sizeof(data)/sizeof(data[0]));
cout << "data =";
for(size_t i = 0; i < sizeof(data)/sizeof(data[0]); ++i) {
std::cout << ' ' << data[i];
}
cout << endl;
cout << endl;
}
int main() {
test_int();
test_char_star();
return 0;
}
|